Extraer datos de amplitud de PCM lineal en el iPhone

Tengo dificultades para extraer datos de amplitud del PCM lineal en el iPhone almacenado en un file audio.caf.

Mis preguntas son:

  1. El PCM lineal almacena muestras de amplitud como valores de 16 bits. ¿Es esto correcto?
  2. ¿Cómo se almacena la amplitud en los packages devueltos por AudioFileReadPacketData ()? Cuando se graba un PCM lineal mono, ¿no es cada muestra (en un cuadro, en un package) solo una matriz para SInt16? ¿Cuál es el order de bytes (big endian vs little endian)?
  3. ¿Qué significa cada uno de los pasos en la amplitud lineal del PCM físicamente?
  4. Cuando el PCM lineal se graba en el iPhone, ¿está el punto central 0 (SInt16) o 32768 (UInt16)? ¿Qué significan los valores máximos mín. En la forma de onda física / presión de air?

y una pregunta adicional: ¿hay forms de onda de sonido / presión de air que el micrófono del iPhone no puede medir?

Mi código sigue:

// get the audio file proxy object for the audio AudioFileID fileID; AudioFileOpenURL((CFURLRef)audioURL, kAudioFileReadPermission, kAudioFileCAFType, &fileID); // get the number of packets of audio data contained in the file UInt64 totalPacketCount = [self packetCountForAudioFile:fileID]; // get the size of each packet for this audio file UInt32 maxPacketSizeInBytes = [self packetSizeForAudioFile:fileID]; // setup to extract the audio data Boolean inUseCache = false; UInt32 numberOfPacketsToRead = 4410; // 0.1 seconds of data UInt32 ioNumPackets = numberOfPacketsToRead; UInt32 ioNumBytes = maxPacketSizeInBytes * ioNumPackets; char *outBuffer = malloc(ioNumBytes); memset(outBuffer, 0, ioNumBytes); SInt16 signedMinAmplitude = -32768; SInt16 signedCenterpoint = 0; SInt16 signedMaxAmplitude = 32767; SInt16 minAmplitude = signedMaxAmplitude; SInt16 maxAmplitude = signedMinAmplitude; // process each and every packet for (UInt64 packetIndex = 0; packetIndex < totalPacketCount; packetIndex = packetIndex + ioNumPackets) { // reset the number of packets to get ioNumPackets = numberOfPacketsToRead; AudioFileReadPacketData(fileID, inUseCache, &ioNumBytes, NULL, packetIndex, &ioNumPackets, outBuffer); for (UInt32 batchPacketIndex = 0; batchPacketIndex < ioNumPackets; batchPacketIndex++) { SInt16 packetData = outBuffer[batchPacketIndex * maxPacketSizeInBytes]; SInt16 absoluteValue = abs(packetData); if (absoluteValue < minAmplitude) { minAmplitude = absoluteValue; } if (absoluteValue > maxAmplitude) { maxAmplitude = absoluteValue; } } } NSLog(@"minAmplitude: %hi", minAmplitude); NSLog(@"maxAmplitude: %hi", maxAmplitude); 

¡Con este código casi siempre obtengo un mínimo de 0 y un máximo de 128! Eso no tiene sentido.

Estoy grabando el audio usando AVAudioRecorder de la siguiente manera:

 // specify mono, 44.1 kHz, Linear PCM with Max Quality as recording format NSDictionary *recordSettings = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithFloat: 44100.0], AVSampleRateKey, [NSNumber numberWithInt: kAudioFormatLinearPCM], AVFormatIDKey, [NSNumber numberWithInt: 1], AVNumberOfChannelsKey, [NSNumber numberWithInt: AVAudioQualityMax], AVEncoderAudioQualityKey, nil]; // store the sound file in the app doc folder as calibration.caf NSString *documentsDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]; NSURL *audioFileURL = [NSURL fileURLWithPath:[documentsDir stringByAppendingPathComponent: @"audio.caf"]]; // create the audio recorder NSError *createAudioRecorderError = nil; AVAudioRecorder *newAudioRecorder = [[AVAudioRecorder alloc] initWithURL:audioFileURL settings:recordSettings error:&createAudioRecorderError]; [recordSettings release]; if (newAudioRecorder) { // record the audio self.recorder = newAudioRecorder; [newAudioRecorder release]; self.recorder.delegate = self; [self.recorder prepareToRecord]; [self.recorder record]; } else { NSLog(@"%@", [createAudioRecorderError localizedDescription]); } 

Gracias por cualquier idea que puedas ofrecer. Este es mi primer proyecto con Core Audio, ¡así que siéntete libre de romper mi enfoque!

PS He intentado search en los files de la list Core Audio, pero la request sigue dando un error: ( http://search.lists.apple.com/?q=linear+pcm+amplitude&cmd=Search%21&ul=coreaudio-api )

PPS he mirado:

http://en.wikipedia.org/wiki/Sound_pressure

http://en.wikipedia.org/wiki/Linear_PCM

http://wiki.multimedia.cx/index.php?title=PCM

¿Obtiene la amplitud en un momento dado dentro de un file de sonido?

http://music.columbia.edu/pipermail/music-dsp/2002-April/048341.html

También he leído la totalidad de Core Audio Overview y la mayor parte de la Guía de progtwigción de sesiones de audio, pero mis preguntas continúan.

1) las rutinas de lectura del file os x / iphone le permiten determinar el formatting de muestra, típicamente uno de SInt8, SInt16, SInt32, Float32, Float64, o 24 contiguos firmados int para LPCM

2) para formattings int, MIN_FOR_TYPE representa la amplitud máxima en la fase negativa, y MAX_FOR_TYPE representa la amplitud máxima en el positivo. 0 equivale al silencio. los formattings de punto flotante modulan entre [-1 … 1], con cero como con float. al leer, escribir, grabar o trabajar con un formatting específico, el endianness será importante: un file puede requerir un formatting específico y, por lo general, desea manipular los datos en el endianness nativo. algunas rutinas en las libs de file de audio de Apple le permiten pasar un indicador que denota el origen endianness, en lugar de convertirlo manualmente. CAF es un poco más complicado: actúa como un envoltorio de meta para uno o más files de audio y es compatible con muchos types.

3) la representación de amplitud para lpcm es solo una representación de la amplitud lineal de la fuerza bruta (no se requiere conversión / deencoding para la reproducción, y los pasos de amplitud son iguales).

4) ver # 2. los valores no están relacionados con la presión del air, están relacionados con 0 dBFS; Por ejemplo, si está enviando la secuencia directamente a un DAC, entonces el int max (o -1/1 si el punto flotante) representa el nivel en el que una muestra individual se recortará.

Bonificación), al igual que todos los ADC y la cadena de componentes tiene límites a lo que puede manejar en la input en términos de voltaje. Además, la frecuencia de muestreo define la frecuencia más alta que se puede capturar (la más alta es la mitad de la frecuencia de muestreo). el ADC puede usar una profundidad de bits fija o seleccionable, pero la tensión de input máxima generalmente no cambia al elegir otra profundidad de bits.

un error que estás cometiendo en el nivel de código: estás manipulando `outBuffer 'como caracteres, no SInt16

  1. Si solicita muestras de 16 bits en su formatting de grabación, obtendrá muestras de 16 bits. Pero existen otros formattings en muchas API de grabación / reproducción de Core Audio, y en posibles formattings de file caf.

  2. En mono, solo obtienes una matriz de ints firmados de 16 bits. Puedes pedir específicamente endian grande o pequeño en algunas de las API de grabación Core Audio.

  3. A less que desee calibrar el micrófono del model de su dispositivo particular o su micrófono externo (y asegúrese de que el procesamiento de audio / AGC esté desactivado), es posible que desee considerar que los niveles de audio sean de escala arbitraria. Además, la respuesta varía también con la direccionalidad del micrófono y la frecuencia de audio.

  4. El punto central para muestras de audio de 16 bits es comúnmente 0 (range de aproximadamente -32k a 32k). Sin sesgo