我正在开发一个应用程序来显示sin波。我使用AudioQueueNewOutput来输出单声道声音是可以的,但是当我来到立体声输出时,我不知道如何做到这一点。我知道mChannelsPerFrame = 2
可以在左右两个通道产生波。
我还想知道发送字节到左通道和右通道的顺序是什么?第一个字节到左通道,第二个字节到右通道?
代码:_audioFormat = new AudioStreamBasicDescription();
_audioFormat->mSampleRate = SAMPLE_RATE; // 44100
_audioFormat->mFormatID = kAudioFormatLinearPCM;
_audioFormat->mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
_audioFormat->mFramesPerPacket = 1;
_audioFormat->mChannelsPerFrame = NUM_CHANNELS; // 1
_audioFormat->mBitsPerChannel = BITS_PER_CHANNEL; // 16
_audioFormat->mBytesPerPacket = BYTES_PER_FRAME; // 2
_audioFormat->mBytesPerFrame = BYTES_PER_FRAME; // 2
和
_sineTableLength = _audioFormat.mSampleRate / SAMPLE_LIMIT_FACTOR; // 44100/100 = 441
_sineTable = new SInt16[_sineTableLength];
for(int i = 0; i < _sineTableLength; i++)
{
// Transfer values between -1.0 and 1.0 to integer values between -sample max and sample max
_sineTable[i] = (SInt16)(sin(i * 2 * M_PI / _sineTableLength) * 32767);
}
和
AudioQueueNewOutput (&_audioFormat,
playbackCallback,
(__bridge void *)(self),
nil,
nil,
0,
&_queueObject);
static void playbackCallback (void* inUserData,
AudioQueueRef inAudioQueue,
AudioQueueBufferRef bufferReference){
SInt16* sample = (SInt16*)bufferReference->mAudioData;
// bufferSize 1024
for(int i = 0; i < bufferSize; i += _audioFormat.mBytesPerFrame, sample++)
{
// set value for *sample
// 9ms sin wave and 4.5ms 0
...
}
...
AudioQueueEnqueueBuffer(...)
}
几天后,我找到了答案。
第一:AudioStreamBasicDescription
可以像这样设置;
则:bufferSize
由1024
变为2048
;
和:SInt16* sample = (SInt16*)bufferReference->mAudioData;
中的:SInt16
都变为SInt32
。因为通道是双的,位也是双的;
最后:每16位包含sample
中左侧或右侧通道所需的数据,只需输入您想要的任何内容。