使用音高调整和其他效果在iPhone上同时播放多个iPod库歌曲

3
我已经在这个问题上努力了两周,而且越来越心烦意乱。几天前我提出了这个问题(从iPod库中提取原始PCM样本并播放声音效果),虽然答案让我解决了一半的问题,但我仍然卡住了。

基本上我想要实现的是从iPod库中加载多首歌曲进行播放,同时加入pitch bend、eq效果等音效。

我试过使用AVPlayer和AVAudioPlayer,但它们太简单了。目前我看到唯一一个能够带有这些效果播放音频的框架是OpenAL。我尝试了一些Objective C的包装器(Finch和ObjectAL),Finch不能播放压缩音频,而只有我传递文件的URL才能让ObjectAL为我转换(这是我无法做到的,因为我只有一个不兼容的iPod库URL)。

一个很好地演示了我想要功能的应用程序是Tap DJ。它可以快速从iPod库中加载歌曲(与TouchDJ不同),并使用各种效果播放它们。

希望能得到任何帮助。

1个回答

5
如果您能将音频数据转换为OpenAL所需的原始PCM格式,那么您就可以将其加载到ObjectAL中。
您需要的是:
- 音频数据 - 数据的字节大小 - 数据格式(AL_FORMAT_MONO16或AL_FORMAT_STEREO16) - 采样率
您还需要一个ALSource来播放缓冲区。如果您与OALSimpleAudio一起使用(建议这样做,因为它会为您处理设备和上下文),则需要告诉它不要占用所有可用的源。
[OALSimpleAudio sharedInstance].reservedSources = 20; // or some number < 32

创建源代码(应在init中执行):
mySource = [[ALSource source] retain];

您可以按照以下方式使用自定义数据创建ALBuffer:
ALBuffer* myBuffer = [ALBuffer bufferWithName:someName
                           data:myAudioData
                           size:audioDataSizeInBytes
                         format:audioFormat
                      frequency:sampleRateInHz];

现在您可以玩:

[mySource play:myBuffer];

编辑:ALBuffer接管了音频数据的管理,并在其解除分配时调用free()。因此,请注意不要重复释放:)

编辑2:我刚刚为ALBuffer添加了“freeDataOnDestroy”属性,因此您现在可以控制它是否释放数据(默认为YES)。

编辑3:算了吧,既然已经走到这一步,那就彻底走下去吧。在OALSimpleAudio中添加了“playBuffer”方法。

所以现在您可以完全使用OALSimpleAudio:

myBuffer = [[ALBuffer bufferWithName:someName
                           data:myAudioData
                           size:audioDataSizeInBytes
                         format:audioFormat
                      frequency:sampleRateInHz] retain];

...

id<ALSoundSource> source = [[OALSimpleAudio sharedInstance] playBuffer:myBuffer
                                                                volume:1.0
                                                                 pitch:1.0
                                                                   pan:0
                                                                  loop:NO];

[source pitchTo:2.0
       duration:5.0
         target:nil
       selector:nil];
// And so on...

现在还有更简单的 [[OALManager sharedInstance] bufferFromUrl:url reduceToMono:NO] 调用,它在内部使用了 bufferWithName:data:size:format:frequency。使用它来创建 ALBuffer *,然后使用 playBuffer 方法。 - Courtney Christensen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接