ExtAudioFileConvert问题

时间:2010-01-08 06:27:39

标签: iphone core-audio extaudiofile

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

谢谢!

-mahboud

PS。

clientFormat的定义如下:

        clientFormat = dstFormat;

和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

1 个答案:

答案 0 :(得分: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数据,则需要关注数据包描述,但是似乎并非如此。