版本:Unity 6 (6000.0)
语言英语
  • C#
实验性:此 API 为实验性功能,未来可能会发生更改或删除。

AudioSampleProvider

UnityEngine.Experimental.Audio 中的类

/

实现于:UnityEngine.AudioModule

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交的内容,但我们确实会阅读用户提出的每个建议更改,并在适用情况下进行更新。

关闭

提交失败

由于某种原因,您的建议更改无法提交。请<a>稍后再试</a>。感谢您抽出时间帮助我们提高 Unity 文档的质量。

关闭

取消

描述

提供对 Unity 对象(如 VideoPlayer)生成的音频样本的访问权限。

此类旨在在主线程之外使用,并且实现假设一次只有一个使用者调用 AudioSampleProvider.ConsumeSampleFrames。音频数据可以从 C# 和 C++ 访问,具体取决于需要对该数据执行的操作。

以下是如何使用从 VideoPlayer 获取的访问器从 C# 访问样本的示例

using UnityEngine;
using Unity.Collections;
using UnityEngine.Experimental.Video;
using UnityEngine.Experimental.Audio;
using UnityEngine.Video;

public class ManagedAudioOutput : MonoBehaviour { AudioSampleProvider provider;

void Start() { VideoPlayer vp = GetComponent<VideoPlayer>(); vp.audioOutputMode = VideoAudioOutputMode.APIOnly; vp.prepareCompleted += Prepared; vp.Prepare(); }

void Prepared(VideoPlayer vp) { provider = vp.GetAudioSampleProvider(0); provider.sampleFramesAvailable += SampleFramesAvailable; provider.enableSampleFramesAvailableEvents = true; provider.freeSampleFrameCountLowThreshold = provider.maxSampleFrameCount / 4; vp.Play(); }

void SampleFramesAvailable(AudioSampleProvider provider, uint sampleFrameCount) { using (NativeArray<float> buffer = new NativeArray<float>( (int)sampleFrameCount * provider.channelCount, Allocator.Temp)) { var sfCount = provider.ConsumeSampleFrames(buffer); Debug.LogFormat("SetupSoftwareAudioOut.Available got {0} sample frames.", sfCount); // Do something with the samples here... } } }

以下是如何从 C++ 访问样本的示例。设置必须在 C# 中完成,然后 Unity 的核心和本机插件可以相互调用,而无需通过托管代码。

using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Experimental.Video;
using UnityEngine.Experimental.Audio;
using UnityEngine.Video;

public class NativeAudioOutput : MonoBehaviour { AudioSampleProvider provider; AudioSampleProvider.SampleFramesEventNativeFunction sampleFramesAvailableNativeHandler = SampleFramesAvailable;

void Start() { VideoPlayer vp = GetComponent<VideoPlayer>(); vp.audioOutputMode = VideoAudioOutputMode.APIOnly; vp.prepareCompleted += Prepared; vp.Prepare(); }

void Prepared(VideoPlayer vp) { provider = vp.GetAudioSampleProvider(0); provider.freeSampleFrameCountLowThreshold = provider.maxSampleFrameCount - 1024;

SetConsumeSampleFramesFunction( AudioSampleProvider.consumeSampleFramesNativeFunction, provider.id, provider.channelCount, provider.sampleRate); provider.SetSampleFramesAvailableNativeHandler( sampleFramesAvailableNativeHandler, (IntPtr)0);

vp.Play(); }

private const string pluginName = #if UNITY_IPHONE "__Internal" #else "NativeAudioOutputPlugin" #endif ;

[DllImport(pluginName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] private static extern void SetConsumeSampleFramesFunction( AudioSampleProvider.ConsumeSampleFramesNativeFunction cb, uint id, ushort channelCount, uint sampleRate);

[AOT.MonoPInvokeCallback(typeof(AudioSampleProvider.SampleFramesEventNativeFunction))] [DllImport(pluginName, ExactSpelling = true, CallingConvention = CallingConvention.Cdecl)] private static extern void SampleFramesAvailable(IntPtr userData, uint id, uint sampleFrameCount); }

以下是配套的 C++ 插件

#include <algorithm>
#include <stdint.h>

typedef uint32_t(__cdecl *ConsumeSampleFramesFunction)( uint32_t providerId, float* interleavedSampleFrames, uint32_t sampleFrameCount);

ConsumeSampleFramesFunction ConsumeSampleFrames = NULL; uint32_t providerId = -1; float* buffer = NULL; uint32_t bufferSampleFrameCount = 0; uint32_t availableSampleFrameCount = 0;

extern "C" __cdecl void SetConsumeSampleFramesFunction( ConsumeSampleFramesFunction function, uint32_t id, uint16_t channelCount, uint32_t sampleRate) { ConsumeSampleFrames = function; providerId = id; delete[] buffer; buffer = new float[channelCount * sampleRate]; // 1s worth of sample frames. bufferSampleFrameCount = sampleRate; }

extern "C" __cdecl void SampleFramesAvailable(void* userData, uint32_t id, uint32_t sampleFrameCount) { if (ConsumeSampleFrames == NULL) return;

// We consume the sample frames from the handler that tells us that there are some available. // But we could also invoke this regularly from another thread, for example the thread providing // samples to an audio device. const uint32_t consumedSampleFrameCount = ConsumeSampleFrames( providerId, buffer, std::min(bufferSampleFrameCount, sampleFrameCount)); // Do something with the samples here... }

静态属性

consumeSampleFramesNativeFunction指向提供对音频样本帧访问权限的本机函数的指针。

属性

availableSampleFrameCount可以使用 AudioSampleProvider.ConsumeSampleFrames 消费的可用样本帧数。
channelCount每个样本帧的音频通道数。
enableSampleFramesAvailableEvents启用 AudioSampleProvider.sampleFramesAvailable 事件。
enableSilencePadding如果为真,则 ConsumeSampleFrames 生成的缓冲区将在静默时进行填充,如果请求的缓冲区大小大于可用缓冲区大小,否则,缓冲区中的额外样本帧将保持不变。
freeSampleFrameCount样本生产者在溢出之前仍可以写入的样本帧数。
freeSampleFrameCountLowThreshold当空闲样本计数低于此阈值时,将发出 AudioSampleProvider.sampleFramesAvailable 事件和关联的本机事件。
id此实例的唯一标识符。
maxSampleFrameCount在发出溢出事件之前,可以在内部缓冲区中累积的最大样本帧数。
owner此提供程序来自的物体。
sampleRate此类生成的样本帧的预期播放速率。
trackIndex创建此提供程序的物体中轨道的索引。
valid如果物体有效,则为真。

公共方法

ClearSampleFramesAvailableNativeHandler清除使用 AudioSampleProvider.SetSampleFramesAvailableNativeHandler 设置的本机处理程序。
ClearSampleFramesOverflowNativeHandler清除使用 AudioSampleProvider.SetSampleFramesOverflowNativeHandler 设置的本机处理程序。
ConsumeSampleFrames从内部缓冲区消费样本帧。
Dispose释放内部资源。继承自 IDisposable。
SetSampleFramesAvailableNativeHandler设置当可用样本帧数超过阈值时发出的事件的本机事件处理程序。
SetSampleFramesOverflowNativeHandler设置当内部样本帧缓冲区溢出时发出的事件的本机事件处理程序。

事件

sampleFramesAvailable当可用样本帧数超过使用 AudioSampleProvider.freeSampleFrameCountLowThreshold 设置的阈值时调用。
sampleFramesOverflow当可用样本帧数超过内部缓冲区所能容纳的最大值时调用。

委托

ConsumeSampleFramesNativeFunction表示用于消费样本帧的本机函数指针的类型。
SampleFramesEventNativeFunction表示用于处理样本帧事件的本机函数指针的类型。
SampleFramesHandler样本帧事件的委托。