Joa*_*erg 6 .net c# unity-game-engine
首先让我说这是我第一次在这里提出问题。如果我的代码格式不清楚或表达不佳,请告诉我,我很乐意进行调整。
我正在为要在 Unity (C#) 中使用的工具进行概念设计,以允许我们实时“流式传输”AudioSource 的输出,然后从不同的游戏对象播放相同的音频。从本质上讲,我们将一个并行信号存储在缓冲区中,而原始 AudioSource 功能如预期,将其播放的剪辑发送到混音器,就像正常一样。
为了实现这一点,我正在尝试使用音频线程和 OnAudioFilterRead() 函数。为了提取浮点音频数据以通过管道传输到 OnAudioFilterRead(),我正在使用 AudioSource.GetOutputData,将其存储到一个数组中,然后将该数组提供给音频过滤器。我还创建了一个空的 AudioClip,从同一个数组中设置它的数据并在新的 GameObject 上播放该 AudioClip。
现在我可以从新的 GameObject 播放音频,但结果非常失真和令人不快,我将其归结为以下一项或多项;
正在以不同步的方式写入/读取音频缓冲区
Unity 采样率导致剪辑出现问题。尝试过 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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
非常感谢我可能被授予的任何智慧!谢谢!
| 归档时间: |
|
| 查看次数: |
1841 次 |
| 最近记录: |