所以我使用苹果的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 秒左右就会改变一次,这是我做错的另一个指标:]
我已经尝试过其他遍历数组的方法。这产生了远离正弦信号的有趣声音。有一次,我在两个 channel 上都有故障/断断续续的输出,这有点像成功。
如果我检查 AudioBuffer 结构,它确认有 2 个 channel ,并且每帧的字节大小为 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;
所以我的问题是,我如何用数据填充像上面设置的立体声缓冲区,以便它正常工作?
谢谢!
最佳答案
看看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
的其他假设是正确的。
关于ios - 如何正确填充立体声 AudioBuffer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6091500/