我正在尝试合并Objective-C项目中的两个.wav文件。我的想法是,我希望它给出这个输出:file1 +(file2 - header)。在这种情况下,必须更改第一个文件的标题以反映新的大小。如果第一个文件是空的(所以只是第一次)我希望该方法作为一个整体返回第二个文件,但在文件1 url中。现在我有:
+(NSURL *)mergeFile1:(NSURL *)file1 withFile2:(NSURL *)file2 {
if(file1 == nil) {
return [file2 copy];
}
NSData * wav1Data = [NSData dataWithContentsOfFile:[file1 absoluteString]];
NSData * wav2Data = [NSData dataWithContentsOfFile:[file2 absoluteString]];
int wav1DataSize = [wav1Data length] - 46;
int wav2DataSize = [wav2Data length] - 46;
[NSMutableData dataWithData:[wav1Data subdataWithRange:NSMakeRange(46, wav1DataSize)]];
if (wav1DataSize <= 0 || wav2DataSize <= 0) {
return nil;
}
NSMutableData * soundFileData = [NSMutableData dataWithData:[wav1Data subdataWithRange:NSMakeRange(0, 46)]];
[soundFileData appendData:[wav1Data subdataWithRange:NSMakeRange(46, wav1DataSize)]];
[soundFileData appendData:[wav2Data subdataWithRange:NSMakeRange(46, wav2DataSize)]];
unsigned int totalLength = [soundFileData length];
NSLog(@"%d", totalLength);
[soundFileData replaceBytesInRange:NSMakeRange(4, 4) withBytes:[NSString stringWithFormat:@"%X", totalLength-8]];
[soundFileData replaceBytesInRange:NSMakeRange(42, 4) withBytes:[NSString stringWithFormat:@"%X", totalLength]];
[soundFileData writeToURL:file1 atomically:YES];
return [file1 copy];
}
我称之为:
if(soundFileURL != nil) {
NSURL *tempURL = [WavUtils mergeFile1:finalSoundFileURL withFile2:soundFileURL];
if(tempURL != nil) {
NSLog(@"Wav files have been merged.");
finalSoundFileURL = [tempURL copy];
[soundFileURL release];
soundFileURL = nil;
} else {
NSLog(@"Wav files could not be merged.");
}
}
finalSoundFileURL定义如下:
@interface class : UIViewController
....
NSURL *soundFileURL;
NSURL *finalSoundFileURL;
....
}
我现在遇到的问题是tempURL
会正确返回,但是当我执行finalSoundFileURL = [tempURL copy];
时,finalSoundFileURL
会在调试时说“无效摘要”。 tempURL将提供正确的URL。我也不能在网址中播放wav,所以有些事情显然是错误的。
任何人都知道发生了什么,因为我不明白发生了什么。任何帮助表示赞赏!
修改
我制作了一些调试器显示的屏幕截图。如下图所示,tempURL很好:
finalSoundFileURL在同一时刻(在将temp复制到最后一个之后)显示:
这对我来说是个大谜。这让我想知道,为什么它无效?它刚被复制(所以有自己的内存空间)并且没有调用它!如果我错了,请纠正我。
答案 0 :(得分:1)
您的replaceBytesInRange
电话看起来有点奇怪:
[soundFileData replaceBytesInRange:NSMakeRange(4, 4) withBytes:[NSString stringWithFormat:@"%X", totalLength-8]];
[soundFileData replaceBytesInRange:NSMakeRange(42, 4) withBytes:[NSString stringWithFormat:@"%X", totalLength]];
这会将指向NSString
个实例的指针传递给新字节。
我想你想做这样的事情:
[soundFileData replaceBytesInRange:NSMakeRange(4, 4)
withBytes:&(UInt32){NSSwapHostIntToLittle(totalLength-8)}];
[soundFileData replaceBytesInRange:NSMakeRange(42, 4)
withBytes:&(UInt32){NSSwapHostIntToLittle(totalLength)}];
现在,长度将以WAV格式指定的小端顺序正确的字节。在为iOS模拟器和ARM构建时,交换到小端的字节可能是一个NOP,但显然可能很好。