iOS:Pitch Shifting&将OpenAL的输出管道输入缓冲区

时间:2010-12-06 09:29:01

标签: ios openal shift pitch

我最近发现在iOS中可以使用OpenAL进行音高变换。

我在看Hollance的声音银行播放器。它会吸收大约15个左右的钢琴音符,通过计算出最接近哪个样本来播放任何音符,然后调整适当数量的音高。这是执行此操作的代码:

- (void) noteOn: (int) midiNoteNumber 
           gain: (float) gain
{
    if (!initialized)
    {
        NSLog(@"SoundBankPlayer is not initialized yet");
        return;
    }

    int sourceIndex = [self findAvailableSource];
    if (sourceIndex != -1)
    {
        alGetError();  // clear any errors

        Note* note = notes + midiNoteNumber;
        if (note->bufferIndex != -1)
        {
            Buffer* buffer = buffers + note->bufferIndex;
            Source* source = sources + sourceIndex;

            source->noteIndex = midiNoteNumber;

            alSourcef(source->sourceId, AL_PITCH, note->pitch / buffer->pitch);
            alSourcei(source->sourceId, AL_LOOPING, AL_FALSE);
            alSourcef(source->sourceId, AL_REFERENCE_DISTANCE, 100.0f);
            alSourcef(source->sourceId, AL_GAIN, gain);

            float sourcePos[] = { note->panning, 0.0f, 0.0f };
            alSourcefv(source->sourceId, AL_POSITION, sourcePos);

            alSourcei(source->sourceId, AL_BUFFER, AL_NONE);
            alSourcei(source->sourceId, AL_BUFFER, buffer->bufferId);
            ALenum error;
            if ((error = alGetError()) != AL_NO_ERROR)
            {
                NSLog(@"Error attaching buffer to source: %x", error);
                return;
            }

            alSourcePlay(source->sourceId);
            if ((error = alGetError()) != AL_NO_ERROR)
            {
                NSLog(@"Error starting source: %x", error);
                return;
            }
        }
    }
}

你可以看到这条线做了音高变换:

        alSourcef(source->sourceId, AL_PITCH, note->pitch / buffer->pitch);

不幸的是,这对于同时播放一组音符并不好,因为它需要太多的CPU。它是动态的音高变换。

我想要的是为每个钢琴音符创建一个缓冲区,并使用这种音高变换技术填充这些缓冲区。但我无法看到如何让openAL将声音播放到缓冲区而不是通过扬声器播放。

有没有办法管道输出             alSourcePlay(源 - >的SourceID);

进入缓冲区?

如果我不能这样做,我的选择是什么?我已经尝试过使用DSPDimension文章中的smbPitchShift,但它没有提供良好的保真度:钢琴音符的攻击阶段确实丢失了。我想我可以使用Dirac3的免费版本...(我目前没有完整版本的钱,但我认为免费版本允许Mono处理,所以我可以破解它)。还有其他选择吗?

编辑:我已经测试过Dirac3,它也有同样的问题。它似乎包围了攻击。似乎OpenAL的音高变换器以某种方式做了Dirac3没有做的事情。

1 个答案:

答案 0 :(得分:4)

alSourcePlayv允许您同时播放多个源 - 最大数量的源是平台相关的,但在iOS上为32(在Apple核心音频列表上回答,此处为完整性)