在iPhone上播放生成的音频

时间:2009-11-10 18:28:22

标签: iphone objective-c

作为iPhone的一次性项目让我能够快速掌握Objective C和iPhone库,我一直在尝试创建一个可以播放各种随机噪音的应用程序。

我一直在构造噪声,因为从[-1,1]归一化的浮点数组。

我被困的地方在于播放生成的数据。看起来这应该是相当简单的,但我已经研究过使用AudioUnit和AVAudioPlayer,这些看起来都不是最优的。

AudioUnit显然需要几百行代码来完成这个简单的任务,而AVAudioPlayer似乎要求我将音频转换成CoreAudio可以理解的东西(据我所知,这意味着LPCM放入WAV文件)

我是否忽略了某些内容,或者这些是以播放数组形式存储的声音数据的最佳方式?

2 个答案:

答案 0 :(得分:3)

这里有一些使用AudioQueue的代码,我已经从SpeakHere示例中修改过了。我有点粘贴好的部分,所以这里或那里可能有一些悬空,但如果你想使用这种方法,这应该是一个好的开始:

AudioStreamBasicDescription format;
memset(&format, 0, sizeof(format));
format.mSampleRate = 44100;
format.mFormatID = kAudioFormatLinearPCM;
format.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
format.mChannelsPerFrame = 1;
format.mBitsPerChannel = 16;
format.mBytesPerFrame = (format.mBitsPerChannel / 8) * format.mChannelsPerFrame;
format.mFramesPerPacket = 1;
format.mBytesPerPacket = format.mBytesPerFrame * format.mFramesPerPacket;

AudioQueueRef queue;

AudioQueueNewOutput(&format, 
            AQPlayer::AQOutputCallback, 
            this,  // opaque reference to whatever you like
            CFRunLoopGetCurrent(), 
            kCFRunLoopCommonModes, 
            0, 
            &queue); 

const int bufferSize = 0xA000;  // 48K - around 1/2 sec of 44kHz 16 bit mono PCM        
for (int i = 0; i < kNumberBuffers; ++i)
    AudioQueueAllocateBufferWithPacketDescriptions(queue, bufferSize, 0, &mBuffers[i]);

AudioQueueSetParameter(queue, kAudioQueueParam_Volume, 1.0);

UInt32 category = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(category), &category);

AudioSessionSetActive(true);

// prime the queue with some data before starting
for (int i = 0; i < kNumberBuffers; ++i)
    OutputCallback(queue, mBuffers[i]);

AudioQueueStart(queue, NULL);

上面的代码引用了这个输出回调。每次执行此回调时,请使用生成的音频填充传入的缓冲区。在这里,我用随机噪音填充它。

void OutputCallback(void* inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inCompleteAQBuffer) {
    // Fill 
    //AQPlayer* that = (AQPlayer*) inUserData;
    inCompleteAQBuffer->mAudioDataByteSize = next->mAudioDataBytesCapacity; 
    for (int i = 0; i < inCompleteAQBuffer->mAudioDataByteSize; ++i)
        next->mAudioData[i] = rand();
    AudioQueueEnqueueBuffer(queue, inCompleteAQBuffer, 0, NULL);
 }

答案 1 :(得分:0)

听起来你是来自一个拥有简单的内置音源的平台。 iPhone没有这样的东西。从声音文件中播放简单的声音更容易。 AudioUnit用于实际处理和生成真实音乐。

所以,是的,您确实需要一个音频文件来播放声音。