IOS Swift读取PCM缓冲区

3

我有一个Android项目,需要从麦克风缓冲区读取short[]数组的PCM数据进行实时分析。我需要将这个功能转换为iOS Swift。在Android中,这非常简单,代码如下:

import android.media.AudioFormat;
import android.media.AudioRecord;
...
AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, someSampleRate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, AudioRecord.getMinBufferSize(...));
recorder.startRecording();

稍后我将使用缓冲区读取
recorder.read(data, offset, length); //data is short[]

这就是我正在寻找的。

文档:https://developer.android.com/reference/android/media/AudioRecord.html

我对Swift和iOS非常陌生。我已经阅读了很多关于AudioToolkit、...Core等的文档。但我发现它们都是C++/Obj-C和Bridging Swift Header的解决方案。这对我来说过于高级和过时了。

目前,我可以使用AVFoundation将PCM数据读取到CAF文件中。

settings = [
        AVLinearPCMBitDepthKey: 16 as NSNumber,
        AVFormatIDKey: Int(kAudioFormatLinearPCM),
        AVLinearPCMIsBigEndianKey: 0 as NSNumber,
        AVLinearPCMIsFloatKey: 0 as NSNumber,
        AVSampleRateKey: 12000.0,
        AVNumberOfChannelsKey: 1 as NSNumber,
        ]
...
recorder = try AVAudioRecorder(URL: someURL, settings: settings)
recorder.delegate = self
recorder.record()

但这不是我正在寻找的(或者说是吗?)。有没有一种优雅的方法来实现上面描述的android read功能?我需要从麦克风缓冲区获取一个示例数组。或者我需要在记录的CAF文件上进行读取吗?

非常感谢!请用简单的解释或代码示例帮助我。iOS术语还不是我的专业领域;-)


1
我在这里发布了一个简短的要点,介绍如何使用Swift 2中的RemoteIO音频单元读取音频样本:https://gist.github.com/hotpaw2/ba815fc23b5d642705f2b1dedfaf0107 - hotpaw2
1个回答

4

如果您不介意使用浮点采样和48kHz,您可以通过以下方式快速从麦克风获取音频数据:

let engine = AVAudioEngine()    // instance variable

func setup() {        
    let input = engine.inputNode!
    let bus = 0

    input.installTapOnBus(bus, bufferSize: 512, format: input.inputFormatForBus(bus)) { (buffer, time) -> Void in
        let samples = buffer.floatChannelData[0]
        // audio callback, samples in samples[0]...samples[buffer.frameLength-1]
    }

    try! engine.start()
}

非常感谢您的帮助。我看到API提供了buffer.int16ChannelData,但是当我调用它时,我会收到EXC_BAD_ACCESS错误。我认为这是nil。有没有一种方法可以配置inputNode以提供这些信息? - Robin
1
它是nil,因为该输入总线仅提供浮点数据。如果您想要不同的格式,我认为您可以通过附加具有所需格式的AVAudioOutputNode并在其上安装挂接来实现。 - Rhythmic Fistman
我需要将 AVAudioInputNodeAVAudioOutputNode 连接起来才能转换传入的 float 数据吗?我该如何在 AVAudioInputNode 上安装 Tap?抱歉,我不熟悉 TapOnBus 方法和 Apple API。 - Robin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接