Unity 2018-OnAudioFilterRead()从缓冲区实时回放

时间:2018-08-08 08:41:28

标签: c# .net unity3d

首先让我说这是我第一次在这里提出问题。如果我不清楚我的代码格式或表示不好,请告诉我,我很乐意进行调整。

我正在为在Unity(C#)中使用的工具进行概念设计,以允许我们实时“流式传输” AudioSource的输出,然后从不同的音频源播放相同的音频。游戏对象。本质上,我们会将并行信号存储在缓冲区中,而原始AudioSource会像预期的那样正常运行,然后像平常一样将其播放片段发送到混音器中。

为此,我尝试使用音频线程和OnAudioFilterRead()函数。为了提取浮点音频数据以传递到OnAudioFilterRead()中,我正在使用AudioSource.GetOutputData,将其存储到数组中,然后将该数组提供给音频滤波器。我还要创建一个空的AudioClip,将其数据设置在同一数组中,然后在新的GameObject上播放该AudioClip。

现在我正在从新的GameObject播放音频,但是结果非常失真且令人不快,我在下面总结了一个或多个;

  1. 正在以不同步的方式写入/读取音频缓冲区

  2. Unitys采样率导致剪辑出现问题。已经尝试了44.1khz和48khz的结果低于标准的情况,并尝试了剪辑的导入设置。 Unity 2018.2的文档非常薄弱,现在不推荐使用许多较旧的方法。

  3. 外星人。

理想情况下,我将能够流回音频而没有听得见的人工制品。我可以忍受一些延迟(〜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;
        }
    }        


}

非常感谢我可能被授予的任何智慧!谢谢!

0 个答案:

没有答案