Swift 多文件播放器上的核心音频声音测量
我有一个AUGraph设置,其中有两个文件播放器音频单元输入多通道混音器单元,然后再输入远程I/O输出。这个设置工作得很好 现在我一直在努力添加一个回调,这样我就可以计算出各个文件播放器的音量Swift 多文件播放器上的核心音频声音测量,swift,swift3,callback,core-audio,audiounit,Swift,Swift3,Callback,Core Audio,Audiounit,我有一个AUGraph设置,其中有两个文件播放器音频单元输入多通道混音器单元,然后再输入远程I/O输出。这个设置工作得很好 现在我一直在努力添加一个回调,这样我就可以计算出各个文件播放器的音量 private let meteringCallback: AURenderCallback = { ( inRefCon, ioActionFlags, inTimeStamp, inBusNumber, frameCount, ioData ) ->
private let meteringCallback: AURenderCallback = { (
inRefCon,
ioActionFlags,
inTimeStamp,
inBusNumber,
frameCount,
ioData ) -> OSStatus in
var status = noErr
var track: AUTrack = unsafeBitCast(inRefCon, to: AUTrack.self)
status = AudioUnitRender(track.fileAU!,
ioActionFlags,
inTimeStamp,
inBusNumber,
frameCount,
ioData!);
var samples = [Float]()
let ptr = ioData!.pointee.mBuffers.mData?.assumingMemoryBound(to: Float.self)
samples.append(contentsOf: UnsafeBufferPointer(start: ptr, count: Int(frameCount)))
// ... fancy algorithm calculating DB value ...
}
AUTrack simple保存有关该特定轨迹的信息。将整个类实例传递给回调(在示例中通常是这样做的)在这里没有意义,因为有多个文件播放器
private let meteringCallback: AURenderCallback = { (
inRefCon,
ioActionFlags,
inTimeStamp,
inBusNumber,
frameCount,
ioData ) -> OSStatus in
var status = noErr
var track: AUTrack = unsafeBitCast(inRefCon, to: AUTrack.self)
status = AudioUnitRender(track.fileAU!,
ioActionFlags,
inTimeStamp,
inBusNumber,
frameCount,
ioData!);
var samples = [Float]()
let ptr = ioData!.pointee.mBuffers.mData?.assumingMemoryBound(to: Float.self)
samples.append(contentsOf: UnsafeBufferPointer(start: ptr, count: Int(frameCount)))
// ... fancy algorithm calculating DB value ...
}
现在我需要将这个回调设置在某个地方,这样我就可以捕获每个文件播放器输入到混合器中的值。然而,当我尝试这样做时,我不断得到一个-10877(无效元素)错误
我尝试用这个设置计量回调
// Set metering callback
var meteringCallbackStruct = AURenderCallbackStruct(inputProc: meteringCallback,
inputProcRefCon: &self.tracks[1])
status = AudioUnitSetProperty(self.tracks[1].fileAU!,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Output,
0,
&meteringCallbackStruct,
UInt32(MemoryLayout<AURenderCallbackStruct>.size))
//设置计数回调
var meteringCallbackStruct=AURenderCallbackStruct(inputProc:meteringCallback,
inputProcRefCon:&self.tracks[1])
状态=AudioUnitSetProperty(self.tracks[1].fileAU!,
kAudioUnitProperty_SetRenderCallback,
考迪翁镜输出,
0,
&meteringCallbackStruct,
UInt32(内存大小))
我不太确定如何解决这个问题
除非我以某种方式将样本传回混合装置,否则这个回调不会“吃掉”样本吗?您不应该用Swift进行回调。渲染线程处理只能在C/C++中完成 您可以使用: 它使用与呈现回调相同的函数签名。它被称为“渲染前”和“渲染后”,您需要处理渲染后。您可以从ioActionFlags获取此信息
int isPostRender = ioActionFlags & kAudioUnitRenderAction_PostRender;
但是,由于您使用的是多通道混音器,因此内置了输入级监控,因此不需要回调
您首先像这样启用它
//AudioUnit mixer; kAudioUnitSubType_MultiChannelMixer
//Call Before AudioUnitInitialize()
UInt32 meteringMode = 1;
AudioUnitSetProperty(mixer, kAudioUnitProperty_MeteringMode, kAudioUnitScope_Input, 0, &meteringMode, sizeof(meteringMode));
然后在处理过程中,您可以通过读取参数来获得级别
int channel = 0;
AudioUnitParameterValue averageDecibles;
AudioUnitGetParameter(mixer, kMultiChannelMixerParam_PreAveragePower, kAudioUnitScope_Input, channel, &averageDecibles);
AudioUnitParameterValue peakHoldDecibles;
AudioUnitGetParameter(mixer, kMultiChannelMixerParam_PrePeakHoldLevel, kAudioUnitScope_Input, channel, &peakHoldDecibles);
Swift:
var meteringMode: UInt32 = 1;
let propSize = UInt32(MemoryLayout<UInt32>.size)
AudioUnitSetProperty(mixer, kAudioUnitProperty_MeteringMode, kAudioUnitScope_Input, 0, &meteringMode, propSize);
var averageDecibles: AudioUnitParameterValue = 0
AudioUnitGetParameter(mixer, kMultiChannelMixerParam_PreAveragePower, kAudioUnitScope_Input, channel, &averageDecibles);
var peakHoldDecibles: AudioUnitParameterValue = 0
AudioUnitGetParameter(mixer, kMultiChannelMixerParam_PrePeakHoldLevel, kAudioUnitScope_Input, channel, &peakHoldDecibles);
var计量模式:UInt32=1;
让propSize=UInt32(MemoryLayout.size)
AudioUnitSetProperty(混音器、kAudioUnitProperty_计量模式、kAudioUnitScope_输入、0和计量模式、propSize);
var averageDecibles:AudioUnitParameterValue=0
AudioUnitGetParameter(混音器、K多通道混音器参数、平均功率、音频范围、输入、通道和平均小数);
var peakHoldDecibles:AudioUnitParameterValue=0
AudioUnitGetParameter(混音器、kMultiChannelMixerParam\u预峰值保持电平、kAudioUnitScope\u输入、通道和峰值分辨率);
非常感谢您。这对我来说是一个很大的帮助,我已经写了一半自己的混音器了。我不敢相信我在头文件中漏掉了这些参数:D