AVAudioEngine
とユーザーのマイクを使用してオーディオを録音したいと思います。私はすでに実用的なサンプルを持っていますが、私が望む出力のフォーマットを指定する方法を理解することができません...
私の要件は、私が話しているようにAVAudioPCMBuffer
が必要であるということです。
トランスコーディングを行う別のノードを追加する必要がありますか?その問題に関するドキュメント/サンプルがあまり見つかりません...
そして、私はオーディオスタッフに関しても初心者です。最大サンプルレートが16000のPCM-16ビットを含むNSData
が必要なことはわかっています(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と同じである必要があるというエラーが生成されます。
どんな助けでも大歓迎です!!!
EDIT:AVAudioConverter
を見つけましたが、iOS8とも互換性がある必要があります...
入力ノードと出力ノードでオーディオ形式を直接変更することはできません。マイクの場合、フォーマットは常に44KHz、1チャンネル、32ビットになります。そのためには、間にミキサーを挿入する必要があります。次に、inputNode> changeformatMixer> mainEngineMixerに接続するときに、必要な形式の詳細を指定できます。
何かのようなもの:
var inputNode = audioEngine.inputNode
var downMixer = AVAudioMixerNode()
//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などのオープンフレームワークを使用することをお勧めします。
サンプリングレートを変更するために働いたことがわかったのは、
AVAudioSettings.sharedInstance().setPreferredSampleRate(...)
Engine.inputNodeをタップして、入力ノードの出力形式を使用できます。
engine.inputNode.installTap(onBus: 0, bufferSize: 2048,
format: engine.inputNode.outputFormat(forBus: 0))
残念ながら、8000、12000、16000、22050、44100はすべて機能しているように見えますが、必要なサンプルレートが得られる保証はありません。
以下は機能しませんでした:
これはiOS12.3.1でした。
入力ノードの構成を変更することはできません。必要な形式でミキサーノードを作成し、エンジンに接続してから、入力ノードに接続してから、mainMixerを作成したノードに接続してください。これで、このノードにタップをインストールしてPCMデータを取得できます。
いくつかの奇妙な理由で、サンプルレートの選択肢があまりないことに注意してください!少なくともiOS9.1では、標準の11025、22050、または44100を使用してください。他のサンプルレートは失敗します。