C# 实时复制缓冲区数据

C# 实时复制缓冲区数据,c#,multithreading,unity3d,audio,buffer,C#,Multithreading,Unity3d,Audio,Buffer,我正在尝试将从Unity传入的麦克风音频实时发送到Wwise。 我有一个“生产者线程”和一个“消费者线程”。我试图将传入缓冲区从生产者复制到消费者 // Unity callback on microphone input (“producer thread“) void OnAudioFilterRead(float[] data, int channels) { // acquire ownership of mutex and buffer mutex.WaitOne();

我正在尝试将从Unity传入的麦克风音频实时发送到Wwise。 我有一个“生产者线程”和一个“消费者线程”。我试图将传入缓冲区从生产者复制到消费者

// Unity callback on microphone input (“producer thread“)
void OnAudioFilterRead(float[] data, int channels)
{
    // acquire ownership of mutex and buffer
    mutex.WaitOne();

    // copy samples to buffer (de–interleave channels)
    for (int i = 0; i < data.Length / channels; i++)
    {
        buffer.Add(data[i * channels]);
    }


    // release ownership of mutex and buffer
    mutex.ReleaseMutex();
}

// Wwise callback that sends buffered samples to Wwise (“consumer thread“)
bool AudioSamplesDelegate(uint playingID, uint channelIndex, float[] samples)
{
    // acquire ownership of mutex and buffer
    mutex.WaitOne();

    // copy samples from buffer to temporary block
    int blockSize = Math.Min(buffer.Count, samples.Length);
    List<float> block = buffer.GetRange(0, blockSize);
    buffer.RemoveRange(0, blockSize);

    // release ownership of mutex and buffer (release mutex as quickly as possible)
    mutex.ReleaseMutex();

    // copy samples from temporary block to output array
    block.CopyTo(samples);

    // Return false to indicate that there is no more data to provide. This will also stop the associated event.
    return IsPlaying;
}
//麦克风输入上的统一回调(“生产者线程”)
无效OnAudioFilterRead(浮点[]数据,整数通道)
{
//获取互斥和缓冲区的所有权
mutex.WaitOne();
//将样本复制到缓冲区(解交织通道)
对于(int i=0;i

这是可行的,但我从Wwise获得的音频是有问题的。关于实现这一点/改进这一点的最佳方法的任何输入?是循环缓冲区吗?

我认为使用多个缓冲区而不是一个大的缓冲区来减少同步时间会很有帮助

// Create a thread-safed queue
Queue bufferQueue = Queue.Synchronized(new Queue());
List<float> remains;

// Unity callback on microphone input (“producer thread“)
void OnAudioFilterRead(float[] data, int channels)
{
    var buffer = new List<folat>(data.Length);  

    // copy samples to buffer (de–interleave channels)
    for (int i = 0; i < data.Length / channels; i++)
    {
        buffer.Add(data[i * channels]);
    }

    // Add buffer to the queue
    bufferQueue.Enqueue(buffer);
}

// Wwise callback that sends buffered samples to Wwise (“consumer thread“)
bool AudioSamplesDelegate(uint playingID, uint channelIndex, float[] samples)
{
    // Fill samples 
    var requiredLength = samples.Length;
    while (requiredLength > 0)
    {
        if (remains == null)
            if (bufferQueue.Count > 0)
                remains = bufferQueue.Dequeue();
            else
                break;

        if (remains.Length > requiredLength)
        {
            remains.CopyTo(0, samples, samples.Length - requiredLength, requiredLength);
            remains.RemoveRange(0, requiredLength);
            break;
        }

        remains.CopyTo(0, samples, samples.Length - requiredLength, remains.Length);
        requiredLength -= remains.Length;
        remains = null;
    }

    // Return false to indicate that there is no more data to provide. This will also stop the associated event.
    return IsPlaying;
}
//创建线程安全队列
Queue bufferQueue=Queue.Synchronized(新队列());
名单仍然存在;
//麦克风输入上的统一回调(“生产者线程”)
无效OnAudioFilterRead(浮点[]数据,整数通道)
{
var buffer=新列表(data.Length);
//将样本复制到缓冲区(解交织通道)
对于(int i=0;i0)
{
如果(保持==null)
如果(bufferQueue.Count>0)
resides=bufferQueue.Dequeue();
其他的
打破
如果(剩余长度>所需长度)
{
resists.CopyTo(0,samples,samples.Length-requiredLength,requiredLength);
剩余长度(0,所需长度);
打破
}
resists.CopyTo(0,samples,samples.Length-requiredLength,resists.Length);
所需长度-=剩余长度;
剩余=空;
}
//返回false表示没有更多数据可提供。这也将停止关联事件。
返回显示;
}

存在的主要问题是,消费者和制作者正在相互屏蔽,即使声音是一个非常时间敏感的东西。您应该共享一个
屏蔽集合
。让制作者按音频样本内部的方式推送音频样本,让消费者等待,也可能需要预先分配缓冲区到所需的大小(因为它是预先知道的)。@500 InternalServerError您是对的。
List.Add
如果超出容量,将花费更多。