4

私は最近、iOSでOpenALを使用してピッチシフトを行うことが可能であることを発見しました。

ホランスのサウンドバンクプレーヤーを見ています。範囲全体に散らばった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(source-> sourceId);の出力をパイプする方法はありますか。

バッファに?

これができない場合、どのような選択肢がありますか?DSPDimensionの記事のsmbPitchShiftを使用してみましたが、忠実度が高くありません。ピアノの音のアタックフェーズが実際に失われています。私はDirac3の無料バージョンを使用できると思います...(現時点ではフルバージョンのお金はありませんが、無料バージョンではモノラル処理が可能だと思うので、それをハックできます)。他に選択肢はありますか?

編集:私はそれ以来Dirac3をテストしました、そしてそれは同じ問題を共有します。攻撃を包み込んでいるようです。OpenALのピッチシフターはどういうわけかDirac3がしないことをしているようです。

4

1 に答える 1

4

alSourcePlayvを使用すると、複数のソースを同時に再生できます。ソースの最大数はプラットフォームによって異なりますが、iOSでは32です(完全を期すために、Apple Core-Audioリストで回答済み)。

于 2010-12-07T17:08:31.353 に答える