多个文件播放器上的Core Audio声音测量

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多个文件播放器上的Core Audio声音测量相关的知识,希望对你有一定的参考价值。

我有一个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;

但是,由于您使用的是多通道混音器,因此内置了输入电平监视功能,因此您不需要回调。

你首先像这样启用它。

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

迅速:

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

以上是关于多个文件播放器上的Core Audio声音测量的主要内容,如果未能解决你的问题,请参考以下文章

使用 Audio Units 播放多个重叠的短音频文件

多个声音相互重叠 <audio>

Web Audio API:将 mp3 声音流合并到一个文件并在 <audio> 标签中播放

如何在 iPhone 的 Core Audio (Audio Unit/ Remote IO) 中将录制的声音更改为男人的声音

Core Audio 大(压缩)文件播放和内存占用

使用 Windows.Media.Audio 相互叠加播放更多声音文件 UWP