Detección de un tono de baja frecuencia en un file de audio

Sé que esta pregunta se ha preguntado cientos de veces … Pero me estoy frustrando con mi resultado, así que quería volver a preguntar. Antes de sumergirme en profundidad, necesito resolver esta sencilla tarea.

Necesito detectar un tono de 20 Hz en un audiofile. Inserto el tono 20hz como en la foto. (Puede ser cualquier frecuencia mientras el oyente no pueda escucharla, así que pensé que debía elegir una frecuencia de 20 a 50 Hz)

introduzca la descripción de la imagen aquí

información sobre el audiofile

afinfo 1.m4a File: 1.m4a File type ID: adts Num Tracks: 1 ---- Data format: 1 ch, 22050 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame Channel layout: Mono estimated duration: 8.634043 sec audio bytes: 42416 audio packets: 219 bit rate: 33364 bits per second packet size upper bound: 768 maximum packet size: 319 audio data file offset: 0 optimized format list: [ 0] format: 1 ch, 22050 Hz, 'aac ' (0x00000000) 0 bits/channel, 0 bytes/packet, 1024 frames/packet, 0 bytes/frame Channel layout: Mono ---- 

Seguí estos tres tutoriales y se me ocurrió un código de trabajo que lee el buffer de audio y me da dobles fps.

http://blog.bjornroche.com/2012/07/frequency-detection-using-fft-aka-pitch.html
https://github.com/alexbw/iPhoneFFT
¿Cómo obtengo las frecuencias de cada valor en un FFT?

Leí los datos de la siguiente manera

 // If there's more packets, read them inCompleteAQBuffer->mAudioDataByteSize = numBytes; CheckError(AudioQueueEnqueueBuffer(inAQ, inCompleteAQBuffer, (sound->packetDescs?nPackets:0), sound->packetDescs), "couldn't enqueue buffer"); sound->packetPosition += nPackets; int numFrequencies=2048; int kNumFFTWindows=10; SInt16 *testBuffer = (SInt16*)inCompleteAQBuffer->mAudioData; //Read data from buffer...! OouraFFT *myFFT = [[OouraFFT alloc] initForSignalsOfLength:numFrequencies*2 andNumWindows:kNumFFTWindows]; for(long i=0; i<myFFT.dataLength; i++) { myFFT.inputData[i] = (double)testBuffer[i]; } [myFFT calculateWelchPeriodogramWithNewSignalSegment]; for (int i=0;i<myFFT.dataLength/2;i++) { NSLog(@"the spectrum data %d is %f ",i,myFFT.spectrumData[i]); } 

y mi logging fuera algo como

 Everything checks out for 4096 samples of data Set up all values, about to init window type 2 the spectrum data 0 is 42449.823771 the spectrum data 1 is 39561.024361 . . . . the spectrum data 2047 is -42859933071799162597786649755206634193030992632381393031503716729604050285238471034480950745056828418192654328314899253768124076782117157451993697900895932215179138987660717342012863875797337184571512678648234639360.000000 

Sé que todavía no estoy calculando la magnitud, pero ¿cómo puedo detectar que el sonido tiene 20 hz? ¿Necesito aprender el algorithm de Goertzel?

Hay muchas forms de transmitir información que se inserta en un patrón de onda preexistente. La información que entra puede variar según la amplitud (modulación de amplitud) o frecuencia (modulación de frecuencia), etc. ¿Tiene una estrategia aquí? Tenga en count que la densidad de información que desea transmitir puede verse influenciada por factores como la frecuencia de modulación (las frecuencias más altas, naturalmente, pueden transmitir más información, ya que puede resolver los cambios más veces por segundo).

Otro enfoque es posible si tanto el emisor como el receptor tienen el audio de origen (reference). En este caso, el receptor podría hacer un cambio entre la reference y el audio recibido real para resolver la información extra transmitida. Una variación en esto sería hacer que el emisor envíe ~~ mismo ~~ audio dos veces, primero envíe el audio sin tocar de reference seguido de una versión modulada de este mismo audio de reference de esa manera, el receptor simplemente hará un diff entre estos dos audiblemente ~~ mismo ~~ clips para resolver el audio embedded.

Volviendo a su pregunta original … si el emisor y el receptor tienen un acuerdo … digamos que durante un período de time X se envía el tono de reference puro de 20 Hz seguido de otro período X que el tono de 20 Hz está modulado por su información de input a altere su amplitud o frecuencia … entonces simplemente repita este patrón … en el lado receptor, simplemente hacen un cambio entre cada par de períodos de time para resolver su información modulada … para que esto funcione, el audio fuente no puede tener ningún los tonos debajo de algunas frecuencias dicen 100 Hz (se elimina esa banda de frecuencia si es necesario) simplemente para eliminar la interferencia del audio de origen … no ha mencionado qué tipo de datos desea transmitir … si su voz primero necesita estirarse bajando de hecho su range de frecuencia desde el range de 1 kHz hasta su range bajo de 20 Hz … una vez que el resultado de diff está disponible en el lado de recepción, entonces exprime esta curva para restablecerlo al range de voz normal de 1 kHz … tal vez más trabajo de lo que tienes time para pero esto podría funcionar … la radio AM / FM real usa modulación para enviar frecuencias de voz a través de mega Hz para que funcione