所以我正在使用Apple的MixerHost sample code来进行立体声合成的基本听力设置。我在弄清楚如何填充缓冲切片时遇到了一些麻烦。具体来说,我只在左声道输出音频,右声道静音:
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;
这会在左声道上播放一个正弦波......音调类型每10秒左右发生变化,另一个指示我做错了:]
我尝试过其他方法来逐步完成阵列。这产生了有趣的声音,远离正弦信号。有一次,我在两个频道上都出现了毛刺/波动的输出,这有点像成功。
如果我检查AudioBuffer结构,它确认有2个通道,每帧的字节大小为4.所以每帧有两个SInt16,对吗?一个用于左侧,一个用于右侧通道..它们应该是交错的?
请注意,我使用的流格式与Apple的示例不同,因为我不知道定点数学。
流格式设置如下:
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;
所以我的问题是,如何填充上面设置的立体声缓冲区,以便它能正常工作?
谢谢!
答案 0 :(得分:2)
查看Classes/MixerHostAudio.m
示例中的MixerHost
,然后向下滚动到他们定义的位置,并指定outSamplesChannelLeft
和outSamplesChannelRight
。看起来API期望左侧和右侧样本位于不同的缓冲区中,而不是交错的。
至于改变音高,试试
if (inc > M_PI) inc -= 2.0*M_PI;
(或Apple定义的任何代替M_PI
)并在循环内执行此操作,而不是在填充整个框架之后。浮点错误累积得非常快。上面的更正使用了sin
超过2*pi
的事实。你的修正任意地将inc
包裹回来,如果包裹不是相位连续的话,会在包裹点引起毛刺。
最后,我不清楚你的bytesPerSample
是否为2,你可能想检查一下。如果是,那么我猜你关于bytesPerFrame
的其他假设是正确的。
答案 1 :(得分:1)
您正在设置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;
}