在iPhone上播放生成的音频 [英] Playing generated audio on an iPhone

查看:91
本文介绍了在iPhone上播放生成的音频的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

As a throwaway project for the iPhone to get me up to speed with Objective C and the iPhone libraries, I've been trying to create an app that will play different kinds of random noise.

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

I've been constructing the noise as an array of floats normalized from [-1,1].

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

Where I'm stuck is in playing that generated data. It seems like this should be fairly simple, but I've looked into using AudioUnit and AVAudioPlayer, and neither of these seem optimal.

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

AudioUnit requires apparently a few hundred lines of code to do even this simple task, and AVAudioPlayer seems to require me to convert the audio into something CoreAudio can understand (as best I can tell, that means LPCM put into a WAV file).

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

Am I overlooking something, or are these really the best ways to play some sound data stored in array form?

推荐答案

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

Here's some code to use AudioQueue, which I've modified from the SpeakHere example. I kind of pasted the good parts, so there may be something dangling here or there, but this should be a good start if you want to use this approach:

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);

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

The code above refers to this output callback. Each time this callback executes, fill the buffer passed in with your generated audio. Here, I'm filling it with random noise.

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);
 }

这篇关于在iPhone上播放生成的音频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆