IOS Swift 读取 PCM 缓冲区

Posted

技术标签:

【中文标题】IOS Swift 读取 PCM 缓冲区【英文标题】:IOS Swift read PCM Buffer 【发布时间】:2016-08-26 09:07:17 【问题描述】:

我有一个 android 项目,它从麦克风缓冲区读取带有 PCM 数据的 short[] 数组以进行实时分析。我需要将此功能转换为 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 术语还不是我的 ;-)

【问题讨论】:

我在这里发布了关于使用 Swift 2 中的 RemoteIO 音频单元读取音频样本的简短要点:gist.github.com/hotpaw2/ba815fc23b5d642705f2b1dedfaf0107 【参考方案1】:

如果您不介意浮点采样和 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()

【讨论】:

非常感谢您的帮助。我已经看到 buffer.int16ChannelData 是由 API 提供的,但是当我调用它时,我得到 EXC_BAD_ACCESS 错误。我认为这是零。有没有办法配置 inputNode 来提供这些信息? 它为零,因为输入总线只提供浮点数据。如果您想要不同的格式,我认为您可以通过附加具有所需格式的AVAudioOutputNode 并在其上安装水龙头来做到这一点。 我需要连接AVAudioInputNodeAVAudioOutputNode 来转换传入的float 数据吗?我如何在AVAudioInputNode 上安装水龙头?抱歉,我不习惯 TapOnBus 方法和 Apple API。

以上是关于IOS Swift 读取 PCM 缓冲区的主要内容,如果未能解决你的问题,请参考以下文章

iOS录制时如何将PCM缓冲区实时转换为AAC数据?

如何正确使用 iOS AudioUnit 渲染回调

如何将 PCM 音频流转换为在线播放

使用 (Python) Gstreamer 解码音频(到 PCM 数据)

在 iOS 中实时将 pcm 样本编码为 mp3,可能吗?

如何仅使用 AVAudioPlayer 或 AVPlayer 播放 PCM 数据/缓冲区?