質問

録音されたオーディオがディスクに保存されるとき、またはリアルタイムで再生されるときに、録音されたオーディオのピッチを変更する方法を探しています。 Audio Unitがこれに使用できることを理解しています。 iPhoneは、Audio Unitsのサポートを制限しています(たとえば、私が知る限り、カスタムのAudio Unitsを作成/使用することはできません)が、AUPitchのような、すぐに使えるオーディオユニットがいくつか利用可能です。

オーディオユニット(具体的にはAUPitch)をどのくらい正確に使用しますか?どういうわけかオーディオキューにフックしますか?オーディオユニットを連結することは可能ですか(たとえば、エコーエフェクトとピッチの変更を同時に追加するために)?

編集:iPhone SDKヘッダーを調べた後(AudioUnit.h、現時点ではMacの前にいないと思います)、AUPitchがコメントアウトされていることに気付きました。結局のところ、AUPitchがiPhoneで利用できるようには見えません。 weep weep

Appleは最近、developer.apple.comでiPhone SDKのドキュメントを整理しているようです。AUPitchなどへの参照を見つけるのが難しくなっています。

とはいえ、iPhoneで(一般的に)Audio Unitsを使用する際の質の高い回答に興味があります。

役に立ちましたか?

解決

ここには非常に優れたリソースがあります( http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/ )RemoteIOオーディオユニットを使用するため。 iPhoneでAudio Unitを操作した経験から、コールバック関数で手動で変換を実装できることがわかりました。そうすることで、問題が解決する場合があります。

他のヒント

iPhoneでのピッチの変更に関しては、OpenALが最適です。ピッチをサポートするOpenALサウンドエンジンの優れた例については、www.71squared.comから入手できるSoundManagerクラスをご覧ください。

- (void)modifySpeedOf:(CFURLRef)inputURL byFactor:(float)factor andWriteTo:(CFURLRef)outputURL {

    ExtAudioFileRef inputFile = NULL;
    ExtAudioFileRef outputFile = NULL;

    AudioStreamBasicDescription destFormat;

    destFormat.mFormatID = kAudioFormatLinearPCM;
    destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
    destFormat.mSampleRate = 44100 * factor;
    destFormat.mBytesPerPacket = 2;
    destFormat.mFramesPerPacket = 1;
    destFormat.mBytesPerFrame = 2;
    destFormat.mChannelsPerFrame = 1;
    destFormat.mBitsPerChannel = 16;
    destFormat.mReserved = 0;

    ExtAudioFileCreateWithURL(outputURL, kAudioFileCAFType,
                              &destFormat, NULL, kAudioFileFlags_EraseFile, &outputFile);

    ExtAudioFileOpenURL(inputURL, &inputFile);

    //find out how many frames is this file long
    SInt64 length = 0;
    UInt32 dataSize2 = (UInt32)sizeof(length);
    ExtAudioFileGetProperty(inputFile,
                            kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);

    SInt16 *buffer = (SInt16*)malloc(kBufferSize * sizeof(SInt16));

    UInt32 totalFramecount = 0;

    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mNumberChannels = 1;
    bufferList.mBuffers[0].mData = buffer; // pointer to buffer of audio data
    bufferList.mBuffers[0].mDataByteSize = kBufferSize *
    sizeof(SInt16); // number of bytes in the buffer

    while(true) {

        UInt32 frameCount = kBufferSize * sizeof(SInt16) / 2;
        // Read a chunk of input
        ExtAudioFileRead(inputFile, &frameCount, &bufferList);
        totalFramecount += frameCount;

        if (!frameCount || totalFramecount >= length) {
            //termination condition
            break;
        }
        ExtAudioFileWrite(outputFile, frameCount, &bufferList);
    }

    free(buffer);

    ExtAudioFileDispose(inputFile);
    ExtAudioFileDispose(outputFile);

}

係数に基づいてピッチを変更します

これには以前にNewTimePitchオーディオユニットを使用しましたが、そのオーディオコンポーネントの説明は

です。
var newTimePitchDesc = AudioComponentDescription(componentType: kAudioUnitType_FormatConverter,
        componentSubType: kAudioUnitSubType_NewTimePitch,
        componentManufacturer: kAudioUnitManufacturer_Apple,
        componentFlags: 0,
        componentFlagsMask: 0)

その後、AudioUnitSetParamater呼び出しでピッチパラメーターを変更できます。たとえば、これはピッチを-1000セント変更します

err = AudioUnitSetParameter(newTimePitchAudioUnit,
        kNewTimePitchParam_Pitch,
        kAudioUnitScope_Global,
        0,
        -1000,
        0)

このオーディオユニットのパラメーターは次のとおりです

    // Parameters for AUNewTimePitch
enum {
      // Global, rate, 1/32 -> 32.0, 1.0
  kNewTimePitchParam_Rate                         = 0,
      // Global, Cents, -2400 -> 2400, 1.0
  kNewTimePitchParam_Pitch                        = 1,
      // Global, generic, 3.0 -> 32.0, 8.0
  kNewTimePitchParam_Overlap                      = 4,
      // Global, Boolean, 0->1, 1
  kNewTimePitchParam_EnablePeakLocking            = 6
};

ただし、目的に合わせてピッチパラメータを変更するだけです。これを実装する方法のガイドについては、ジャスティンの答えを参照してください

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top