首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与AudioQueueServices同步播放(10+)

与AudioQueueServices同步播放(10+)
EN

Stack Overflow用户
提问于 2011-09-12 11:02:47
回答 3查看 681关注 0票数 2

谁能告诉我iPhone是如何做到这一点的?我正在尝试制作一个可以同时播放大约12种声音的游戏,但我不知道如何使用AudioQueueServices。我知道你必须初始化,添加缓冲区,回放它们,并使用AudioQueueEnqueueBufferWithParameters来获得同步播放,但我不知道如何将其转换为代码。任何人在这上面有代码,或者有人可以向我解释它将是令人惊讶的!

如果你听说过Tone Grid/Tone Board,那正是我想要做的。我知道Appstore中已经有几个应用程序可以做到这一点,但我不知道它是如何做到的。

在使用10+声音同时播放AudioQueueServices时,需要帮助。

示例:

新播放

代码语言:javascript
运行
复制
    if (isPlaying == NO) {
err = AudioQueueNewOutput (&streamFormat, AudioEngineOutputBufferCallback, self, nil, nil, 0, &outputQueue);
if (err != noErr) NSLog(@"AudioQueueNewOutput() error: %d", err);

入队缓冲区

代码语言:javascript
运行
复制
outputBuffersToRewrite = 3;
bufferByteSize = (sampleRate > 16000)? 2176 : 512; // 40.5 Hz : 31.25 Hz 
for (i=0; i<3; i++) {
    err = AudioQueueAllocateBuffer (outputQueue, bufferByteSize, &buffer); 
    if (err == noErr) {
        [self generateTone: buffer];
        err = AudioQueueEnqueueBuffer (outputQueue, buffer, 0, nil);
        if (err != noErr) NSLog(@"AudioQueueEnqueueBuffer() error: %d", err);
    } else {
        NSLog(@"AudioQueueAllocateBuffer() error: %d", err); 
        return;
    }
}

开始播放

代码语言:javascript
运行
复制
isPlaying = YES;
err = AudioQueueStart(outputQueue, nil);
if (err != noErr) { NSLog(@"AudioQueueStart() error: %d", err); isPlaying= NO; return; }
} else {
NSLog (@"Error: audio is already playing back.");

设置流格式字段

代码语言:javascript
运行
复制
BOOL isHighSampleRate = (sampleRate > 16000);
int bufferByteSize;
AudioQueueBufferRef buffer;

AudioStreamBasicDescription streamFormat;
streamFormat.mSampleRate = sampleRate;
streamFormat.mFormatID = kAudioFormatLinearPCM;
streamFormat.mFormatFlags = kLinearPCMFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked;
streamFormat.mBitsPerChannel = 16;
streamFormat.mChannelsPerFrame = 1;
streamFormat.mBytesPerPacket = 2 * streamFormat.mChannelsPerFrame;
streamFormat.mBytesPerFrame = 2 * streamFormat.mChannelsPerFrame;
streamFormat.mFramesPerPacket = 1;
streamFormat.mReserved = 0;
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-10-28 04:37:40

AudioQueue可以同时播放声音。

来自苹果:

如何同时播放多个声音?

使用音频队列服务(AudioToolbox/AudioQueue.h)中的接口。为要播放的每个声音创建一个音频队列对象。然后使用AudioQueueEnqueueBufferWithParameters函数为每个音频队列中的第一个音频缓冲区指定同时开始时间。

以下限制适用于iPhone OS中的同步声音,具体取决于音频数据格式:

AAC、MP3和ALAC (苹果无损)音频:您可以同时播放多个AAC、MP3和ALAC格式的声音;播放这些格式的多个声音将需要占用CPU资源进行解码。

线性PCM和IMA/ADPCM (IMA4音频):您可以同时播放多个线性PCM或IMA4格式的声音,而无需考虑CPU资源问题。

票数 1
EN

Stack Overflow用户

发布于 2011-09-14 17:01:17

AudioQueue无法同时播放多个声音。它只是一个接一个地从入队缓冲区发送音频数据值。所以你需要把你想同时播放的所有声音组合成一个单独的声音。你如何做到这一点?如果数据没有被压缩,它不会太难。你有两种不同的声音。它们中的每一个都可以描述为从-1到1的浮点值的数组。当声音存储在文件中或排队到audioQueue时,它们必须以适当的格式表示。在您的示例中(kAudioFormatLinearPCM,streamFormat.mBitsPerChannel = 16),它是两个字节的整数,每个值都表示为从-32767到32767的短整型。因此,两个声音中的每一个都是一个短小的数组,当你将buffer排入队列时,你用这个数组的值填充它(如果声音不是从文件中动态生成的,这个数组不存在,但是值是逐个计算的)。要创建这两个音频文件的“总和”,您应该将每个新数组值构造为两个声音数组的相应值的平均值。

即resultSoundi = sound1i/2 + sound2i/2;

对于任何数量的声音都是一样的。例如,要生成纯谐波声音,您可以填充buffer,如下所示:

代码语言:javascript
运行
复制
buffer[i] = sin(i * 2 * M_PI * frequency / sampleRate) * 32767;

并混合两种不同频率的和声:

代码语言:javascript
运行
复制
buffer[i] = sin(i * 2 * M_PI * frequency1 / sampleRate) + sin(i * 2 * M_PI * frequency2 / sampleRate) * 0.5 * 32767;
票数 1
EN

Stack Overflow用户

发布于 2012-08-09 09:50:10

请记住,您正在处理单个音频流,因此您需要自己创建组合流,或者您可以使用混音器单元来为其提供多个流。请参阅苹果公司的“音频混音器(MixerHost)”示例代码。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7382903

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档