我编写了一个 V3 AudioUnit 并使用AVAudioUnit. 我的渲染回调使用 512 帧进行调用,这对于我的应用程序(合成器)来说延迟太高。
有没有办法AVAudioEngine设置处理缓冲区大小?或者我需要直接使用CoreAudio?
注意:这是在 OS X 10.11 上。
我用来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)
实现这样的功能(即在录制时播放多个文件(可能彼此重叠))的最佳方法是什么?
我正在使用 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)
如果我将音频转换为立体声,一切正常。
我正在尝试对我正在使用 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) 我在哪里可以得到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 类型异常终止
你可以帮帮我吗?
我是在 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 的解决方案: …
我想录制音频文件并通过应用一些效果来保存它。录音没问题,播放带有效果的音频也没问题。问题是当我尝试离线保存此类音频时,它会生成空的音频文件。这是我的代码:
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) 我已经开始遇到以前没有发生的崩溃,因为记录的初始化有错误:
[avae] AVAEInternal.h:70:_AVAE_Check: required condition is false: [AVAudioIONodeImpl.mm:911:SetOutputFormat: (format.sampleRate == hwFormat.sampleRate)]
Run Code Online (Sandbox Code Playgroud)
在这种情况下,它似乎与使用 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) 在过去的几周里,我一直试图从许多不同的例子中拼凑出一个解决方案,这将使我能够:
我见过的几乎所有示例都涉及将音频编码到文件中,我这样做是为了测试,但不是我需要的。我需要取一个数据包,编码并传输它
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) TL;DR -AVAudioSession将AVAudioSessionMediaServicesWereLostNotification在指定蓝牙端口时触发,AVAudioSession.setPreferredInput并且该设备在使用AVCaptureSession或主动读取输入时断开连接AVAudioEngine。示例项目在这里。
https://openradar.appspot.com/FB8921592
通过我认为的“快乐路径”,或者至少应该得到 Apple 支持的路径,我可以始终如一AVAudioSession地触发它AVAudioSessionMediaServicesWereLostNotification和AVAudioSessionMediaServicesWereResetNotification通知。
在这两个通知之间,您的应用无法执行任何音频或视频 I/O 或处理(编码或解码)。这是一个总的媒体服务关闭 1 到 2 秒。
这仅在使用时发生AVAudioSession.setPreferredInput,其中您设置的端口是蓝牙设备。从该端口主动录制时,您关闭蓝牙设备。
发生这种情况时,在服务丢失之前不会触发来自AVAudioSession、AVAudioEngine或 的其他通知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
avaudioengine ×10
ios ×7
swift ×5
avfoundation ×4
core-audio ×3
avaudiofile ×2
audio ×1
macos ×1
pcm ×1