Domanda

sto facendo qualche progresso di prendere un (mp3) suono compressa e salvarlo come PCM. Inoltre, ho voluto dividere il file originale in blocchi che sono lunghe 2 secondi, all'interno dello stesso processo. Mi sembra di avere successo, ma io sono un po 'confuso sul perché.

Mentre leggevo blocchi di audio e scrivere i file fuori, controllo per vedere se sto per scrivere un pezzo che avrebbe fatto il mio file supera il mio limite di 2 secondo. Se è così, scrivo abbastanza per arrivare a 2 secondi, chiudere il file, e quindi aprire un nuovo file e scrivere il resto nel nuovo file, e quindi leggere più dati. Qualcosa di simile a questo:

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);

Ecco le mie domande (ho cercato di etichettare la relativa riga):

A: C'è un modo migliore per trovare l'offset nel mio tampone in modo da non erroneamente codice duro qualche valore in là? Per esempio, c'è un modo benedetta per ottenere i dati di correzione dal numero di telaio?

B: Se ExtAudioFileWrite sta facendo la conversione da compressa decompresso, quindi i dati che sto scrivendo non è ancora stato decompresso (giusto?), Quindi non dovrebbe ho dovuto preoccuparsi di giocare con i numeri di telaio e offset quando ho occupo di dati compressi? Dovrei essere invece la conversione del file prima, sia in un file PCM o nella memoria, e poi dividere quel PCM?

Grazie!

-mahboud

ps.

Il clientFormat è definito come segue:

        clientFormat = dstFormat;

e 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
È stato utile?

Soluzione

E 'difficile rispondere correttamente senza vedere un po' più di codice. Ma, supponendo clientFormat è un formato PCM Interleaved:

B) ExtAudioFileWrite non esegue la conversione da compressa decompresso, ExtAudioFileRead does- a seconda di quale formato cliente è stata impostata. Ipotizzando un file sorgente MP3 e una a 16 bit 44.1 KHz formato PCM cliente "standard", chiamate a ExtAudioFileRead convertirà dai byte MP3 ai dati PCM. Questo viene fatto sotto il cofano utilizzando AudioFile e le API AudioConverter.

A) Questo è un po 'difficile da rispondere senza vedere come srcBuffer è definito (presumo un array di int16_t). Se si lavora con i dati PCM, cosa si sta facendo sembra OK. Si potrebbe anche usare newNumFrames * * clientFormat.mBytesPerFrame clientFormat.mChannelsPerFrame, ma assumendo dati PCM a 16 bit, mBytesPerFrame == mBytesPerPacket == 2. Se si stava lavorando con dati non CBR si avrebbe bisogno di preoccuparsi con le descrizioni dei pacchetti, ma che non sembra essere il caso.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top