合并WAV文件时,NSURL返回无效摘要 [英] NSURL returns Invalid Summary when merging WAV files

查看:63
本文介绍了合并WAV文件时,NSURL返回无效摘要的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在Objective-C项目中合并2个.wav文件.这个想法是我希望它给出以下输出:file1 +(file2-header).在这种情况下,必须更改第一个文件的标头以反映新的大小.如果第一个文件为空(那么只有第一次),我希望该方法作为一个整体返回第二个文件,但要返回文件1的URL.现在我有:

I'm trying to merge 2 .wav files inside of an Objective-C project. The idea is that i want it to give this output: file1 + (file2 - header). In that case the first file's header has to be changed to reflect the new size. If the first file is empty (so only the first time) i want the method to return the second file as a whole, but in the file 1 url. Right now i have:

+(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的定义如下:

The finalSoundFileURL is defined like this:

   @interface class : UIViewController
        ....
        NSURL *soundFileURL;
        NSURL *finalSoundFileURL;
        ....
    }

我现在遇到的问题是tempURL将正确返回,但是当我执行finalSoundFileURL = [tempURL copy];时,finalSoundFileURL在调试时会显示无效摘要". tempURL将提供正确的URL.我也无法在网址中播放wav,所以显然有问题.

The problem i have right now is that the tempURL will return correctly, but when i do the finalSoundFileURL = [tempURL copy]; the finalSoundFileURL will say "Invalid Summary" while debugging. The tempURL will give the correct URL. I cannot play the wav in the url either, so something is clearly wrong.

任何人都知道发生了什么,因为我不明白发生了什么.感谢您的帮助!

Anyone has an idea what is going on, becouse i dont understand what is going on. Any help is appreciated!

编辑

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

I made a few screenshots of what the debugger shows. As the picture below shows the tempURL is just fine:

恰好在同一时间(将临时复制到最终副本之后)的finalSoundFileURL显示如下:

The finalSoundFileURL at that exact same moment (after the temp being copied to the final one) shows this:

对我来说,这是一个大谜团.这让我想知道,为什么它无效?它刚刚被复制(因此具有其自己的存储空间),并且没有在其上调用任何发行版!如果我做错了,请纠正我.

This is the big mystery for me. This leaves me to wonder, why is it invalid? It has just been Copied (so has its own memory space) and no release is called on it! Please correct me if i'm wrong on this.

推荐答案

您的replaceBytesInRange调用看起来有点奇怪:

Your replaceBytesInRange calls looks a bit weird:

[soundFileData replaceBytesInRange:NSMakeRange(4, 4) withBytes:[NSString stringWithFormat:@"%X", totalLength-8]];
[soundFileData replaceBytesInRange:NSMakeRange(42, 4) withBytes:[NSString stringWithFormat:@"%X", totalLength]];

这会将指向NSString实例的指针传递为新字节.

This will pass pointers to NSString instances to be used as new bytes.

我认为您想做这样的事情:

I think you want to do something like this:

[soundFileData replaceBytesInRange:NSMakeRange(4, 4)
                         withBytes:&(UInt32){NSSwapHostIntToLittle(totalLength-8)}];
[soundFileData replaceBytesInRange:NSMakeRange(42, 4)
                         withBytes:&(UInt32){NSSwapHostIntToLittle(totalLength)}];

现在,该长度将按照WAV格式指定的顺序以小尾数顺序显示正确的字节.在为iOS模拟器和ARM编译时,将字节交换为little endian可能是NOP,但明确表示可能会很好.

Now the length will the correct bytes in little endian order as the WAV format specifies. The byte swapping to little endian is probably a NOP when building for both iOS simulator and ARM but it's probably good to be explicit.

这篇关于合并WAV文件时,NSURL返回无效摘要的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆