Hello

I am trying to write an external plugin that simply reads audio from the built 
in microphone, obtains the raw audio data, and passes it to an SDK API.
My setup is very simple, I have a single session, with a single input device 
(built in microphone) and a single output (AVCaptureAudioDataOutput)
I Initialize the Session, Input, and Output as follow:

            // Obtain the device and retain it

            _pAudioCaptureInput = [pAVInputDevice retain];


            // Initialize Capture Session

            _dispatchQueue = dispatch_get_main_queue();

            _pCaptureSession = [[AVCaptureSession alloc] init];

            _pCaptureSession.sessionPreset = AVCaptureSessionPresetHigh;



            // Put the Device inside an Input

            pInputDevice = [[AVCaptureDeviceInput alloc] 
initWithDevice:_pAudioCaptureInput error:&pError];

            [_pCaptureSession addInput:pInputDevice]; // Add Audio Input to 
Session

            [pInputDevice release];

            pInputDevice = nil;


            // Setup the Output Configurations

            NSDictionary *pAudioSettings = [NSDictionary 
dictionaryWithObjectsAndKeys:

                                                   [NSNumber 
numberWithInt:kAudioFormatLinearPCM], AVFormatIDKey,

                                                   [NSNumber 
numberWithInt:44100], AVSampleRateKey,

                                                   [NSNumber numberWithInt:2], 
AVNumberOfChannelsKey,

                                                   [NSNumber numberWithInt:16], 
AVLinearPCMBitDepthKey,

                                                   [NSNumber 
numberWithBool:NO], AVLinearPCMIsFloatKey,

                                                   [NSNumber 
numberWithBool:NO], AVLinearPCMIsBigEndianKey,

                                                   nil];




            // Create the Output

            _pAudioCaptureOutput = [[AVCaptureAudioDataOutput alloc] init];

            [_pAudioCaptureOutput setAudioSettings:pAudioSettings]; // Apply 
Output Settings

            [_pCaptureSession addOutput:_pAudioCaptureOutput]; // Add Output to 
Session


            // Create the Output Delegate that will receive the SampleBuffer 
callbacks

            _pAudioCaptureDelegate = [[ACaptureDelegate alloc] init];

            [_pAudioCaptureOutput setSampleBufferDelegate:_pAudioCaptureDelegate

                                                    queue:_dispatchQueue];



            // Remember the Device Name

            _deviceName = [_pAudioCaptureInput.localizedName UTF8String];

I start the session running by calling startRunning on the session.  My 
callback delegate is notified with Audio Samples.  The follow is the callback 
implementation:


- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
fromConnection:(AVCaptureConnection *)connection

{

// Save the Timescale

    CMTime timestamp = 
CMSampleBufferGetOutputPresentationTimeStamp(sampleBuffer);

    if(_timescale == -1) {

        _timescale = timestamp.timescale;

    }

    CMItemCount numSamples = CMSampleBufferGetNumSamples(sampleBuffer);


    // Get Audio Data

    CMBlockBufferRef dataBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);

    zuint32 dataLength = CMBlockBufferGetDataLength(dataBuffer);



    AVCaptureAudioDataOutput *pOutput = static_cast<AVCaptureAudioDataOutput 
*>(captureOutput);

    NSDictionary *pAudioSettings = pOutput.audioSettings;



    // Retrieve Audio Settings Information from AVOutputDevice

    NSNumber *audioSettingValue = nil;

    zint32 sampleRate = 44100;

    audioSettingValue = [pAudioSettings objectForKey:AVSampleRateKey];

    if(audioSettingValue) {

        sampleRate = [audioSettingValue intValue];

    }


    zint32 bitDepth = 16;

    audioSettingValue = [pAudioSettings objectForKey:AVLinearPCMBitDepthKey];

    if(audioSettingValue) {

        bitDepth = [audioSettingValue intValue];

    }



    zint32 channels = 2;

    audioSettingValue = [pAudioSettings objectForKey:AVNumberOfChannelsKey];

    if(audioSettingValue) {

        channels = [audioSettingValue intValue];

    }




    zuint8 *pAudioData = new zuint8[dataLength];

    OSStatus err = CMBlockBufferCopyDataBytes(dataBuffer, 0, dataLength, 
pAudioData);

    if(err == noErr) {

// Populate SDK Audio structure

        _audioBuffer.format = kFormatPCM;

        _audioBuffer.dataLength = dataLength;

        _audioBuffer.timeStamp = 0;

        _audioBuffer.flags = kBufferFlagTimeValid;

        _audioBuffer.sampleRate = sampleRate;

        _audioBuffer.bitsPerSample = bitDepth;

        _audioBuffer.channels = channels;

        _audioBuffer.data = pAudioData; // The Raw Audio Data



// Send Audio Data to SDK API

        _pAudioDataArriveCallback(_pAudioDataArriveContext, &_audioBuffer);



        delete [] pAudioData;

        pAudioData = NULL;

    }

}

The Problem is, the audio is playing back with a higher pitch.  Like someone is 
fast forwarding.  If I adjust the SampleRate in the Output Audio Settings, it 
affects the play out.
Higher I set it, the less squeaky it becomes, but never correct.  Is there any 
initialization step I am missing?

I have not been able to play the raw audio data back myself without the main 
app as I am new to AVFoundation and CoreAudio.
If someone has sample code of getting this up, I would much appreciate it.

Thanks,
-San Saeteurn

_______________________________________________

Cocoa-dev mailing list ([email protected])

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to [email protected]

Reply via email to