首先让我说这是我第一次在这里提出问题。如果我不清楚我的代码格式或表示不好,请告诉我,我很乐意进行调整。
我正在为在Unity(C#)中使用的工具进行概念设计,以允许我们实时“流式传输” AudioSource的输出,然后从不同的音频源播放相同的音频。游戏对象。本质上,我们会将并行信号存储在缓冲区中,而原始AudioSource会像预期的那样正常运行,然后像平常一样将其播放片段发送到混音器中。
为此,我尝试使用音频线程和OnAudioFilterRead()函数。为了提取浮点音频数据以传递到OnAudioFilterRead()中,我正在使用AudioSource.GetOutputData,将其存储到数组中,然后将该数组提供给音频滤波器。我还要创建一个空的AudioClip,将其数据设置在同一数组中,然后在新的GameObject上播放该AudioClip。
现在我正在从新的GameObject播放音频,但是结果非常失真且令人不快,我在下面总结了一个或多个;
正在以不同步的方式写入/读取音频缓冲区
Unitys采样率导致剪辑出现问题。已经尝试了44.1khz和48khz的结果低于标准的情况,并尝试了剪辑的导入设置。 Unity 2018.2的文档非常薄弱,现在不推荐使用许多较旧的方法。
外星人。
理想情况下,我将能够流回音频而没有听得见的人工制品。我可以忍受一些延迟(〜30-50ms),但音频质量不会差。
下面是正在使用的代码。该脚本已附加到GameObject上,该脚本将从原始发射器接收此音频信号,并且它具有自己的AudioSource用于播放和定位。
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
[RequireComponent(typeof(AudioSource))]
public class ECO_receiver : MonoBehaviour {
public AudioSource emitterSend;
private AudioSource audioSource;
public AudioClip streamedClip;
public bool debugSampleData;
private float[] sampleDataArray;
public float sampleSize;
public float sampleFreq;
private int outputSampleRate;
public bool _bufferReady;
void Start () {
audioSource = GetComponent<AudioSource>();
sampleSize = emitterSend.clip.samples;
sampleFreq = emitterSend.clip.frequency;
sampleDataArray = new float[2048];
streamedClip = AudioClip.Create("audiostream", (int)sampleSize, 1, (int)sampleFreq, false);
audioSource.clip = streamedClip;
audioSource.Play();
_bufferReady = true;
}
private void FixedUpdate()
{
if (emitterSend.isPlaying && _bufferReady == true)
{
FillAudioBuffer();
}
else if (!emitterSend.isPlaying)
{
Debug.Log("Emitter is not playing!");
}
if (debugSampleData && sampleDataArray != null && Input.GetKeyDown("p"))
{
for (int i = 0; i < sampleDataArray.Length; i++)
{
Debug.Log(sampleDataArray[i]);
}
}
else if (sampleDataArray == null)
{
Debug.Log("No data in array!");
}
}
void FillAudioBuffer()
{
emitterSend.GetOutputData(sampleDataArray, 0);
streamedClip.SetData(sampleDataArray, 0);
_bufferReady = false;
}
void OnAudioFilterRead(float[] data, int channels)
{
if (!_bufferReady)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = (float)sampleDataArray[i];
}
_bufferReady = true;
}
}
}
非常感谢我可能被授予的任何智慧!谢谢!