How can I use AVAudioPlayer to play audio faster *and* higher pitched?

后端 未结 2 1306
攒了一身酷
攒了一身酷 2021-02-15 05:48

Statement of Problem:

I have a collection of sound effects in my app stored as.m4a files (AAC format, 48 KHz, 16-bit) that I want to play a

2条回答
  •  执笔经年
    2021-02-15 06:43

    The forum link Jack Wu mentions has one suggestion, which involves overriding the AIFF header data directly. This may work, but you will need to have AIFF files since it relies on a specific range of the AIFF header to write into. This also needs to be done before you create the AVAudioPlayer, which means that you can't modify the pitch once it is running.

    If you are willing to go to the AudioUnits route, a complete simple solution is probably ~200 lines (note that this assumes the code style that has one function take up to 7 lines with one parameter on each line). There is an Varispeed AudioUnit, which does exactly what you want by locking pitch to rate. You would basically need to look at the API, docs and some sample AudioUnit code to get familiar and then:

    1. create/init the audio graph and stream format (~100 lines)
    2. create and add to the graph a RemoteIO AudioUnit (kAudioUnitSubType_RemoteIO) (this outputs to the speaker)
    3. create and add a varispeed unit, and connect the output of the varispeed unit (kAudioUnitSubType_Varispeed) to the input of the RemoteIO Unit
    4. create and add to the graph a AudioFilePlayer (kAudioUnitSubType_AudioFilePlayer) unit to read the file and connect it to the varispeed unit
    5. start the graph to begin playback
    6. when you want to change the pitch, do it via AudioUnitSetParameter, and the pitch and playback rate change will take effect while playing

    Note that there is a TimePitch audio unit which allows independent control of pitch and rate, as well.

提交回复
热议问题