NSURL возвращает неверную сводку при объединении файлов WAV

Я пытаюсь объединить 2 файла .wav внутри проекта Objective-C. Идея в том, что я хочу, чтобы он выдавал этот вывод: файл1 + (файл2 - заголовок). В этом случае заголовок первого файла должен быть изменен, чтобы отразить новый размер. Если первый файл пуст (так что только в первый раз), я хочу, чтобы метод возвращал второй файл целиком, но в файле 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 в URL-адресе, так что что-то явно не так.

У кого-нибудь есть идея, что происходит, потому что я не понимаю, что происходит. Любая помощь приветствуется!

ИЗМЕНИТЬ

Я сделал несколько скриншотов того, что показывает отладчик. Как показано на рисунке ниже, tempURL в порядке: img1

FinalSoundFileURL в тот же момент (после копирования временного файла в последний) показывает следующее: img2

Это большая загадка для меня. Это заставляет меня задаться вопросом, почему это недействительно? Он только что был скопирован (поэтому имеет собственное пространство памяти), и для него не требуется освобождение! Пожалуйста, поправьте меня, если я ошибаюсь в этом.


person Manuel    schedule 16.12.2011    source источник
comment
Я проверяю этот вопрос каждый день, поэтому спрашивайте меня обо всем, что вам нужно знать ^_^   -  person Manuel    schedule 20.12.2011
comment
Где вы объявляете/назначаете finalSoundFileURL? Возможно ли, что вы чрезмерно выпускаете его?   -  person Martin Gordon    schedule 20.12.2011
comment
Недопустимая сводка отображается в отладчике, когда переменная выходит за пределы области действия относительно того места, где вы остановились. Где определена переменная finalSoundFilaURL NSURL? Установите точку останова после того, как вы назначите ее в `[soundFileURL release] и посмотрите, что она говорит в этот момент.   -  person Jessedc    schedule 20.12.2011
comment
@Martin Gordon: Думаю, когда вы перевыпустите его, произойдет SIGABRT. Этого не происходит.   -  person Manuel    schedule 20.12.2011
comment
@Jessedc: я поставил точку останова, вот где я получил неверную сводку. Переменная определена в файле .h этого класса.   -  person Manuel    schedule 20.12.2011
comment
@dragon112, значит, finalSoundFileURL определяется как @property? пожалуйста, покажите мне, как это синтезируется.   -  person Jessedc    schedule 20.12.2011
comment
@Jessedc: Нет, это только локально, но оно также используется только локально.   -  person Manuel    schedule 20.12.2011
comment
а это определено в шапке?   -  person Jessedc    schedule 20.12.2011
comment
Да, он определен в заголовке, но используется только в классе, в котором он определен. Думаю, локальное имя не подходит для него, но только в этом конкретном классе.   -  person Manuel    schedule 20.12.2011
comment
Определите finalSoundFileURL в строке выше if(soundFileURL != nil) {, а не там, где вы находитесь в данный момент, и посмотрите, показывает ли отладчик по-прежнему Invalid Summary.   -  person Jessedc    schedule 20.12.2011
comment
Нет, если я определю это в строке выше, и это не даст неверную сводку? Любая идея, почему это?   -  person Manuel    schedule 20.12.2011
comment
@dragon112 Dragon112 Как следует из моего удивления, это не похоже на то, что вы правильно объявляете и используете переменную, «определяя ее в заголовке». Добавьте в вопрос код, который вы используете для определения finalSoundFileURL.   -  person Jessedc    schedule 20.12.2011
comment
Я добавил полезную часть интерфейса к вопросу.   -  person Manuel    schedule 21.12.2011
comment
И tempURL, и finalSoundFilaURL имеют один и тот же адрес 0x53572f0. Можете ли вы попробовать добавить NSLog(@"%@", tempURL) и NSLog(@"%@", finalSoundFilaURL), чтобы дважды проверить, действителен ли URL-адрес?   -  person Laurent Etiemble    schedule 22.12.2011
comment
В логе работает нормально (оба дают правильный путь). однако при воспроизведении файла будет воспроизводиться только та часть, которая добавлена ​​последней.   -  person Manuel    schedule 23.12.2011


Ответы (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. Замена байтов на обратный порядок байтов, вероятно, является NOP при сборке как для симулятора iOS, так и для ARM, но, вероятно, лучше быть явным.

person Mattias Wadman    schedule 20.12.2011
comment
Спасибо за подсказку, я изменил это (к сожалению, это не решило проблему на :‹). - person Manuel; 21.12.2011