Pregunta

Estoy haciendo algunos progresos en tomar un comprimido de sonido (mp3) y guardarlo como PCM. Además, quería dividir el archivo original en trozos que son 2 segundos de duración, dentro del mismo proceso. Me parece tener éxito, pero estoy un poco confundido en cuanto a por qué.

Al leer bloques de audio y grabar los archivos a cabo, puedo comprobar para ver si estoy a punto de escribir un trozo que haría que mi archivo excede mi segundo límite 2. Si es así, escribo lo suficiente como para llegar a 2 segundos, cierre el archivo y abra un nuevo archivo y escribir el resto en el nuevo archivo, y luego leer más datos. Algo como esto:

framesInTimedSegment += numFrames;
if ((framesInTimedSegment  > (2.0 * sampleRate)) && (j < 5)) {
    UInt32 newNumFrames = numFrames;
    numFrames = framesInTimedSegment - (2.0 * sampleRate);
    newNumFrames -= numFrames;
// Question A
    UInt32 segmentOffset = newNumFrames * numChannels * 2;
    error = ExtAudioFileWrite(segmentFile, newNumFrames, &fillBufList);
// Question B
       // handle this error!  We might have an interruption
    if (segmentFile) ExtAudioFileDispose(segmentFile);
    XThrowIfError(ExtAudioFileCreateWithURL(urlArray[++j], kAudioFileCAFType, &dstFormat, NULL, kAudioFileFlags_EraseFile, &breakoutFile), "ExtAudioFileCreateWithURL failed! - segmentFile");
    size = sizeof(clientFormat);
    XThrowIfError(ExtAudioFileSetProperty(segmentFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat), "couldn't set destination client format"); 
    fillBufList.mBuffers[0].mData = srcBuffer + segmentOffset;
    fillBufList.mBuffers[0].mDataByteSize = numFrames * fillBufList.mBuffers[0].mNumberChannels * 2;
    framesInTimedSegment = numFrames;
}
error = ExtAudioFileWrite(segmentFile, numFrames, &fillBufList);

Aquí están mis preguntas (He tratado de etiquetar la línea correspondiente):

A: ¿Hay una mejor manera de encontrar el valor de desviación en mi memoria intermedia por lo que no dura código erróneamente algún valor en allí? Por ejemplo, hay una manera bendita para obtener los datos de corrección de número de cuadro?

B: Si ExtAudioFileWrite está haciendo la conversión de comprimido para descomprimir, los datos que estoy escribiendo todavía no se ha descomprimido (¿verdad?), Así que no debería tener que preocuparse acerca de jugar con números del marco y las compensaciones cuando estoy tratando con datos comprimidos? Debería ser en su lugar de convertir el archivo en primer lugar, ya sea en un archivo PCM o en la memoria, y luego dividir esa PCM?

Gracias!

-mahboud

ps.

El clientFormat se define como sigue:

        clientFormat = dstFormat;

y dstFormat:

        dstFormat.mFormatID = outputFormat;
        dstFormat.mChannelsPerFrame = srcFormat.NumberChannels();
        dstFormat.mBitsPerChannel = 16;
        dstFormat.mBytesPerPacket = dstFormat.mBytesPerFrame = 2 * dstFormat.mChannelsPerFrame;
        dstFormat.mFramesPerPacket = 1;
        dstFormat.mFormatFlags = kLinearPCMFormatFlagIsPacked | kLinearPCMFormatFlagIsSignedInteger; // little-endian
¿Fue útil?

Solución

Es difícil de contestar correctamente sin ver un poco más de código. Pero, suponiendo clientFormat es un formato PCM intercalada:

B) ExtAudioFileWrite no realiza la conversión de comprimido para descomprimir, ExtAudioFileRead hace- dependiendo de qué formato cliente que haya establecido. Suponiendo un archivo fuente de MP3 y un formato "estándar" de 16 bits 44,1 kHz PCM cliente, las llamadas a ExtAudioFileRead va a convertir de MP3 a los bytes de datos PCM. Esto se hace bajo el capó mediante el uso de AudioFile y APIs AudioConverter.

A) Esto es un poco difícil de responder sin ver cómo se define srcBuffer (supongo que una serie de int16_t). Si está trabajando con datos PCM, lo que está haciendo se ve bien. También es posible usar newNumFrames * * clientFormat.mBytesPerFrame clientFormat.mChannelsPerFrame, pero asumiendo datos PCM de 16 bits, mBytesPerFrame == == mBytesPerPacket 2. Si estaba trabajando con datos no CBR que tendría que preocuparse por las descripciones de paquetes, pero eso no parece ser el caso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top