Я делаю некоторые успехи в том, чтобы взять сжатый (mp3) звук и сохранить его как PCM. Кроме того, я хотел разбить исходный файл на куски по 2 секунды в рамках одного процесса. Я, кажется, добился успеха, но я немного смущен тем, почему.
Когда я читаю блоки аудио и записываю файлы, я проверяю, не собираюсь ли я написать фрагмент, из-за которого мой файл превысит 2-секундный лимит. Если это так, я пишу достаточно, чтобы добраться до 2 секунд, закрыть файл, а затем открыть новый файл и записать остаток в новый файл, а затем прочитать больше данных. Что-то вроде этого:
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);
Вот мои вопросы (я попытался пометить соответствующую строку):
О: Есть ли лучший способ найти смещение в моем буфере, чтобы ошибочно не закодировать туда какое-то значение? Например, есть ли благословенный способ получить смещение данных от номера кадра?
B: Если ExtAudioFileWrite выполняет преобразование из сжатого в распакованный, то данные, которые я записываю, еще не были распакованы (правильно?), так что не должен ли я беспокоиться об игре с номерами кадров и смещениями, когда я имею дело с сжатые данные? Должен ли я вместо этого сначала преобразовать файл либо в файл PCM, либо в память, а затем разделить этот файл PCM?
Спасибо!
-махбуд
ps.
clientFormat определяется следующим образом:
clientFormat = dstFormat;
и формат dst:
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