ExtAudioFileWrite 谜题(kExtAudioFileError_InvalidOperationOrder 错误)

发布于 2024-09-30 22:54:10 字数 4063 浏览 1 评论 0原文

以下代码跳过 pcm caf 文件中音频的第一秒并删除最后 5 秒,写入临时文件(比输入短 6 秒)。每次循环都会在 ExtAudioFileWrite 上生成 kExtAudioFileError_InvalidOperationOrder。我做错了什么?

NSString *destURLString = [self.track.location absoluteString];
destURLString = [destURLString substringToIndex:([destURLString length] - 4)];     //remove .caf
destURLString = [NSString stringWithFormat:@"%@TMP.caf",destURLString]; //add tmp.caf
NSURL *destinationURL = [NSURL URLWithString:destURLString];

ExtAudioFileRef inputFile = NULL;
ExtAudioFileRef outputFile = NULL;

AudioStreamBasicDescription destFormat;

destFormat.mFormatID = kAudioFormatLinearPCM;
destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
destFormat.mSampleRate = 22000;
destFormat.mFormatFlags = 0;
destFormat.mBytesPerPacket = 2;
destFormat.mFramesPerPacket = 1;
destFormat.mBytesPerFrame = 2;
destFormat.mChannelsPerFrame = 1;
destFormat.mBitsPerChannel = 16;
destFormat.mReserved = 0;

ExtAudioFileCreateWithURL((CFURLRef)destinationURL, kAudioFileCAFType, &destFormat, NULL, kAudioFileFlags_EraseFile, &outputFile);

OSStatus fileStatus = ExtAudioFileOpenURL((CFURLRef)track.location, &inputFile);
//AudioFileID fileID;
//OSStatus fileStatus = AudioFileOpenURL((CFURLRef)track.location, kAudioFileReadPermission, 0, &fileID);
//ExtAudioFileWrapAudioFileID (fileID, true, &inputFile);
OSStatus fileStatus2 = ExtAudioFileOpenURL((CFURLRef)destinationURL, &outputFile);

//NSLog(@"open status: %i", fileStatus2);

//find out how many frames long this file is
SInt64 length = 0;
UInt32 dataSize2 = (UInt32)sizeof(length);
OSStatus propStatus2 = ExtAudioFileGetProperty(inputFile, kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);

AudioStreamBasicDescription clientFormat;
clientFormat.mFormatID = kAudioFormatLinearPCM;
clientFormat.mSampleRate = 22000;
clientFormat.mFormatFlags = kAudioFormatFlagsCanonical;
clientFormat.mBitsPerChannel = 16;
clientFormat.mChannelsPerFrame = 1;
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerPacket = 2;
clientFormat.mBytesPerFrame = 2;
destFormat.mReserved = 0;

UInt32 size = sizeof(clientFormat);

//set the intermediate format to canonical on the source file for conversion (?)
OSStatus setpropstatus = ExtAudioFileSetProperty(inputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
OSStatus setpropstatusout = ExtAudioFileSetProperty(outputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);

//UInt32 size = sizeof(destFormat);
//OSStatus setpropstatus = ExtAudioFileSetProperty(inputFile, kAudioFilePropertyDataFormat, size, &destFormat);
//NSLog(@"set prop status in %i", setpropstatus);
//NSLog(@"set prop status out %i", setpropstatusout);


OSStatus seekStatus = ExtAudioFileSeek(inputFile, (SInt64)22000); // skip one second of audio
NSLog(@"seekstatus %i", seekStatus);

SInt64 newLength = length - (5*22000); //shorten by 5 seconds worth of frames

NSLog(@"length: %i frames", length);

UInt8 *buffer = malloc(65536); //64K

UInt32 totalFramecount = 0;
while(true) {
    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mNumberChannels = 1;
    bufferList.mBuffers[0].mData = buffer; //pointer to buffer of audio data
    bufferList.mBuffers[0].mDataByteSize = 65536; //number of bytes in the buffer

    UInt32 frameCount = 65536 / 2; //2 bytes per frame

    // Read a chunk of input
    OSStatus status = ExtAudioFileRead(inputFile, &frameCount, &bufferList);
    totalFramecount += frameCount;

    NSLog(@"read status %i", status);
    //NSLog(@"loaded %f KB of data in %i frames", frameCount*2 / 1024.0, frameCount);
    NSLog(@"loaded %i frames and stopping at %i", totalFramecount, newLength);

    if (!frameCount || totalFramecount >= newLength) {
        //termination condition
        break;
    }

    OSStatus writeStatus = ExtAudioFileWrite(outputFile, frameCount, &bufferList);
    NSLog(@"ws: %i", writeStatus);
}

free(buffer);

ExtAudioFileDispose(inputFile);
ExtAudioFileDispose(outputFile);

The following code skips the first second of audio in a pcm caf file and removes the last 5 seconds, writing to a temp file (which will be 6 seconds shorter than the input). The loop, everytime, produces a kExtAudioFileError_InvalidOperationOrder on the ExtAudioFileWrite. What am I doing wrong?

NSString *destURLString = [self.track.location absoluteString];
destURLString = [destURLString substringToIndex:([destURLString length] - 4)];     //remove .caf
destURLString = [NSString stringWithFormat:@"%@TMP.caf",destURLString]; //add tmp.caf
NSURL *destinationURL = [NSURL URLWithString:destURLString];

ExtAudioFileRef inputFile = NULL;
ExtAudioFileRef outputFile = NULL;

AudioStreamBasicDescription destFormat;

destFormat.mFormatID = kAudioFormatLinearPCM;
destFormat.mFormatFlags = kAudioFormatFlagsCanonical;
destFormat.mSampleRate = 22000;
destFormat.mFormatFlags = 0;
destFormat.mBytesPerPacket = 2;
destFormat.mFramesPerPacket = 1;
destFormat.mBytesPerFrame = 2;
destFormat.mChannelsPerFrame = 1;
destFormat.mBitsPerChannel = 16;
destFormat.mReserved = 0;

ExtAudioFileCreateWithURL((CFURLRef)destinationURL, kAudioFileCAFType, &destFormat, NULL, kAudioFileFlags_EraseFile, &outputFile);

OSStatus fileStatus = ExtAudioFileOpenURL((CFURLRef)track.location, &inputFile);
//AudioFileID fileID;
//OSStatus fileStatus = AudioFileOpenURL((CFURLRef)track.location, kAudioFileReadPermission, 0, &fileID);
//ExtAudioFileWrapAudioFileID (fileID, true, &inputFile);
OSStatus fileStatus2 = ExtAudioFileOpenURL((CFURLRef)destinationURL, &outputFile);

//NSLog(@"open status: %i", fileStatus2);

//find out how many frames long this file is
SInt64 length = 0;
UInt32 dataSize2 = (UInt32)sizeof(length);
OSStatus propStatus2 = ExtAudioFileGetProperty(inputFile, kExtAudioFileProperty_FileLengthFrames, &dataSize2, &length);

AudioStreamBasicDescription clientFormat;
clientFormat.mFormatID = kAudioFormatLinearPCM;
clientFormat.mSampleRate = 22000;
clientFormat.mFormatFlags = kAudioFormatFlagsCanonical;
clientFormat.mBitsPerChannel = 16;
clientFormat.mChannelsPerFrame = 1;
clientFormat.mFramesPerPacket = 1;
clientFormat.mBytesPerPacket = 2;
clientFormat.mBytesPerFrame = 2;
destFormat.mReserved = 0;

UInt32 size = sizeof(clientFormat);

//set the intermediate format to canonical on the source file for conversion (?)
OSStatus setpropstatus = ExtAudioFileSetProperty(inputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);
OSStatus setpropstatusout = ExtAudioFileSetProperty(outputFile, kExtAudioFileProperty_ClientDataFormat, size, &clientFormat);

//UInt32 size = sizeof(destFormat);
//OSStatus setpropstatus = ExtAudioFileSetProperty(inputFile, kAudioFilePropertyDataFormat, size, &destFormat);
//NSLog(@"set prop status in %i", setpropstatus);
//NSLog(@"set prop status out %i", setpropstatusout);


OSStatus seekStatus = ExtAudioFileSeek(inputFile, (SInt64)22000); // skip one second of audio
NSLog(@"seekstatus %i", seekStatus);

SInt64 newLength = length - (5*22000); //shorten by 5 seconds worth of frames

NSLog(@"length: %i frames", length);

UInt8 *buffer = malloc(65536); //64K

UInt32 totalFramecount = 0;
while(true) {
    AudioBufferList bufferList;
    bufferList.mNumberBuffers = 1;
    bufferList.mBuffers[0].mNumberChannels = 1;
    bufferList.mBuffers[0].mData = buffer; //pointer to buffer of audio data
    bufferList.mBuffers[0].mDataByteSize = 65536; //number of bytes in the buffer

    UInt32 frameCount = 65536 / 2; //2 bytes per frame

    // Read a chunk of input
    OSStatus status = ExtAudioFileRead(inputFile, &frameCount, &bufferList);
    totalFramecount += frameCount;

    NSLog(@"read status %i", status);
    //NSLog(@"loaded %f KB of data in %i frames", frameCount*2 / 1024.0, frameCount);
    NSLog(@"loaded %i frames and stopping at %i", totalFramecount, newLength);

    if (!frameCount || totalFramecount >= newLength) {
        //termination condition
        break;
    }

    OSStatus writeStatus = ExtAudioFileWrite(outputFile, frameCount, &bufferList);
    NSLog(@"ws: %i", writeStatus);
}

free(buffer);

ExtAudioFileDispose(inputFile);
ExtAudioFileDispose(outputFile);

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

谁的新欢旧爱 2024-10-07 22:54:10

结果 ExtAudioFileCreateWithURL 返回一个已经打开的文件,因此不需要调用 ExtAudioFileOpenURL,即使它成功返回。我删除了它,一切正常。

Turns out ExtAudioFileCreateWithURL returns a file already open, so the call to ExtAudioFileOpenURL was not needed, even though it returns successfully. I removed that and all works correctly.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文