¿Cómo get array de datos flotantes de audio de AudioQueueRef en iOS?

Estoy trabajando para get audio en el iPhone en una forma en que pueda pasarlo a un algorithm de análisis (C ++). Hay, por supuesto, muchas opciones: el tutorial de AudioQueue en trailsinthesand comienza a funcionar.

La callback de audio, sin embargo, da un AudioQueueRef , y estoy encontrando la documentation de Apple delgada en este lado de las cosas. Métodos incorporados para escribir en un file, pero nada en el que parezca realmente dentro de los packages para ver los datos.

Necesito datos No quiero escribir nada en un file, que es lo que parecen apuntar todos los tutoriales, e incluso los objects de E / S convenientes de Apple. Apple AVAudioRecorder (exasperantemente) le dará niveles y escribirá los datos, pero en realidad no le dará acceso a él. A less que me falte algo …

¿Como hacer esto? En el siguiente código hay inBuffer->mAudioData que está tentadoramente cerca, pero no puedo encontrar ninguna información sobre el formatting en el que se encuentra este "dato" o cómo acceder a él.

AudioQueue Callback:

 void AudioInputCallback(void *inUserData, AudioQueueRef inAQ, AudioQueueBufferRef inBuffer, const AudioTimeStamp *inStartTime, UInt32 inNumberPacketDescriptions, const AudioStreamPacketDescription *inPacketDescs) { static int count = 0; RecordState* recordState = (RecordState*)inUserData; AudioQueueEnqueueBuffer(recordState->queue, inBuffer, 0, NULL); ++count; printf("Got buffer %d\n", count); } 

Y el código para escribir el audio en un file:

 OSStatus status = AudioFileWritePackets(recordState->audioFile, false, inBuffer->mAudioDataByteSize, inPacketDescs, recordState->currentPacket, &inNumberPacketDescriptions, inBuffer->mAudioData); // THIS! This is what I want to look inside of. if(status == 0) { recordState->currentPacket += inNumberPacketDescriptions; } 

  // so you don't have to hunt them all down when you decide to switch to float: #define AUDIO_DATA_TYPE_FORMAT SInt16 // the actual sample-grabbing code: int sampleCount = inBuffer->mAudioDataBytesCapacity / sizeof(AUDIO_DATA_TYPE_FORMAT); AUDIO_DATA_TYPE_FORMAT *samples = (AUDIO_DATA_TYPE_FORMAT*)inBuffer->mAudioData; 

Luego tiene su (en este caso SInt16 ) samples matriz a las que puede acceder desde las samples[0] a las samples[sampleCount-1] .

La solución anterior no funcionó para mí; estaba recibiendo los datos de muestra incorrectos en sí. (Un problema endian) Si en algún caso alguien está recibiendo datos de muestra incorrectos en el futuro, espero que esto lo ayude a:

– (vacío) feedSamplesToEngine: (UInt32) audioDataBytesCapacity audioData: (void *) audioData {int sampleCount = audioDataBytesCapacity / sizeof (SAMPLE_TYPE);

 SAMPLE_TYPE *samples = (SAMPLE_TYPE*)audioData; //SAMPLE_TYPE *sample_le = (SAMPLE_TYPE *)malloc(sizeof(SAMPLE_TYPE)*sampleCount );//for swapping endians std::string shorts; double power = pow(2,10); for(int i = 0; i < sampleCount; i++) { SAMPLE_TYPE sample_le = (0xff00 & (samples[i] << 8)) | (0x00ff & (samples[i] >> 8)) ; //Endianess issue char dataInterim[30]; sprintf(dataInterim,"%f ", sample_le/power); // normalize it. shorts.append(dataInterim); }