标签: avaudioengine

AVAudioEngine:有什么方法可以控制缓冲区大小(延迟)?

我编写了一个 V3 AudioUnit 并使用AVAudioUnit. 我的渲染回调使用 512 帧进行调用,这对于我的应用程序(合成器)来说延迟太高。

有没有办法AVAudioEngine设置处理缓冲区大小?或者我需要直接使用CoreAudio?

注意:这是在 OS X 10.11 上。

macos core-audio avaudioengine

5
推荐指数
1
解决办法
1961
查看次数

使用后删除 AVAudioPlayerNode 会导致崩溃

我用来AVAudioEngine播放声音文件并将输出记录到文件中。我有很多音效文件,每个音效文件都是通过点击按钮来播放的。为了播放该文件,我创建了一个AVAudioPlayerNode并将其连接到引擎。文件播放后,我尝试断开/分离completionHandler 闭包中的节点,以释放内存。如果我不删除节点,我将继续向引擎添加新节点和新连接。

但是,下次我尝试播放文件时,应用程序就会冻结。这是我的代码:

let url = NSBundle.mainBundle().URLForResource(name, withExtension: "wav")!
let audioPlayerFile = try AVAudioFile(forReading: url)
let playerNode = AVAudioPlayerNode()
self.engine.attachNode(playerNode)
self.engine.connect(playerNode, to: self.engine.mainMixerNode, format: audioPlayerFile.processingFormat)
playerNode.scheduleFile(audioPlayerFile, atTime: nil, completionHandler: { () -> Void in
    self.engine.disconnectNodeOutput(playerNode)
    self.engine.detachNode(playerNode)
})
playerNode.play()
Run Code Online (Sandbox Code Playgroud)

实现这样的功能(即在录制时播放多个文件(可能彼此重叠))的最佳方法是什么?

ios avaudioengine

5
推荐指数
1
解决办法
1113
查看次数

将单声道 AVAudioPCMBuffer 写入立体声 AVAudioFile

我正在使用 AVAudioEngine 录制音频,并将其保存为声音文件。

用户可以选择导入音频文件,然后如果愿意,可以在此文件的末尾继续录制。我通过将导入的文件读入 AVAudioPCMBuffer 来获取音频数据,然后将其写入要录制的文件中。如果导入的文件是立体声的(因为我正在写入的文件也是立体声的),这非常有用。但是,如果导入的文件是单声道的,当我尝试将 AVAudioPCMBuffer 写入文件时,代码会崩溃,仅仅是因为通道数不匹配。

是否可以将处理格式设置为立体声的单声道 AVAudioPCMBuffer 读入 av AVAudioFile 中?我可以将缓冲区转换为立体声吗?

以下是我如何从导入的文件中获取音频缓冲区的示例:

let existingAudioFile = try AVAudioFile(forReading: existingFileUrl)
var audioFrameCount = AVAudioFrameCount(existingAudioFile.length)
let audioBuffer = AVAudioPCMBuffer(PCMFormat: existingAudioFile.processingFormat, frameCapacity: audioFrameCount) //Mono
try existingAudioFile.readIntoBuffer(audioBuffer)
Run Code Online (Sandbox Code Playgroud)

这就是我使用 AVAudioEngine 创建 AVAudioFile 的地方:

self.audioFile = try AVAudioFile(forWriting: self.audioRecordURL, settings: self.engine.mainMixerNode.outputFormatForBus(0).settings) //This is in stereo
Run Code Online (Sandbox Code Playgroud)

最后,这就是我将音频缓冲区写入文件的方式:

try self.audioFile.writeFromBuffer(audioBuffer)
Run Code Online (Sandbox Code Playgroud)

如果我将音频转换为立体声,一切正常。

ios avaudioengine avaudiopcmbuffer avaudiofile

5
推荐指数
0
解决办法
1744
查看次数

访问 AVAudioPCMBuffer 的 Float 样本进行处理

我正在尝试对我正在使用 AVAudioEngine 图表播放的 mp3 文件的原始 PCM 样本进行一些计算。我每 44100 个样本就有一个闭包,提供AVAudioPCMBuffer. 它有一个channelDatatype属性UnsafePointer<UnsafeMutablePointer<Float>>?。我没有在 Swift 3 中使用过指针,所以我不清楚如何访问这些 Float 值。

我有以下代码,但有很多问题:

audioPlayerNode.installTap(onBus: 0, 
                           bufferSize: 1024, 
                           format: audioPlayerNode.outputFormat(forBus: 0)) { (pcmBuffer, time) in

let numChans = Int(pcmBuffer.format.channelCount)
let frameLength = pcmBuffer.frameLength
     
if let chans = pcmBuffer.floatChannelData?.pointee {
    for a in 0..<numChans {   
        let samples = chans[a]// samples is type Float.  should be pointer to Floats.
        for b in 0..<flength {
            print("sample: \(b)") // should be samples[b] but that gives error …
Run Code Online (Sandbox Code Playgroud)

audio avfoundation swift avaudioengine avaudiopcmbuffer

5
推荐指数
1
解决办法
2724
查看次数

如何搜索“com.apple.coreaudio.avfaudio”的错误代码?

我在哪里可以得到com.apple.coreaudio.avfaudio错误代码的信息,例如:

由于未捕获的异常“com.apple.coreaudio.avfaudio”而终止应用程序,原因:“错误 -50”

将 PCM 缓冲区写入AVAudioFile. 缓冲区来自AVAudioEngine的输出节点。

在此处输入图片说明

错误:

*终止应用程序由于未捕获的异常'com.apple.coreaudio.avfaudio',理由是: '错误-50' *第一掷调用堆栈:(0x18eb46fe0 0x18d5a8538 0x18eb46eb4 0x1a8d051cc 0x1a8d731dc 0x1000d45e0 0x1000d4820 0x1a8d14654 0x1a8d146c0 0x1a8d8c26c 0x1a8d8c1fc 0x100ae5a10 0x100af1a84 0x100b001f8 0x100ae7a60 0x100af3128 0x100ae9634 0x100af5630 0x100af6f48 0x18dc0968c 0x18dc0959c 0x18dc06cb4) libc++abi.dylib:以未捕获的 NSException 类型异常终止

你可以帮帮我吗?

avaudioengine avaudiofile

5
推荐指数
1
解决办法
3108
查看次数

使用特定采样率捕获音频样本,如 iOS Swift 中的 Android

我是在 IOS 中使用声音和 AVAudioEngine 的初学者,我正在开发一个应用程序,将音频样本捕获为缓冲区并对其进行分析。此外,采样率必须为 8000 kHz,也必须编码为 PCM16Bit,但 AVAudioEngine 中的默认 inputNode 为 44.1 kHz。

在 Android 中,过程非常简单:

AudioRecord audioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC,
                8000, AudioFormat.CHANNEL_IN_MONO,
                AudioFormat.ENCODING_PCM_16BIT, bufferSize);
Run Code Online (Sandbox Code Playgroud)

然后启动缓冲区的读取功能。我搜索了很多,但没有找到任何类似的例子。相反,我遇到的所有示例都以默认节点的采样率(44.1 kHz)捕获样本,例如:

    let input = audioEngine.inputNode
    let inputFormat = input.inputFormat(forBus: 0)
    input.installTap(onBus: 0, bufferSize: 640, format: inputFormat) { (buffer, time) -> Void in
                print(inputFormat)
                if let channel1Buffer = buffer.floatChannelData?[0] {
                    for i in 0...Int(buffer.frameLength-1) {
                        print(channel1Buffer[i])
                    }
                }
            }
try! audioEngine.start()
Run Code Online (Sandbox Code Playgroud)

所以我想使用 AVAudioEngine 以 8000 kHz 采样率和 PCM16Bit 编码捕获音频样本。

*编辑: 我找到了将输入转换为 8 kHz 的解决方案: …

pcm avfoundation ios swift avaudioengine

5
推荐指数
1
解决办法
929
查看次数

使用 AVAudioEngine 离线渲染音频文件

我想录制音频文件并通过应用一些效果来保存它。录音没问题,播放带有效果的音频也没问题。问题是当我尝试离线保存此类音频时,它会生成空的音频文件。这是我的代码:

let effect = AVAudioUnitTimePitch()
effect.pitch = -300
self.addSomeEffect(effect)

func addSomeEffect(_ effect: AVAudioUnit) {
    try? AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord, with: .defaultToSpeaker)

    let format = self.audioFile.processingFormat
    self.audioEngine.stop()
    self.audioEngine.reset()

    self.audioEngine = AVAudioEngine()
    let audioPlayerNode = AVAudioPlayerNode()


    self.audioEngine.attach(audioPlayerNode)
    self.audioEngine.attach(effect)

    self.audioEngine.connect(audioPlayerNode, to: self.audioEngine.mainMixerNode, format: format)
    self.audioEngine.connect(effect, to: self.audioEngine.mainMixerNode, format: format)

    audioPlayerNode.scheduleFile(self.audioFile, at: nil)
    do {
        let maxNumberOfFrames: AVAudioFrameCount = 8096
        try self.audioEngine.enableManualRenderingMode(.offline,
                                                       format: format,
                                                       maximumFrameCount: maxNumberOfFrames)
    } catch {
        fatalError()
    }


    do {
        try audioEngine.start()
        audioPlayerNode.play()
    } catch {

    }

    let outputFile: AVAudioFile
    do {
        let url …
Run Code Online (Sandbox Code Playgroud)

avfoundation avaudioplayer ios swift avaudioengine

5
推荐指数
1
解决办法
966
查看次数

AVAudioEngine 在 Swift 中的采样率崩溃

我已经开始遇到以前没有发生的崩溃,因为记录的初始化有错误:

[avae] AVAEInternal.h:70:_AVAE_Check: required condition is false: [AVAudioIONodeImpl.mm:911:SetOutputFormat: (format.sampleRate == hwFormat.sampleRate)]
Run Code Online (Sandbox Code Playgroud)

这似乎是一个棘手的错误,有些人也使用AudioKit

在这种情况下,它似乎与使用 48k 而不是 44.1k 的采样率有关。但是,就我而言,使用音频引擎,我根本没有设置任何采样率。

我的代码主要是用于记录的样板。崩溃发生在以下行:

inputNode.installTap(onBus: 0, bufferSize: 4096, format: recordingFormat) { (buffer, when) in
print("got here")//never gets here
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议在使用音频引擎进行录音时如何解决这个问题?

感谢您的任何建议。

编辑

这就是我创建记录格式的方式:

let recordingFormat = inputNode.outputFormat(forBus: 0)
Run Code Online (Sandbox Code Playgroud)

这就是调试器中的 RecordingFormat 的样子..它似乎设置为 44.1k:

po recordingFormat
<AVAudioFormat 0x282b1e580:  1 ch,  44100 Hz, Float32>
Run Code Online (Sandbox Code Playgroud)

inputNode 看起来像这样:

po inputNode
<AVAudioInputNode: 0x280a0eb70>

(lldb) p inputNode
(AVAudioInputNode) $R4 = 0x0000000280a0eb70 {
  AVFoundation.AVAudioIONode = {
    baseAVAudioNode@0 = <extracting data from …
Run Code Online (Sandbox Code Playgroud)

ios swift avaudioengine sfspeechrecognizer

5
推荐指数
0
解决办法
739
查看次数

从麦克风中获取音频,对其进行下采样,对其进行编码(使用 AAC)并通过套接字传输

在过去的几周里,我一直试图从许多不同的例子中拼凑出一个解决方案,这将使我能够:

  1. 从麦克风捕获音频
  2. 将其下采样到 8khz
  3. 使用 AAC 对每个缓冲区进行编码
  4. 通过套接字发送结果

我见过的几乎所有示例都涉及将音频编码到文件中,我这样做是为了测试,但不是我需要的。我需要取一个数据包,编码并传输它

MicrophoneService

这基本上设置了 aAVAudioEngine并将a附加AVAudioMixerNode到它,这对音频进行了下采样。

然后将结果放入阻塞队列 ( AudioEncoderQueue) 以便编码服务可以对缓冲区进行编码

import Foundation
import AVFoundation

// Base on /sf/ask/2771681111/
// https://github.com/onmyway133/notes/issues/367

class MicrophoneService {

    let audioEngine = AVAudioEngine()

    init() {
        do {
            try AVAudioSession.sharedInstance().setPreferredSampleRate(16000)
        } catch let error {
            print(error)
        }

        let engineInputNode = audioEngine.inputNode
        let bus = 0
        let engineInputNodeFormat = engineInputNode.outputFormat(forBus: bus)

        //engineInputNode.installTap(onBus: bus, bufferSize: 1024, format: engineInputNodeFormat) { (buffer, time) in
        //  AudioEncoderQueue.shared.put(buffer)
        //}

        let mixer = …
Run Code Online (Sandbox Code Playgroud)

core-audio avfoundation ios swift avaudioengine

5
推荐指数
0
解决办法
683
查看次数

从断开连接的蓝牙设备捕获输入时,AVAudioSession 服务会重置

TL;DR -AVAudioSessionAVAudioSessionMediaServicesWereLostNotification在指定蓝牙端口时触发,AVAudioSession.setPreferredInput并且该设备在使用AVCaptureSession或主动读取输入时断开连接AVAudioEngine。示例项目在这里

https://openradar.appspot.com/FB8921592

问题

通过我认为的“快乐路径”,或者至少应该得到 Apple 支持的路径,我可以始终如一AVAudioSession地触发它AVAudioSessionMediaServicesWereLostNotificationAVAudioSessionMediaServicesWereResetNotification通知。

在这两个通知之间,您的应用无法执行任何音频或视频 I/O 或处理(编码或解码)。这是一个总的媒体服务关闭 1 到 2 秒。

触发

这仅在使用时发生AVAudioSession.setPreferredInput,其中您设置的端口是蓝牙设备。从该端口主动录制时,您关闭蓝牙设备。

发生这种情况时,在服务丢失之前不会触发来自AVAudioSessionAVAudioEngine或 的其他通知AVCaptureSession,因此无法抢先处理这种情况。用户可以随时关闭耳机,导致服务全面失败。

一些代码

首先我设置了音频会话

try! AVAudioSession.sharedInstance().setCategory(.record, mode: .videoRecording, options: .allowBluetooth)
try! AVAudioSession.sharedInstance().setActive(true)
Run Code Online (Sandbox Code Playgroud)

然后指定正确的端口

let bluetoothPort = AVAudioSession.sharedInstance().availableInputs?
    .first(where: { $0.portType == .bluetoothHFP })
guard let validPort = newPort else {
    print("Couldn't find a valid bluetooth port")
    return
} …
Run Code Online (Sandbox Code Playgroud)

core-audio ios avcapturesession avaudiosession avaudioengine

5
推荐指数
0
解决办法
400
查看次数