我想实时修改传入信号并将其发送到iOS设备扬声器。我已经读过AVAudioEngine可以用于这样的任务。但无法找到我想要实现的文档或示例。
出于测试目的,我已经完成了:
audioEngine = AVAudioEngine()
let unitEffect = AVAudioUnitReverb()
unitEffect.wetDryMix = 50
audioEngine.attach(unitEffect)
audioEngine.connect(audioEngine.inputNode, to: unitEffect, format: nil)
audioEngine.connect(unitEffect, to: audioEngine.outputNode, format: nil)
audioEngine.prepare()
如果按下按钮,我就会这样做:
do {
try audioEngine.start()
} catch {
print(error)
}
或audioEngine.stop()
。
混响效果应用于信号,我可以听到它有效。所以现在我想摆脱混响并且:
答案 0 :(得分:1)
这个github存储库从字面上做到了:https://github.com/dave234/AppleAudioUnit。
只需从此处将BufferedAudioUnit
添加到您的项目中,然后使用以下实现将其子类化:
AudioProcessingUnit.h:
#import "BufferedAudioUnit.h"
@interface AudioProcessingUnit : BufferedAudioUnit
@end
AudioProcessingUnit.m:
#import "AudioProcessingUnit.h"
@implementation AudioProcessingUnit
-(ProcessEventsBlock)processEventsBlock:(AVAudioFormat *)format {
return ^(AudioBufferList *inBuffer,
AudioBufferList *outBuffer,
const AudioTimeStamp *timestamp,
AVAudioFrameCount frameCount,
const AURenderEvent *realtimeEventListHead) {
for (int i = 0; i < inBuffer->mNumberBuffers; i++) {
float *buffer = inBuffer->mBuffers[i].mData;
for (int j = 0; j < inBuffer->mBuffers[i].mDataByteSize; j++) {
buffer[j] = /*process it here*/;
}
memcpy(outBuffer->mBuffers[i].mData, inBuffer->mBuffers[i].mData, inBuffer->mBuffers[i].mDataByteSize);
}
};
}
@end
然后,在您的AVAudioEngine设置中:
let audioComponentDescription = AudioComponentDescription(
componentType: kAudioUnitType_Effect,
componentSubType: kAudioUnitSubType_VoiceProcessingIO,
componentManufacturer: 0x0,
componentFlags: 0,
componentFlagsMask: 0
);
AUAudioUnit.registerSubclass(
AudioProcessingUnit.self,
as: audioComponentDescription,
name: "AudioProcessingUnit",
version: 1
)
AVAudioUnit.instantiate(
with: audioComponentDescription,
options: .init(rawValue: 0)
) { (audioUnit, error) in
guard let audioUnit = audioUnit else {
NSLog("Audio unit is NULL")
return
}
let formatHardwareInput = self.engine.inputNode.inputFormat(forBus: 0)
self.engine.attach(audioUnit)
self.engine.connect(
self.engine.inputNode,
to: audioUnit,
format: formatHardwareInput
)
self.engine.connect(
audioUnit,
to: self.engine.outputNode,
format: formatHardwareInput
)
}