2015-11-02 137 views
4

我想用AVAudioEngine和用戶麥克風錄製一些音頻。我已經有一個工作示例,但只是無法弄清楚如何指定我想要的輸出格式...如何指定AVAudioEngine麥克風輸入的格式?

我的要求是,我需要AVAudioPCMBuffer,因爲我現在正在說它..

我需要添加一個獨立的節點來做一些轉碼嗎?我找不到很多有關這個問題的文檔/樣本...

而且我也是一個菜鳥,當談到音頻材料。我知道,我想NSData含PCM-16位16000一個最大采樣率(8000會更好)

這是我的工作樣本:

private var audioEngine = AVAudioEngine() 

func startRecording() { 

    let format = audioEngine.inputNode!.inputFormatForBus(bus) 

    audioEngine.inputNode!.installTapOnBus(bus, bufferSize: 1024, format: format) { (buffer: AVAudioPCMBuffer, time:AVAudioTime) -> Void in 

    let audioFormat = PCMBuffer.format 
    print("\(audioFormat)") 
    } 

    audioEngine.prepare() 
    do { 
    try audioEngine.start() 
    } catch { /* Imagine some super awesome error handling here */ } 
} 

如果我改變讓格式」說

let format = AVAudioFormat(commonFormat: AVAudioCommonFormat.PCMFormatInt16, sampleRate: 8000.0, channels: 1, interleaved: false) 

那麼如果會產生一個錯誤說,採樣率必須是一樣的hwInput ...

任何幫助非常感謝!

編輯:我剛剛發現AVAudioConverter但我需要與iOS8上以及兼容...

回答

0

你不能改變輸入節點的配置,嘗試創建與你想要的格式混頻器節點,將其附加到引擎,然後將其連接到輸入節點,然後將mainMixer連接到剛剛創建的節點。現在你可以在這個節點上安裝一個tap來獲取PCM數據。

請注意,由於一些奇怪的原因,您沒有太多的採樣率選擇!至少不在iOS 9.1上使用標準11025,22050或44100.任何其他採樣率都將失敗!

+0

8000也適用。 – nullforlife

+1

看起來好像要使8000赫茲工作,你必須在AVAudioSession.sharedInstance()上調用session.setPreferredSampleRate(8000) 。它實際上會將採樣率更改爲16000,但Mixer可以將採樣率降低到8kHz。 – philips77

3

您不能直接在輸入和輸出節點上更改音頻格式。在麥克風的情況下,格式將始終爲44KHz,1通道,32位。爲此,您需要在兩者之間插入混音器。然後當你連接inputNode> changeformatMixer> mainEngineMixer時,你可以指定你想要的格式的細節。

喜歡的東西:

var inputNode = audioEngine.inputNode 
var downMixer = AVAudioMixerNode() 
var mainMixer = audioEngine.mainMixerNode 

//I think you the engine's I/O nodes are already attached to itself by default, so we attach only the downMixer here: 
audioEngine.attachNode(downMixer) 

//You can tap the downMixer to intercept the audio and do something with it: 
downMixer.installTapOnBus(0, bufferSize: 2048, format: downMixer.outputFormatForBus(0), block: //originally 1024 
      { (buffer: AVAudioPCMBuffer!, time: AVAudioTime!) -> Void in 
       print(NSString(string: "downMixer Tap")) 
       do{ 
        print("Downmixer Tap Format: "+self.downMixer.outputFormatForBus(0).description)//buffer.audioBufferList.debugDescription) 

     }) 

//let's get the input audio format right as it is 
let format = inputNode.inputFormatForBus(0) 
//I initialize a 16KHz format I need: 
let format16KHzMono = AVAudioFormat.init(commonFormat: AVAudioCommonFormat.PCMFormatInt16, sampleRate: 11050.0, channels: 1, interleaved: true) 

//connect the nodes inside the engine: 
//INPUT NODE --format-> downMixer --16Kformat--> mainMixer 
//as you can see I m downsampling the default 44khz we get in the input to the 16Khz I want 
audioEngine.connect(inputNode, to: downMixer, format: format)//use default input format 
audioEngine.connect(downMixer, to: audioEngine.outputNode, format: format16KHzMono)//use new audio format 
//run the engine 
audioEngine.prepare() 
try! audioEngine.start() 

我會建議使用一個開放的框架,如EZAudio,相反,雖然。

+1

您的'mainMixerNode'未使用。您正在連接到示例中的'outputNode'。爲什麼? –

+0

這也不適用於任意格式。 –

+0

這是一個iOS的限制,你提供了一堆格式,但只有2或3實際工作。 @ErikAigner我 – Josh