我正在尝试将PCM 32位浮点音频流转换为ALAC。我发现了一些可以构建的工作示例,但是我自己的代码从AudioConverterFillComplexBuffer获得了-50(paramErr)。我的眼睛正在看着这段代码;我看不出与我的例子有什么不同。
我设置输入和输出格式并创建转换器:
UInt32 numChannels = 2;
// Describe the input stream
AudioStreamBasicDescription inputFormat;
memset(&inputFormat, 0, sizeof(AudioStreamBasicDescription));
inputFormat.mSampleRate = 44100;
inputFormat.mFormatID = kAudioFormatLinearPCM;
inputFormat.mFramesPerPacket = 1;
inputFormat.mChannelsPerFrame = numChannels;
inputFormat.mFormatFlags = kLinearPCMFormatFlagIsFloat | kLinearPCMFormatFlagIsPacked;
inputFormat.mBitsPerChannel = sizeof(Float32) * 8;
inputFormat.mBytesPerPacket = numChannels * (inputFormat.mBitsPerChannel / 8);
inputFormat.mBytesPerFrame = inputFormat.mBytesPerPacket * inputFormat.mFramesPerPacket;
// Describe the output stream
AudioStreamBasicDescription outputFormat;
memset(&outputFormat, 0, sizeof(AudioStreamBasicDescription));
outputFormat.mSampleRate = 44100;
outputFormat.mFormatID = kAudioFormatAppleLossless;
outputFormat.mFramesPerPacket = 4096;
OSStatus err = AudioConverterNew(&inputFormat, &outputFormat, &_alacConverter);
然后我获得最大输出数据包大小并分配一个缓冲区来保存转换后的数据:
size = sizeof(UInt32);
UInt32 maxOutputSize;
AudioConverterGetProperty(_alacConverter,
kAudioConverterPropertyMaximumOutputPacketSize,
&size,
&maxOutputSize);
_outputBuffer = [[NSMutableData dataWithCapacity:maxOutputSize] retain];
最后,我调用AudioConverterFillComplexBuffer来获取一些数据:
AudioBufferList bufferList;
memset(&bufferList, 0, sizeof(AudioBufferList));
memset(&bufferList.mBuffers[0], 0, sizeof(AudioBuffer));
bufferList.mNumberBuffers = 1;
bufferList.mBuffers[0].mNumberChannels = numChannels;
bufferList.mBuffers[0].mDataByteSize = [_outputBuffer length];
bufferList.mBuffers[0].mData = [_outputBuffer mutableBytes];
AudioStreamPacketDescription streamDesc = {0};
UInt32 numPackets = 1;
err = AudioConverterFillComplexBuffer(_alacConverter,
_encoderDataProc,
self,
&numPackets,
&bufferList,
&streamDesc);
...我总是得到-50错误。任何人都可以给我一个线索,我哪里出错了?很多(很多)谢谢!
更新:我只是使用存根函数作为数据源,永远不会被调用:
OSStatus _encoderDataProc(AudioConverterRef inAudioConverter,
UInt32* ioNumberDataPackets,
AudioBufferList* ioData,
AudioStreamPacketDescription** outDataPacketDescription,
void* inUserData)
{
TraceDebug(@"_encoderDataProc has been called");
return -1;
}
maxOutputSize以32776的形式返回。为了更好的衡量,这是我从CAShow(_alacConverter)得到的:
AudioConverter 0xa8404e (0x101c449f0):
PCMConverter2 0x101c34370
Input: 2 ch, 44100 Hz, 'lpcm' (0x00000009) 32-bit little-endian float
Output: 2 ch, 44100 Hz, 'lpcm' (0x0000000C) 32-bit little-endian signed integer
CodecConverter 0x101c44b90
Input: 2 ch, 44100 Hz, 'lpcm' (0x0000000C) 32-bit little-endian signed integer
Output: 2 ch, 44100 Hz, 'alac' (0x00000004) from 32-bit source, 4096 frames/packet
codec: 'aenc'/'alac'/'appl'
Input layout tag: 0x650002
Output layout tag: 0x650002
与以往一样,非常感谢任何帮助。自原帖以来,我没有取得任何进展。
答案 0 :(得分:2)
我陷入了同样的境地(基本上是在使用代码作为模板之后)。解决方案似乎是为AudioBufferList分配内存。实施this answer为我做了伎俩(虽然我的目标-C不足以看到确切的区别:))
答案 1 :(得分:0)
我遇到了同样的问题(AudioConverterFillComplexBuffer返回-50)
-
但只有在第一个文件播放结束后用第二个文件重新启动相同的转换器后才出现。
第一个文件完美转换没有问题。
借助克劳德的回答(谢谢!)我发现了转换器 实际上,如果到达文件的末尾,则将AudioBufferList的大小更改为0.
将AudioBufferList的大小重置为原始值后,everthing现在按预期工作。