如何正确填充立体声AudioBuffer
所以我使用苹果公司的MixerHost示例代码为立体声合成做一个基本的听觉设置。 我有一些麻烦,搞清楚如何填补缓冲区。 具体来说,我只在左声道中获取audio,右声道是沉默的:
AudioUnitSampleType *buffer = (AudioUnitSampleType *)ioData->mBuffers[0].mData; SInt16 sampleValue; for(UInt32 i = 0; i < inNumberFrames; i++) { sampleValue = sinf(inc) * 32767.0f; // generate sine signal inc += .08; buffer[i] = sampleValue; } if(inc > 2e10) inc -= 2e10;
这在左声道上播放正弦波…音调types每10秒左右改变一次,另一个指标是我做错了:]
我已经尝试了其他的方法来通过数组。 这产生了离正弦信号很远的有趣声音。 有一次,我在两个频道上都输出了糟糕/不连贯的结果,这有点像成功。
如果我检查AudioBuffer结构,它确认有2个通道,每帧的字节数是4.所以每帧有两个SInt16,对吧? 一个用于左侧,另一个用于右侧通道..他们应该交错?
请注意,我使用的是与Apple示例不同的stream格式,因为我不知道定点math。
stream格式设置如下:
size_t bytesPerSample = sizeof (AudioUnitSampleType); stereoStreamFormat.mFormatID = kAudioFormatLinearPCM; stereoStreamFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; stereoStreamFormat.mBytesPerPacket = bytesPerSample; stereoStreamFormat.mFramesPerPacket = 1; stereoStreamFormat.mBytesPerFrame = bytesPerSample; stereoStreamFormat.mChannelsPerFrame = 2; stereoStreamFormat.mBitsPerChannel = 8 * bytesPerSample; stereoStreamFormat.mSampleRate = graphSampleRate;
所以我的问题是,我如何填充一个立体声缓冲区设置像上面的数据,以便它只是工作?
谢谢!
在MixerHost
示例中查看Classes/MixerHostAudio.m
,向下滚动到他们定义的位置,并指定outSamplesChannelLeft
和outSamplesChannelRight
。 它看起来像API预计在不同的缓冲区左,右采样,不交错。
至于变化的沥青,尝试
if (inc > M_PI) inc -= 2.0*M_PI;
(或苹果定义的M_PI
地方),并在循环内,而不是填充整个框架之后。 浮点错误快速累积。 上面的修正使用了2*pi
周期性的事实。 如果包装不是相位连续的,你的修正任意地将包裹重新包裹,并且在包裹点处会引起毛刺。
最后,我不清楚你的bytesPerSample
是否为2,你可能想检查一下。 如果是,那么我猜你对bytesPerFrame
的其他假设是正确的。
你正在设置mBytesPerFrame = bytesPerSample。 这只允许每帧一个样本。 对于交错立体声(即mChannelsPerFrame = 2),每帧需要两个采样。 尝试设置mBytesPerFrame = 2 * bytesPerSample.
在你的渲染函数中:
UInt32 numOfSamples = 2 * inNumberFrames; for (i = 0; i < numOfSamples; i+=2) { buffer[i] = //assign left channel value; buffer[i+1] = //assign right channel value; }