2010-09-30 12 views
10

Tengo dificultades para extraer datos de amplitud del PCM lineal en el iPhone almacenado en un audio.caf.Extracción de datos de amplitud desde PCM lineal en el iPhone

Mis preguntas son:

  1. tiendas PCM lineal de amplitud muestras como valores de 16 bits. ¿Es esto correcto?
  2. ¿Cómo se almacena la amplitud en paquetes devueltos por AudioFileReadPacketData()? Al grabar PCM lineales mono, ¿no es cada muestra, (en un cuadro, en un paquete) solo una matriz para SInt16? ¿Cuál es el orden de bytes (big endian vs. little endian)?
  3. ¿Qué significa físicamente cada paso en la amplitud PCM lineal?
  4. Cuando se graba PCM lineal en el iPhone, ¿el punto central es 0 (SInt16) o 32768 (UInt16)? ¿Qué significan los valores mínimos máximos en la forma de onda física/presión de aire?

y una pregunta adicional: ¿Hay formas de ondas de presión de sonido/aire que el micrófono iPhone no puede medir?

Mi código de la siguiente manera:

// 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 dan un mínimo de 0 y un máximo de 128! Eso no me hace sentido a .

estoy grabando el audio usando el 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 puede ofrecer. Este es mi primer proyecto usando Core Audio, ¡así que siéntete libre de romper mi enfoque!

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

P.P.S. He mirado:

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

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

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

Get the amplitude at a given time within a sound file?

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

También he leído la totalidad del Core Audio Descripción y la mayor parte del audio Programación de sesión Guía, pero mis preguntas permanecen.

Respuesta

7

1) el sistema operativo archivo x/iphone leer rutinas le permiten determinar el formato de muestra, por lo general uno de SInt8, Sint16, Sint32, Float32, float64, o contigua int firmado 24 bits para LPCM

2) para formatos 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 es igual a silencio los formatos de punto flotante modulan entre [-1 ... 1], con cero como con float. al leer, escribir, grabar o trabajar con un formato específico, la endianidad importará: un archivo puede requerir un formato específico y, por lo general, usted desea manipular los datos en la endianidad nativa. algunas rutinas en las librerías de archivos de audio de Apple le permiten pasar una bandera que indica endianidad de origen, en lugar de convertirla manualmente. CAF es un poco más complicado: actúa como un contenedor de metadatos para uno o más archivos de audio y admite muchos tipos.

3) la representación de amplitud para lpcm es solo una representación de amplitud lineal de fuerza bruta (no se requiere conversión/descodificación 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 aire, están relacionados con 0 dBFS; p.ej. si está enviando la transmisión directamente a un DAC, entonces int max (o -1/1 si es un punto flotante) representa el nivel en el que se recortará una muestra individual.

Bonificación), al igual que todas las CAD y las cadenas de componentes tienen límites a lo que puede manejar la entrada en términos de voltaje. además, la tasa de muestreo define la frecuencia más alta que se puede capturar (la más alta es la mitad de la frecuencia de muestreo). la adc puede usar una profundidad de bits fija o seleccionable, pero la tensión de entrada máxima generalmente no cambia cuando se elige otra profundidad de bits.

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

2
  1. Si solicita muestras de 16 bits en el formato de grabación, obtendrá muestras de 16 bits. Pero existen otros formatos en muchas API de grabación/reproducción de Core Audio y en posibles formatos de archivos caf.

  2. En mono, acaba de obtener una serie de entradas de 16 bit firmadas. Puedes pedir específicamente endian grande o pequeño en algunas de las API de grabación de Core Audio.

  3. A menos que desee calibrar para el micrófono de su dispositivo particular o para su micrófono externo (y asegúrese de que el procesamiento de audio/AGC esté desactivado), quizás desee considerar los niveles de audio como escalados arbitrarios. Además, la respuesta varía con la direccionalidad del micrófono y la frecuencia de audio también.

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

Cuestiones relacionadas