【问题标题】:NSURL returns Invalid Summary when merging WAV files合并 WAV 文件时 NSURL 返回无效摘要
【发布时间】:2011-12-16 14:11:13
【问题描述】:

我正在尝试在一个 Objective-C 项目中合并 2 个 .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。我也不能在 url 中播放 wav,所以显然有问题。

任何人都知道发生了什么,因为我不明白发生了什么。任何帮助表示赞赏!

编辑

我制作了一些调试器显示的屏幕截图。如下图所示,tempURL 很好:

在同一时刻(在将临时文件复制到最后一个文件之后)的 finalSoundFileURL 显示如下:

这对我来说是个大谜。这让我想知道,为什么它无效?它刚刚被复制(所以有自己的内存空间)并且没有调用它!如果我在这方面错了,请纠正我。

【问题讨论】:

  • 我每天都在检查这个问题,有什么想知道的可以问我^_^
  • 你在哪里声明/分配 finalSoundFileURL?您是否可能过度释放它?
  • 当变量超出相对于您暂停位置的范围时,调试器中会显示“无效摘要”。 finalSoundFilaURL NSURL 变量在哪里定义?在 `[soundFileURL release] 分配断点后设置断点,然后查看它在该点上的内容。
  • @Martin Gordon:当你过度释放它时,我认为会发生 SIGABRT。这不会发生。
  • @Jessedc:我确实放了一个断点,这就是我得到“无效摘要”的地方。该变量在该类的 .h 文件中定义。

标签: objective-c wav nsurl


【解决方案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,但最好是明确的。

【讨论】:

  • 感谢您的提示,我更改了这个(不幸的是它没有解决问题:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-26
  • 1970-01-01
  • 2012-12-08
  • 2016-05-08
  • 1970-01-01
  • 2015-11-14
相关资源
最近更新 更多