2009-06-25 11 views
5

Sto cercando un modo per modificare il tono dell'audio registrato mentre viene salvato su disco o riprodotto (in tempo reale). Capisco che le unità audio possano essere utilizzate per questo. L'iPhone offre un supporto limitato per le unità audio (ad esempio non è possibile creare/utilizzare unità audio personalizzate, per quanto ne so), ma sono disponibili diverse unità audio pronte all'uso, una delle quali è AUPitch.Come utilizzare un'unità audio su iPhone

Come utilizzare esattamente un'unità audio (in particolare AUPitch)? Lo si collega in una coda audio in qualche modo? È possibile unire insieme le unità audio (ad esempio, per aggiungere contemporaneamente un effetto eco e un cambiamento di intonazione)?

MODIFICA: dopo aver ispezionato le intestazioni dell'SDK dell'iPhone (penso AudioUnit.h, non sono di fronte a un Mac al momento), ho notato che AUPitch è stato commentato. Quindi non sembra che AUPitch sia disponibile su iPhone, dopotutto. piangerepiangere

Apple sembra avere una migliore organizzato la loro documentazione iPhone SDK a developer.apple.com negli ultimi tempi - ora il suo più difficile trovare riferimenti a AUPitch, ecc

Detto questo, ho' Mi interessano ancora le risposte di qualità sull'utilizzo di unità audio (in generale) su iPhone.

risposta

4

Qui ci sono alcune ottime risorse (http://michael.tyson.id.au/2008/11/04/using-remoteio-audio-unit/) per l'utilizzo dell'unità audio RemoteIO. Nella mia esperienza di lavoro con Audio Units su iPhone, ho scoperto che posso implementare manualmente una trasformazione nella funzione di callback. In tal modo, potresti scoprire che risolvi il tuo problema.

1

Per quanto riguarda il cambio di tono su iPhone, OpenAL è la strada da percorrere. Scopri la classe SoundManager disponibile su www.71squared.com per un ottimo esempio di un motore audio OpenAL che supporta l'intonazione.

+0

Ricordarsi che OpenAL supporta solo il cambiamento di intonazione audio in tempo reale, significa che non puoi salvare l'audio modificato – hyd00

0
- (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); 

} 

cambierà passo sulla base di fattore

0

Ho usato l'unità audio NewTimePitch per questo prima, la descrizione audio componente di ciò è

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

allora è possibile modificare il pitch parametro con una chiamata AudioUnitSetParamater. Per esempio, questo cambia il passo da -1000 centesimi

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

I parametri per questa unità audio sono i seguenti

// 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 
}; 

ma avrete solo bisogno di cambiare il parametro di campo per i vostri scopi. Per una guida su come implementare questo rimanda alla risposta di Justin

Problemi correlati