1

所以我正在使用 Apple 的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;

所以我的问题是,我如何用数据填充像上面设置的立体声缓冲区,以便它正常工作?

谢谢!

4

2 回答 2

2

看一下Classes/MixerHostAudio.m示例MixerHost,然后向下滚动到他们定义和分配的位置outSamplesChannelLeftoutSamplesChannelRight。看起来 API 需要不同缓冲区中的左右样本,而不是交错的。

至于改变音高,试试

if (inc > M_PI) inc -= 2.0*M_PI;

(或任何 Apple 定义的代替M_PI)并在循环中执行此操作,而不是在填充整个帧之后。浮点误差累积得惊人地快。sin上面的修正使用了周期性超过的事实2*pi。您的校正会任意回绕inc,如果包裹不是相位连续的,则会在包裹点引起毛刺。

最后,我不清楚你是否bytesPerSample是 2,你可能想检查一下。如果是,那么我猜你的其他假设bytesPerFrame是正确的。

于 2011-05-22T23:49:06.233 回答
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;
}
于 2012-03-17T17:44:16.303 回答