2016-09-14 1 views
0

Мне нужно преобразовать WAV-файл, записанный с двумя аудиоканалами, в .wav, который имеет только 1 канал, а также уменьшить глубину бит от 32 до 16. Я был пытаясь использовать AVAudioConverter.convertToBuffer Однако при конвертации вы бросаете ошибку: Error Domain=NSOSStatusErrorDomain Code=-50 "(null)"Ошибка AVAudioConverter.convertToBuffer код ошибки -50

В принципе, единственное, что действительно нужно изменить - это отключить звук до одного канала и глубину бит. Я получаю эти файлы из другого инструмента, поэтому я не могу просто изменить способ записи файлов.

Я не так учусь при работе с аудио, и я немного в тупике. Код, над которым я работаю, ниже - есть ли что-то, чего я не вижу?

let inAudioFileURL:NSURL = <url_to_wav_file> 

var inAudioFile:AVAudioFile? 
do 
{ 
    inAudioFile = try AVAudioFile(forReading: inAudioFileURL) 
} 
catch let error 
{ 
    print ("error: \(error)") 
} 

let inAudioFormat:AVAudioFormat = inAudioFile!.processingFormat 
let inFrameCount:UInt32 = UInt32(inAudioFile!.length) 

let inAudioBuffer:AVAudioPCMBuffer = AVAudioPCMBuffer(PCMFormat: inAudioFormat, frameCapacity: inFrameCount) 

do 
{ 
    try inAudioFile!.readIntoBuffer(inAudioBuffer) 
} 
catch let error 
{ 
    print ("readError: \(error)") 
} 

let startFormat:AVAudioFormat = AVAudioFormat.init(settings: inAudioFile!.processingFormat.settings) 
print ("startFormat: \(startFormat.settings)") 

var endFormatSettings = startFormat.settings 
endFormatSettings[AVLinearPCMBitDepthKey] = 16 
endFormatSettings[AVNumberOfChannelsKey] = 1 
endFormatSettings[AVEncoderAudioQualityKey] = AVAudioQuality.Medium.rawValue 
print ("endFormatSettings: \(endFormatSettings)") 


let endFormat:AVAudioFormat = AVAudioFormat.init(settings: endFormatSettings) 
let outBuffer = AVAudioPCMBuffer(PCMFormat: endFormat, frameCapacity: inFrameCount) 

let avConverter:AVAudioConverter = AVAudioConverter.init(fromFormat: startFormat, toFormat: endFormat) 

do 
{ 
    try avConverter.convertToBuffer(outBuffer, fromBuffer: inAudioBuffer) 
} 
catch let error 
{ 
    print ("avconverterError: \(error)") 
} 

Что касается выхода:

startFormat: 
    ["AVSampleRateKey": 16000, 
    "AVLinearPCMBitDepthKey": 32, 
    "AVLinearPCMIsFloatKey": 1, 
    "AVNumberOfChannelsKey": 2, 
    "AVFormatIDKey": 1819304813, 
    "AVLinearPCMIsNonInterleaved": 0, 
    "AVLinearPCMIsBigEndianKey": 0] 

endFormatSettings: 
["AVSampleRateKey": 16000, 
"AVLinearPCMBitDepthKey": 16, 
"AVLinearPCMIsFloatKey": 1, 
"AVNumberOfChannelsKey": 1, 
"AVFormatIDKey": 1819304813, 
"AVLinearPCMIsNonInterleaved": 0, 
"AVLinearPCMIsBigEndianKey": 0, 
"AVEncoderQualityKey": 64] 

avconverterError: Error Domain=NSOSStatusErrorDomain Code=-50 "(null)" 

ответ

2

Я не 100% уверен, почему это так, но я нашел решение, которое получило это работает для меня, так вот, как я понимаю, проблема. Я нашел это решение, пытаясь использовать альтернативный метод convert(to:error:withInputFrom:). Используя это дает мне другую ошибку:

`ERROR: AVAudioConverter.mm:526: FillComplexProc: required condition is false: [impl->_inputBufferReceived.format isEqual: impl->_inputFormat]` 

Проблема была вызвана в строке, где я настроить AVAudioConverter:

let avConverter:AVAudioConverter = AVAudioConverter.init(fromFormat: startFormat, toFormat: endFormat) 

Оказывается, что аудио конвертер хочет использовать тот же AVAudioFormat, что буфер ввода используется вместо использования копии на основе настроек оригинала. Однажды я поменял startFormat на inAudioFormat, convert(to:error:withInputFrom:) Ошибка была упущена, и все работало так, как ожидалось. Затем я смог вернуться к использованию более простого метода convert(to:fromBuffer:), и исходная ошибка, с которой я имел дело, тоже ушла.

Чтобы резюмировать, то настройки преобразователя Теперь строка выглядит так:

let avConverter:AVAudioConverter = AVAudioConverter.init(fromFormat: inAudioFormat, toFormat: endFormat) 

Что касается отсутствия документации о том, как использовать AVAudioConverter, я понятия не имею, почему ссылка API имеет бесценок. Вместо этого, в Xcode, CMD-щелкните по AVAudioConverter в вашем коде, чтобы перейти к его заголовочному файлу. Там много комментариев и информации. Не полный образец кода или что-то еще, но это хоть что-то.