首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >实时复制缓冲区数据

实时复制缓冲区数据
EN

Stack Overflow用户
提问于 2018-08-22 02:11:08
回答 1查看 220关注 0票数 1

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

代码语言:javascript
运行
复制
// 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;
}

这是有效的,但我从Wwise得到的音频是小故障。对实现这一点/改进这一点的最佳方法有什么建议?循环缓冲区是可行的吗?

EN

回答 1

Stack Overflow用户

发布于 2018-08-28 17:47:13

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

代码语言:javascript
运行
复制
// 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;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51954447

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档