2012-04-23 9 views
6

Recibo el error -50 (parámetros no válidos) de AudioUnitRender en el siguiente contexto. Estoy usando esta aplicación de ejemplo Pitch Detector como mi punto de partida, y funciona bien. La única diferencia importante en mi proyecto es que también estoy usando la unidad de E/S remotas para la salida de audio. La salida de audio funciona bien. Aquí está mi devolución de llamada de entrada y mi código de inicialización (con la verificación de errores eliminada por brevedad). Sé que es mucho, pero el error -50 realmente me da muy poca información sobre dónde podría estar el problema.Error -50 de AudioUnitRender

de devolución de llamada de entrada:

OSStatus inputCallback(void* inRefCon, 
          AudioUnitRenderActionFlags *ioActionFlags, 
          const AudioTimeStamp  *inTimeStamp, 
          UInt32      inBusNumber, 
          UInt32      inNumberFrames, 
          AudioBufferList    *ioData) { 

    WBAudio* audioObject= (WBAudio*)inRefCon; 

    AudioUnit rioUnit = audioObject->m_audioUnit; 
    OSStatus renderErr; 
    UInt32 bus1 = 1; 

    renderErr = AudioUnitRender(rioUnit, ioActionFlags, 
           inTimeStamp, bus1, inNumberFrames, audioObject->m_inBufferList); 
    if (renderErr < 0) { 
     return renderErr; // breaks here 
    } 

    return noErr; 
} // end inputCallback() 

inicialización:

- (id) init { 

    self= [super init]; 
    if(!self) return nil; 

    OSStatus result; 

    //! Initialize a buffer list for rendering input 
    size_t bytesPerSample; 
    bytesPerSample = sizeof(SInt16); 
    m_inBufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer)); 
    m_inBufferList->mNumberBuffers = 1; 
    m_inBufferList->mBuffers[0].mNumberChannels = 1; 
    m_inBufferList->mBuffers[0].mDataByteSize = 512*bytesPerSample; 
    m_inBufferList->mBuffers[0].mData = calloc(512, bytesPerSample); 

    //! Initialize an audio session to get buffer size 
    result = AudioSessionInitialize(NULL, NULL, NULL, NULL); 

    UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord; 
    result = AudioSessionSetProperty(kAudioSessionProperty_AudioCategory, sizeof(audioCategory), &audioCategory); 

    // Set preferred buffer size 
    Float32 preferredBufferSize = static_cast<float>(m_pBoard->m_uBufferSize)/m_pBoard->m_fSampleRate; 
    result = AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, sizeof(preferredBufferSize), &preferredBufferSize); 

    // Get actual buffer size 
    Float32 audioBufferSize; 
    UInt32 size = sizeof (audioBufferSize); 
    result = AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareIOBufferDuration, &size, &audioBufferSize); 

    result = AudioSessionSetActive(true); 

    //! Create our Remote I/O component description 
    AudioComponentDescription desc; 
    desc.componentType= kAudioUnitType_Output; 
    desc.componentSubType= kAudioUnitSubType_RemoteIO; 
    desc.componentFlags= 0; 
    desc.componentFlagsMask= 0; 
    desc.componentManufacturer= kAudioUnitManufacturer_Apple; 

    //! Find the corresponding component 
    AudioComponent outputComponent = AudioComponentFindNext(NULL, &desc); 

    //! Create the component instance 
    result = AudioComponentInstanceNew(outputComponent, &m_audioUnit); 

    //! Enable audio output 
    UInt32 flag = 1; 
    result = AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag)); 

    //! Enable audio input 
    result= AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, kInputBus, &flag, sizeof(flag)); 

    //! Create our audio stream description 
    m_audioFormat.mSampleRate= m_pBoard->m_fSampleRate; 
    m_audioFormat.mFormatID= kAudioFormatLinearPCM; 
    m_audioFormat.mFormatFlags= kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked; 
    m_audioFormat.mFramesPerPacket= 1; 
    m_audioFormat.mChannelsPerFrame= 1; 
    m_audioFormat.mBitsPerChannel= 16; 
    m_audioFormat.mBytesPerPacket= 2; 
    m_audioFormat.mBytesPerFrame= 2; 

    //! Set the stream format 
    result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &m_audioFormat, sizeof(m_audioFormat)); 

    result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_StreamFormat, 
           kAudioUnitScope_Output, 
           kInputBus, &m_audioFormat, sizeof(m_audioFormat)); 

    //! Set the render callback 
    AURenderCallbackStruct renderCallbackStruct= {0}; 
    renderCallbackStruct.inputProc= renderCallback; 
    renderCallbackStruct.inputProcRefCon= m_pBoard; 
    result = AudioUnitSetProperty(m_audioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &renderCallbackStruct, sizeof(renderCallbackStruct)); 

    //! Set the input callback 
    AURenderCallbackStruct inputCallbackStruct = {0}; 
    inputCallbackStruct.inputProc= inputCallback; 
    inputCallbackStruct.inputProcRefCon= self; 
    result= AudioUnitSetProperty(m_audioUnit, kAudioOutputUnitProperty_SetInputCallback, kAudioUnitScope_Input, kOutputBus, &inputCallbackStruct, sizeof(inputCallbackStruct)); 

    //! Initialize the unit 
    result = AudioUnitInitialize(m_audioUnit); 

    return self; 
} 
+1

Compruebe para asegurarse de que su bus1 y inBusNumber son los mismos. Además, el sitio web que menciona no tiene código para un detector de tono, solo un detector de frecuencia de pico mal etiquetado, que a menudo fallará en la estimación del tono. – hotpaw2

+0

Son lo mismo. Y definitivamente tomaré la detección de pitch con un grano de sal. – Luke

+0

¿Pudo resolverlo? Tengo el problema de que normalmente la llamada a AudioUnitRender tiene éxito, pero cuando mi aplicación vuelve desde el fondo falla, porque la devolución de llamada de entrada solicita más bytes. Mi primer pensamiento fue que tiene algo que ver con los tamaños de mi búfer, pero aumentarlos no ayudó – tomk

Respuesta

0

está asignando el m_inBufferList como:

m_inBufferList = (AudioBufferList *)malloc(sizeof(AudioBuffer)); 

Esto debería ser:

m_inBufferList = (AudioBufferList *)malloc(sizeof(AudioBufferList) + sizeof(AudioBuffer) * numberOfBuffers); //numberOfBuffers in your case is 1 

Quizás esto pueda resolver su problema.

+0

Te falta un paréntesis en alguna parte. –

+0

Buena captura pero el error sigue ahí. – Luke

+2

Como solo quiere 1 buffer, puede omitir el segundo sizeof, porque la declaración de AudioBufferList ya asigna un mbuffer – tomk

1

Error -50 en el doc desarrollar medios de error params, asegurarse de que tiene pasar los parametros adecuados en AudioUnitRender. comprobar el formato de flujo y su unidad

Cuestiones relacionadas