C# 使用AudioTrack播放PCm数据

C# 使用AudioTrack播放PCm数据,c#,android,xamarin,C#,Android,Xamarin,我得到一个解码的PCm字节[]流。然后我启动AudioTrack对象,在while循环中(直到流有数据为止),我读取数据并通过write()函数将其发送到AudioTrack。问题是,我播放了一部分音乐,然后它播放了几秒钟,然后你能听到的就是噪音和这种连续性。我确实尝试增加缓冲区大小,但没有任何帮助。我时常会遇到这样的错误: 12-30 17:57:44.012 D/dalvikvm( 9195): GC_CONCURRENT freed 438K, 15% free 10178K/11847K

我得到一个解码的PCm字节[]流。然后我启动AudioTrack对象,在while循环中(直到流有数据为止),我读取数据并通过write()函数将其发送到AudioTrack。问题是,我播放了一部分音乐,然后它播放了几秒钟,然后你能听到的就是噪音和这种连续性。我确实尝试增加缓冲区大小,但没有任何帮助。我时常会遇到这样的错误:

12-30 17:57:44.012 D/dalvikvm( 9195): GC_CONCURRENT freed 438K, 15% free 10178K/11847K, paused 14ms+3ms, total 49ms
这是我的代码:

public void Read()
{
    System.Threading.Tasks.Task.Run(() =>
    {
        int _bufferSize;
        AudioTrack _output;

        _bufferSize = AudioTrack.GetMinBufferSize(44100, ChannelOut.Stereo, Android.Media.Encoding.Pcm16bit);
        _output = new AudioTrack(Android.Media.Stream.Music, 44100, ChannelOut.Stereo, Android.Media.Encoding.Pcm16bit,

       _bufferSize, AudioTrackMode.Stream);
       _output.Play();

       byte[] myReadBuffer = new byte[8000];

       while (mmInStream.CanRead)
       {
           try
           {
               mmInStream.Read(myReadBuffer, 0, myReadBuffer.Length);
               _output.Write(myReadBuffer, 0, myReadBuffer.Length);
           }
           catch (System.IO.IOException ex)
           {
               System.Diagnostics.Debug.WriteLine("Input stream was disconnected", ex);
           }
       }
       _output.Stop();
   }).ConfigureAwait(false);
}
如何修复此代码,使其在不中断的情况下播放


请注意,我将编辑此问题。 事实上,我已经明白了,我现在从音轨中得到了一个恒定的声音,现在的问题是,我有时会有短暂的口吃,而不是连续播放。然而,口吃会导致延迟,导致设备无法与其他设备同步播放音乐。这是我的更新代码:

    public void Read()
    {
        System.Threading.Tasks.Task.Run(() =>
        {
            int _bufferSize;
            AudioTrack _output;

            _output = new AudioTrack(Android.Media.Stream.Music, 44100, ChannelOut.Stereo, Android.Media.Encoding.Pcm16bit,
                10000, AudioTrackMode.Stream);
            _output.Play();

            byte[] myReadBuffer = new byte[1000];

            System.Threading.Tasks.Task.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        mmInStream.Read(myReadBuffer, 0, myReadBuffer.Length);
                        _output.Write(myReadBuffer, 0, myReadBuffer.Length);
                    }
                    catch (System.IO.IOException ex)
                    {
                        System.Diagnostics.Debug.WriteLine("Input stream was disconnected", ex);
                    }
                }
            }).ConfigureAwait(false);
        }).ConfigureAwait(false);
    }

代码中发生缓冲区溢出

根据缓冲区大小和采样率定期提交缓冲区

在你的while循环中引入一些睡眠

   /* First Buffer */
   if(mmInStream.CanRead)
   {
       try
       {
           mmInStream.Read(myReadBuffer, 0, myReadBuffer.Length);            
           _output.Write(myReadBuffer, 0, myReadBuffer.Length);
       }
       catch (System.IO.IOException ex)
       {
           System.Diagnostics.Debug.WriteLine("Input stream was disconnected", ex);
       }

   }

  while (mmInStream.CanRead)
   {
       try
       {
           mmInStream.Read(myReadBuffer, 0, myReadBuffer.Length);

           Sleep(x) --- calculate the x millisecond/second based on the buffer size & sampling frequency.

           _output.Write(myReadBuffer, 0, myReadBuffer.Length);
       }
       catch (System.IO.IOException ex)
       {
           System.Diagnostics.Debug.WriteLine("Input stream was disconnected", ex);
       }

   }
要正确播放音频质量,请检查支持的缓冲区并将缓冲区提交给


检查更多关于音轨使用的示例w.r.t。

可以使用原始PCm字节[]而不是解码的PCm字节[]进行测试吗?这是不是也有同样的问题?虽然有同样的问题,但播放的歌曲更少。@WendyZang MSFT事实上如果我使用我的手机三星Galaxy A5 2016,应用程序播放得很好,但在我的测试手机三星S4 mini(非常旧)上,手机播放得很差。这可能是版本的原因,我建议使用最新版本。实际上,还有一个问题,我目前有,请参阅更新的问题。更新了我的回答,请确保提交缓冲区的线程以适当的间隔进行调度。由于mmInStread阻止直到读取,因此输出也会阻止,问题不在于它读取速度不够快吗?您正在从静态文件读取,因此,您可以读取并准备好数据,然后进入睡眠状态。一旦你醒来,你可以提交缓冲区。