gpt4 book ai didi

swift - 多个文件播放器上的 Core Audio 声音计量

转载 作者:行者123 更新时间:2023-11-28 06:06:39 28 4
gpt4 key购买 nike

我有一个 AUGraph 设置,其中有几个 File Player 音频单元馈送到 MultiChannelMixer 单元,然后馈送到远程 I/O 输出。这个设置工作得很好。

现在我一直在努力添加一个回调,以便我可以计算各个文件播放器的音量。

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 简单保存有关该特定轨道的信息。将整个类实例传递给回调(如通常在示例中所做的那样)在这里没有意义,因为有多个文件播放器。

现在我需要在某个地方设置这个回调,这样我就可以从每个文件播放器中获取输入到混音器中的值。然而,当我尝试这样做时,我不断收到 -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))

我不太确定如何解决这个问题。

除非我以某种方式将样本传回混合器单元,否则此回调不会“吃掉”样本吗?

最佳答案

您不应该在 Swift 中执行回调。渲染线程处理只能在 C/C++ 中完成。

您可以使用 render notify :

AudioUnitAddRenderNotify(mixer, my_C_callback, nil) //my_C_callback should not reference Swift objects, or be a Swift callback.

它使用与渲染回调相同的函数签名。它被称为渲染前和渲染后,您想处理渲染后。您可以从 ioActionFlags 获得此信息。

int isPostRender = ioActionFlags & kAudioUnitRenderAction_PostRender;

但是,由于您使用的是多 channel 混音器,输入电平监控是内置的,因此您不需要回调。

你首先像这样启用它。

//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);

关于swift - 多个文件播放器上的 Core Audio 声音计量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48009288/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com