【问题标题】:Playing live audio stream from byte[] packet从 byte[] 数据包播放实时音频流
【发布时间】:2018-09-05 23:07:58
【问题描述】:

我正在尝试播放以太网麦克风提供的声音。

设备通过 udp 数据包传输实时音频,我在网络接收器线程中读取:

MemoryStream msAudio = new MemoryStream();

private void process_stream(byte[] buffer)
{
    msAudio.Write(fragment, 0, fragment.Length);
}

process_stream 在任务中被调用

然后我有另一个任务要在 NAudio 中播放流(NAudio 不是强制性的):

  while (IsConnected)
        {
            msAudio.Position = 0;
            var waveFormat = new WaveFormat(8000, 16, 1); // Same format
            using (WaveStream blockAlignedStream = new BlockAlignReductionStream(
                                                            WaveFormatConversionStream.CreatePcmStream(
                                                                new RawSourceWaveStream(msAudio , waveFormat))))
            {
                using (WaveOut waveOut = new WaveOut(WaveCallbackInfo.FunctionCallback()))
                {
                    waveOut.Init(blockAlignedStream);
                    waveOut.Play();
                    while (waveOut.PlaybackState == PlaybackState.Playing)
                    {
                        System.Threading.Thread.Sleep(100);
                    }
                }
            }
        }

我的问题是:

  • 我听到 Toc Toc Toc 噪音(大约每秒 4 次)
  • 音频变慢,声音变形,像比特率太低(但8khz是正确的)
  • 音频循环播放,我想我必须刷新我的流,但我没有看到...

如果您能告诉我一些建议,非常感谢...

附注: 为了帮助,原始代码正在使用 AudioTrack 在 android 中运行。代码是here

P.S 2:这里是我拥有的音频噪声的“图像”:

【问题讨论】:

  • 对于循环问题:使用BufferedWaveProvider 代替memoryStream,使用.AddSample() 它提供循环缓冲区,实现起来非常简单
  • 对于慢速问题:尝试将 SampleRate 加倍 .... 是的,它正在使用 16KHz... 我不知道为什么规范不正确...
  • 对于噪音问题:分析 RawAudio 似乎你的字节开头或结尾有额外字节[] 尝试删除一些字节......是的,它正在工作......我认为前4个字节提供了一些头信息,现在我有一个清晰的声音......

标签: c# audio stream byte


【解决方案1】:

我不喜欢自己回答……但我认为我的问题太具体了…… 所以我解决了我的问题:

  • 使用BufferedWaveProvider 代替memoryStream
  • 双倍采样率 (16KHz)
  • 删除缓冲区的前 4 个字节

现在我的代码看起来像:

    public ctor()
    {            
        var waveFormat = new WaveFormat(16000, 16, 1);
        buffer = new BufferedWaveProvider(waveFormat)
        {
            BufferDuration = TimeSpan.FromSeconds(10),
            DiscardOnBufferOverflow = true
        };
    }

    internal void OnDataReceived(byte[] currentFrame)
    {
        if (mPlaying && mAudioTrack != null)
        {               
            buffer.AddSamples(currentFrame, 4, currentFrame.Length);
        }
    }

    internal void ConfigureCodec()
    {                   
        mAudioTrack = new WaveOut(WaveCallbackInfo.FunctionCallback());
        mAudioTrack.Init(buffer);
        if (mPlaying)
        {
            mAudioTrack.Play();
        }            
    }

没有更多的线程......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-21
    • 2016-12-15
    • 2018-02-05
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多