如何正确填充立体声音频缓冲区
所以我使用苹果的 MixerHost示例代码用于进行立体声合成的基本听力记录设置。我在弄清楚如何填充缓冲区切片时遇到了一些麻烦。具体来说,我只在左声道中输出音频,右声道是静音的:
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;
所以我的问题是,如何用数据填充像上面设置的立体声缓冲区,以便它正常工作?
谢谢!
so i'm using Apple's MixerHost sample code to do a basic audiograph setup for stereo synthesis. I have some trouble figuring out how i have to fill the buffer slice. Specifically, i get audio out only in the left channel, the right channel is silent:
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;
This plays a sine wave on the left channel... The pitch kind of changes every 10 seconds or so, another indicator that i'm doing it wrong :]
i've tried other ways of stepping through the array. this produced interesting sounds which were far from a sine signal. At one point i had glitchy/choppy output on both channels, which was kind of like a success.
If i inspect the AudioBuffer struct, it confirms there are 2 channels, and the bytesize per frame is 4. So per frame, there are two SInt16, right? One for left, and one for the right channel.. and they are supposed to be interleaved?
Note that i am using a stream format that is different from Apple's example because i don't know fixed point math.
The stream format is setup like so:
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;
so my question is, how do i fill a stereo buffer which is setup like above with data so that it just works?
thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看
MixerHost
示例中的Classes/MixerHostAudio.m
,然后向下滚动到它们定义并分配outSamplesChannelLeft
和outSamplesChannelRight 的位置
。看起来 API 期望左右样本位于不同的缓冲区中,而不是交错的。至于改变音高,请尝试
(或 Apple 定义的任何替代
M_PI
)并在循环内执行此操作,而不是在填充整个帧之后。浮点错误的累积速度惊人地快。上述修正利用了sin
在2*pi
上具有周期性的事实。您的校正会任意将inc
重新包裹起来,如果包裹不是相位连续的,则会在包裹点处导致故障。最后,我不清楚您的
bytesPerSample
是否为 2,您可能需要检查一下。如果是,那么我猜您关于bytesPerFrame
的其他假设是正确的。Take a look at
Classes/MixerHostAudio.m
in theMixerHost
example, and scroll down to where they define and assignoutSamplesChannelLeft
andoutSamplesChannelRight
. It looks like the API expects left and right samples in different buffers, not interleaved.As for the changing pitch, try
(or whatever Apple defines in place of
M_PI
) and do this within the loop, not after filling the whole frame. Floating point error accumulates surprisingly quickly. The correction above uses the fact thatsin
is periodic over2*pi
. Your correction arbitrarily wrapsinc
back in, and will cause a glitch at the wrap point if the wrapping isn't phase continuous.And finally, it's not clear to me if your
bytesPerSample
is 2 or not, you might want to check this. If it is, then I'd guess your other assumption aboutbytesPerFrame
is correct.您正在设置 mBytesPerFrame = bytesPerSample。这仅允许每帧一个样本。对于交错立体声(即 mChannelsPerFrame = 2),每帧需要两个样本。 设置
mBytesPerFrame = 2 * bytesPerSample。
尝试在渲染函数中
You are setting mBytesPerFrame = bytesPerSample. This only allows one sample per frame. For interleaved stereo (i.e. mChannelsPerFrame = 2) you need two samples per frame. Try setting
mBytesPerFrame = 2 * bytesPerSample.
In your render function: