1

我在获取压缩(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);

这是我的问题(我试图标记相关行):

A:有没有更好的方法来找到缓冲区的偏移量,这样我就不会错误地在其中硬编码一些值?例如,有没有一种幸运的方法可以从帧号中获取数据偏移量?

B:如果 ExtAudioFileWrite 正在做从压缩到解压缩的转换,那么我正在写入的数据还没有被解压缩(对吗?),所以我在处理时不必担心播放帧数和偏移量压缩数据?我是否应该先将文件转换为 PCM 文件或内存,然后拆分该 PCM?

谢谢!

-马布德

附言。

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
4

1 回答 1

2

如果不看更多代码,很难正确回答。但是,假设 clientFormat 是交错的 PCM 格式:

B) ExtAudioFileWrite 不执行从压缩到解压缩的转换,ExtAudioFileRead 执行 - 取决于您设置的客户端格式。假设 MP3 源文件和“标准”16 位 44.1 KHz PCM 客户端格式,对 ExtAudioFileRead 的调用将从 MP3 字节转换为 PCM 数据。这是通过使用 AudioFile 和 AudioConverter API 在后台完成的。

A)如果不看 srcBuffer 是如何定义的,这有点难以回答(我假设一个 int16_t 数组)。如果您正在使用 PCM 数据,那么您所做的看起来还不错。您也可以使用 newNumFrames * clientFormat.mBytesPerFrame * clientFormat.mChannelsPerFrame,但假设 16 位 PCM 数据,mBytesPerFrame == mBytesPerPacket == 2。如果您使用的是非 CBR 数据,您需要关注数据包描述,但是情况似乎并非如此。

于 2010-01-08T06:59:26.140 回答