版本: Unity 6 (6000.0)
语言英语
  • C#

MonoBehaviour.OnAudioFilterRead(float[], int)

建议更改

成功!

感谢您帮助我们提高 Unity 文档的质量。虽然我们无法接受所有提交,但我们确实阅读了用户提出的每一个建议更改,并将根据需要进行更新。

关闭

提交失败

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

关闭

取消

切换到手册

参数

数据 一个包含音频数据的浮点数数组
通道 一个整数,用于存储传递给此委托的音频数据通道数量。

描述

如果实现了 OnAudioFilterRead,Unity 将在音频 DSP 链中插入自定义滤波器。

滤波器将按照 Inspector 中显示的 MonoBehaviour 脚本的顺序插入。

每次将一组音频数据发送到滤波器时,都会调用 OnAudioFilterRead(这会频繁发生,每隔约 20 毫秒,具体取决于采样率和平台)。音频数据是一个范围在 [-1.0f;1.0f] 之间的浮点数数组,包含来自链中前一个滤波器或 音频剪辑 的音频 音频源。如果这是链中的第一个滤波器,并且没有将剪辑附加到音频源,则将此滤波器作为音频源播放。这样一来,您可以将滤波器用作音频剪辑,以过程方式生成音频。

如果有多个通道,则通道数据是交错的。这意味着数组中的每个连续数据样本都来自不同的通道,直到您用完所有通道并循环回到第一个通道为止。 data.Length 报告数据的总大小,因此要找到每个通道的样本数量,请将 data.Length 除以 channels

如果实现了 OnAudioFilterRead,则 Inspector 中会显示一个 VU 表,显示输出样本电平。滤波器的处理时间也会被测量,并将花费的毫秒数显示在 VU 表旁边。如果滤波器占用时间过长,则该数字将变为红色,这意味着混音器将缺乏音频数据。

另外,请注意 OnAudioFilterRead 是在与主线程不同的线程(即音频线程)上调用的,因此不允许从此函数调用许多 Unity 函数(如果尝试,则会在运行时显示警告)。

其他资源:音频滤波器

using UnityEngine;

// The code example shows how to implement a metronome that procedurally // generates the click sounds via the OnAudioFilterRead callback. // While the game is paused or suspended, this time will not be updated and sounds // playing will be paused. Therefore developers of music scheduling routines do not have // to do any rescheduling after the app is unpaused

[RequireComponent(typeof(AudioSource))] public class AudioTest : MonoBehaviour { public double bpm = 140.0F; public float gain = 0.5F; public int signatureHi = 4; public int signatureLo = 4;

private double nextTick = 0.0F; private float amp = 0.0F; private float phase = 0.0F; private double sampleRate = 0.0F; private int accent; private bool running = false;

void Start() { accent = signatureHi; double startTick = AudioSettings.dspTime; sampleRate = AudioSettings.outputSampleRate; nextTick = startTick * sampleRate; running = true; }

void OnAudioFilterRead(float[] data, int channels) { if (!running) return;

double samplesPerTick = sampleRate * 60.0F / bpm * 4.0F / signatureLo; double sample = AudioSettings.dspTime * sampleRate; int dataLen = data.Length / channels;

int n = 0; while (n < dataLen) { float x = gain * amp * Mathf.Sin(phase); int i = 0; while (i < channels) { data[n * channels + i] += x; i++; } while (sample + n >= nextTick) { nextTick += samplesPerTick; amp = 1.0F; if (++accent > signatureHi) { accent = 1; amp *= 2.0F; } Debug.Log("Tick: " + accent + "/" + signatureHi); } phase += amp * 0.3F; amp *= 0.993F; n++; } } }