Echtzeit-audio-Verarbeitung ohne Ausgabe

Ich bin auf der Suche auf dieses Beispiel http://teragonaudio.com/article/How-to-do-realtime-recording-with-effect-processing-on-iOS.html

und ich möchte mich von meinem Ausgang. Ich versuche es zu ändern: kAudioSessionCategory_PlayAndRecord zu kAudioSessionCategory_RecordAudio aber das wird nicht funktionieren. Ich versuche auch, um loszuwerden off:

  if(AudioUnitSetProperty(*audioUnit, kAudioUnitProperty_StreamFormat,
                            kAudioUnitScope_Output, 1, &streamDescription, sizeof(streamDescription)) != noErr) {
        return 1;
    }

Becouse will ich, um den Ton vom Mikrofon, aber nicht spielen. Aber egal, was ich tun, wenn mein sound zu bekommen renderCallback Methode gibt es einen -50 Fehler. Wenn audio spielt automatisch bei der Ausgabe funktioniert alles einwandfrei...

Update mit code:

using namespace std;

AudioUnit *audioUnit = NULL;

float *convertedSampleBuffer = NULL;

int initAudioSession() {
    audioUnit = (AudioUnit*)malloc(sizeof(AudioUnit));

    if(AudioSessionInitialize(NULL, NULL, NULL, NULL) != noErr) {
        return 1;
    }

    if(AudioSessionSetActive(true) != noErr) {
        return 1;
    }

    UInt32 sessionCategory = kAudioSessionCategory_PlayAndRecord;
    if(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                               sizeof(UInt32), &sessionCategory) != noErr) {
        return 1;
    }

    Float32 bufferSizeInSec = 0.02f;
    if(AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration,
                               sizeof(Float32), &bufferSizeInSec) != noErr) {
        return 1;
    }

    UInt32 overrideCategory = 1;
    if(AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
                               sizeof(UInt32), &overrideCategory) != noErr) {
        return 1;
    }

    //There are many properties you might want to provide callback functions for:
    //kAudioSessionProperty_AudioRouteChange
    //kAudioSessionProperty_OverrideCategoryEnableBluetoothInput
    //etc.

    return 0;
}

OSStatus renderCallback(void *userData, AudioUnitRenderActionFlags *actionFlags,
                        const AudioTimeStamp *audioTimeStamp, UInt32 busNumber,
                        UInt32 numFrames, AudioBufferList *buffers) {
    OSStatus status = AudioUnitRender(*audioUnit, actionFlags, audioTimeStamp,
                                      1, numFrames, buffers);

    int doOutput = 0;

    if(status != noErr) {
        return status;
    }

    if(convertedSampleBuffer == NULL) {
        //Lazy initialization of this buffer is necessary because we don't
        //know the frame count until the first callback
        convertedSampleBuffer = (float*)malloc(sizeof(float) * numFrames);
        baseTime = (float)QRealTimer::getUptimeInMilliseconds();
    }

    SInt16 *inputFrames = (SInt16*)(buffers->mBuffers->mData);

    //If your DSP code can use integers, then don't bother converting to
    //floats here, as it just wastes CPU. However, most DSP algorithms rely
    //on floating point, and this is especially true if you are porting a
    //VST/AU to iOS.

    int i;

    for( i = numFrames; i < fftlength; i++ )        //Shifting buffer
        x_inbuf[i - numFrames] = x_inbuf[i];

    for(  i = 0; i < numFrames; i++) {
        x_inbuf[i + x_phase] = (float)inputFrames[i] / (float)32768;
    }

    if( x_phase + numFrames == fftlength )
    {
        x_alignment.SigProc_frontend(x_inbuf);  //Signal processing front-end (FFT!)
        doOutput = x_alignment.Align();


        ///Output as text! In the real-time version,
        //     this is where we update visualisation callbacks and launch other services
        if ((doOutput) & (x_netscore.isEvent(x_alignment.Position()))
            &(x_alignment.lastAction()<x_alignment.Position()) )
        {
          // here i want to do something with my input!
        }
    }
    else
        x_phase += numFrames;


   return noErr;
}


int initAudioStreams(AudioUnit *audioUnit) {
    UInt32 audioCategory = kAudioSessionCategory_PlayAndRecord;
    if(AudioSessionSetProperty(kAudioSessionProperty_AudioCategory,
                               sizeof(UInt32), &audioCategory) != noErr) {
        return 1;
    }

    UInt32 overrideCategory = 1;
    if(AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
                               sizeof(UInt32), &overrideCategory) != noErr) {
        //Less serious error, but you may want to handle it and bail here
    }

    AudioComponentDescription componentDescription;
    componentDescription.componentType = kAudioUnitType_Output;
    componentDescription.componentSubType = kAudioUnitSubType_RemoteIO;
    componentDescription.componentManufacturer = kAudioUnitManufacturer_Apple;
    componentDescription.componentFlags = 0;
    componentDescription.componentFlagsMask = 0;
    AudioComponent component = AudioComponentFindNext(NULL, &componentDescription);
    if(AudioComponentInstanceNew(component, audioUnit) != noErr) {
        return 1;
    }

    UInt32 enable = 1;
    if(AudioUnitSetProperty(*audioUnit, kAudioOutputUnitProperty_EnableIO,
                            kAudioUnitScope_Input, 1, &enable, sizeof(UInt32)) != noErr) {
        return 1;
    }

    AURenderCallbackStruct callbackStruct;
    callbackStruct.inputProc = renderCallback; //Render function
    callbackStruct.inputProcRefCon = NULL;
    if(AudioUnitSetProperty(*audioUnit, kAudioUnitProperty_SetRenderCallback,
                            kAudioUnitScope_Input, 0, &callbackStruct,
                            sizeof(AURenderCallbackStruct)) != noErr) {
        return 1;
    }

    AudioStreamBasicDescription streamDescription;
    //You might want to replace this with a different value, but keep in mind that the
    //iPhone does not support all sample rates. 8kHz, 22kHz, and 44.1kHz should all work.
    streamDescription.mSampleRate = 44100;
    //Yes, I know you probably want floating point samples, but the iPhone isn't going
    //to give you floating point data. You'll need to make the conversion by hand from
    //linear PCM <-> float.
    streamDescription.mFormatID = kAudioFormatLinearPCM;
    //This part is important!
    streamDescription.mFormatFlags = kAudioFormatFlagIsSignedInteger |
    kAudioFormatFlagsNativeEndian |
    kAudioFormatFlagIsPacked;
    streamDescription.mBitsPerChannel = 16;
    //1 sample per frame, will always be 2 as long as 16-bit samples are being used
    streamDescription.mBytesPerFrame = 2;
    streamDescription.mChannelsPerFrame = 1;
    streamDescription.mBytesPerPacket = streamDescription.mBytesPerFrame *
    streamDescription.mChannelsPerFrame;
    //Always should be set to 1
    streamDescription.mFramesPerPacket = 1;
    //Always set to 0, just to be sure
    streamDescription.mReserved = 0;

    //Set up input stream with above properties
    if(AudioUnitSetProperty(*audioUnit, kAudioUnitProperty_StreamFormat,
                            kAudioUnitScope_Input, 0, &streamDescription, sizeof(streamDescription)) != noErr) {
        return 1;
    }

    //Ditto for the output stream, which we will be sending the processed audio to
    if(AudioUnitSetProperty(*audioUnit, kAudioUnitProperty_StreamFormat,
                            kAudioUnitScope_Output, 1, &streamDescription, sizeof(streamDescription)) != noErr) {
        return 1;
    }

    return 0;
}


int startAudioUnit(AudioUnit *audioUnit) {
    if(AudioUnitInitialize(*audioUnit) != noErr) {
        return 1;
    }

    if(AudioOutputUnitStart(*audioUnit) != noErr) {
        return 1;
    }

    return 0;
}

Und Anrufe aus meinem VC:

  initAudioSession();
    initAudioStreams( audioUnit);
    startAudioUnit( audioUnit);
InformationsquelleAutor Jakub | 2013-03-21
Schreibe einen Kommentar