实时播放充满 pcm 值的数组

Posted

技术标签:

【中文标题】实时播放充满 pcm 值的数组【英文标题】:playing array filled with pcm values in real time 【发布时间】:2013-12-01 14:32:19 【问题描述】:

我需要能够实时播放一个填充了 16 位 PCM 值(解码后)的 short[] 数组。 数组越来越长,玩家应该可以在数组“增长”时播放它。

我是用 C# 编写的。

谢谢你, 奥菲克

编辑: 我使用了 BufferedWaveProvider,代码如下所示:

Class Player

    Private WaveFormat waveForamt=new WaveFormat(8000,16,1);
    private BufferedWaveProvider bufferedWaveProvider;

    public Player()
    
        bufferedWaveProvider=new BufferedWaveProvider(waveFormat);
    

    public void AddSamples(byte[] array)
    
        bufferedWaveProvider.AddSamples(array,0,array.length);
        WaveOut waveout=new WaveOut();
        waveout.Init(bufferedWaveProvider);
        waveout.Play();
    

AddSamples func 得到的数组是 32000 长我可以看到参数 bufferedWaveProvider.BufferedBytes = 32000 bufferedWaveProvider.BufferedBytes = 80000 bufferedWaveProvider.BufferedDuration = 00:00:02 bufferedWaveProvider.BufferDuration = 00:00:05

当我记录数组时,我会说 2 秒钟,然后说:“一、二、三……” 问题是当我播放它时,我只听到一个快速的声音,和我说的完全不同..

关于哪里出了问题有什么想法吗?

Thnaks, Ofek

编辑 2: 现在我的代码看起来像这样,我从 Capture 类中调用 AddSamples 函数。 每次调用 waveout.Play() 函数后 - 我清除缓冲区并等待它再次填满。一旦它又满了,我就玩它,依此类推。问题是,在我第二次播放缓冲区时,声音开始很快,然后变慢......我听说过一些关于使用两个缓冲区的事情......你知道吗? 非常感谢!

这里是调用 player.AddSamples 的类

【问题讨论】:

How to play 16-bit pcm array programmatically 的可能重复项 不要多发。改为改进您的原始问题。详情请见How to Ask。 这不是同一个问题——这是关于实时播放的。 好的,下次知道了 屏幕照片?我认为您从字面上理解“屏幕截图”。 【参考方案1】:

您基本上需要能够设置声卡驱动程序以从音频缓冲区读取然后写入同一缓冲区。 naudio 中的 BufferedWaveProvider 类可以提供帮助。看看http://naudio.codeplex.com/。

编辑:你的课程在一个空的“表单”项目中对我来说很好,播放 2 秒的音频:

public partial class Form1 : Form

    public Form1()
    
        InitializeComponent();

        var player = new Player();

        var rand = new Random();
        var bytes = new byte[32000];
        rand.NextBytes(bytes);

        player.AddSamples(bytes);
    

您是在后台线程中调用它,还是在控制台应用程序中调用它?这可能是线程或回调问题 - 请参阅 http://naudio.codeplex.com/wikipage?title=Audio%20Output%20Driver%20Selection 中的 1) WaveOut 部分。您可能需要将不同的回调选项传递给 WaveOut()?

【讨论】:

感谢您的回答。现在它对我有用,我将回调函数添加到 WaveOut ctor。但如果你能帮助我,我还有另一个问题......请再次查看我更新的问题:) 问题:为什么您的播放器类使用 AddSamples() 中的 WaveOut 做任何事情?你不应该只是在那里添加样本吗? 另外,这是一个控制台应用吗? 最后 - 屏幕截图并不是那么友好,因为它们无法复制/粘贴或搜索 :) 优秀。祝你项目的其余部分好运! :)

以上是关于实时播放充满 pcm 值的数组的主要内容,如果未能解决你的问题,请参考以下文章

使用 GStreamer 播放保存在数组中的原始 PCM

实时播放生成的 PCM 数据

iOS语音对讲(三)FFmpeg实时解码AAC并播放PCM

在delphi中从数组数据中播放声音的最简单方法是啥

音视频 — AudioRecorder 和 AudioTrack

在 C++ 中连续流式传输 PCM 数据?