当前位置: 代码网 > it编程>编程语言>Asp.net > C#播放short或者byte类型的音频

C#播放short或者byte类型的音频

2024年12月24日 Asp.net 我要评论
一、通过nuget安装naudio包开发工具:vs2019点击visualstudio 2019的工具->nuget包管理器-》管理解决方案的nuget的程序包-》浏览-》在搜索框中输入naud

一、通过nuget安装naudio包

开发工具:vs2019

点击visual studio 2019的工具->nuget包管理器-》管理解决方案的nuget的程序包-》浏览-》在搜索框中输入naudio-》点击安装

二、获取short类型或者byte类型的音频数据

我的数据是一组short类型的正弦波信号,存储在txt中,如下图所示:

通过c#读取文档并存储在short数组中

string filepath = "20500left.txt"; // txt文件路径
short[] audiodata = new short[48000 * 2]; //双声道数据 
int index = 0;
// 读取txt文档并按逗号分割文本
using (streamreader reader = new streamreader(filepath))
{
    string line;
    while ((line = reader.readline()) != null)
    {
        string[] parts = line.split(',');
        foreach (string part in parts)
        {
            //console.writeline(part);
            audiodata[index] = convert.toint16(part);
            index++;
        }
    }
              
}

将short变为byte类型的数据(如果本身你的音频数据就是byte类型就不需要执行下边操作)

// 将short[]音频数据转换为byte[]数据
byte[] bytedata = new byte[audiodata.length * 2]; // short类型占2个字节
buffer.blockcopy(audiodata, 0, bytedata, 0, bytedata.length);

三、循环播放自己的音频数据,重写wavestream类

主要是重写了read这个函数,读到数据流末尾,就从开头读取。

 class loopingwavestream : wavestream
    {
        private wavestream sourcestream;
 
        public loopingwavestream(wavestream sourcestream)
        {
            this.sourcestream = sourcestream;
        }
 
        public override waveformat waveformat => sourcestream.waveformat;
 
        public override long length => sourcestream.length;
 
        public override long position
        {
            get => sourcestream.position;
            set => sourcestream.position = value;
        }
 
        public override int read(byte[] buffer, int offset, int count)
        {
            int bytesread = 0;
 
            while (bytesread < count)
            {
                int read = sourcestream.read(buffer, offset + bytesread, count - bytesread);
                if (read == 0)
                {
                    // 如果读取到末尾,重新从头开始读取
                    sourcestream.position = 0;
                }
                bytesread += read;
            }
 
            return bytesread;
        }
    }

将上边的byte类型的数据转换为stream类型,并填入waveout对象中,进行播放

 // 创建内存流
            using (memorystream stream = new memorystream(bytedata))
            {
                // 从内存流中创建rawsourcewavestream   //采样率设置为48000,位深设置位16位,通道为双声道
                rawsourcewavestream rawstream = new rawsourcewavestream(stream, new waveformat(48000, 16, 2));
                loopingwavestream loopingwavestream=new loopingwavestream(rawstream); 
                // 使用waveoutevent播放音频数据
                waveout waveout = new waveout();
                waveout.init(loopingwavestream);//想要循环播放
                //waveout.init(rawstream);      //不想要循环播放
                waveout.play();
 
                //下边两种方式的循环播放会有爆音,不采用。
                //waveout.playbackstopped += (sender, e) =>
                //   {
                //       if (waveout.playbackstate == playbackstate.stopped)
                //       {
                //           rawstream.position = 0;
                //           waveout.play();
                //       }
                //   };
                //while (waveout.playbackstate == playbackstate.playing)
                //{
                //    if (rawstream.position >= rawstream.length)
                //    {
                //        rawstream.position = 0;
                //        //console.writeline("audio stream reached the end.");
                //        //break;
                //    }                    
                //}
 
                console.writeline("press enter to stop playback.");
                console.readline();   //阻塞线程
 
                waveout.stop();  //停止播放
                waveout.dispose();
            }

四、完整代码

using naudio.wave;
using system;
using system.collections.generic;
using system.io;
using system.linq;
using system.media;
using system.text;
using system.threading.tasks;
 
namespace 播放short
{
    class loopingwavestream : wavestream
    {
        private wavestream sourcestream;
 
        public loopingwavestream(wavestream sourcestream)
        {
            this.sourcestream = sourcestream;
        }
 
        public override waveformat waveformat => sourcestream.waveformat;
 
        public override long length => sourcestream.length;
 
        public override long position
        {
            get => sourcestream.position;
            set => sourcestream.position = value;
        }
 
        public override int read(byte[] buffer, int offset, int count)
        {
            int bytesread = 0;
 
            while (bytesread < count)
            {
                int read = sourcestream.read(buffer, offset + bytesread, count - bytesread);
                if (read == 0)
                {
                    // 如果读取到末尾,重新从头开始读取
                    sourcestream.position = 0;
                }
                bytesread += read;
            }
 
            return bytesread;
        }
    }
    class program
    {
        static void main(string[] args)
        {
            console.writeline("开始");
 
            string filepath = "20500left.txt"; // txt文件路径
            short[] audiodata = new short[48000 * 2]; //双声道数据 
            int index = 0;
            // 读取txt文档并按逗号分割文本
            using (streamreader reader = new streamreader(filepath))
            {
                string line;
                while ((line = reader.readline()) != null)
                {
                    string[] parts = line.split(',');
                    foreach (string part in parts)
                    {
                        //console.writeline(part);
                        audiodata[index] = convert.toint16(part);
                        index++;
                    }
                }
              
            }
            // 将short[]音频数据转换为byte[]数据
            byte[] bytedata = new byte[audiodata.length * 2]; // short类型占2个字节
            buffer.blockcopy(audiodata, 0, bytedata, 0, bytedata.length);
            //方式1///
            
            // 创建内存流
            using (memorystream stream = new memorystream(bytedata))
            {
                // 从内存流中创建rawsourcewavestream   //采样率设置为48000,位深设置位16位,通道为双声道
                rawsourcewavestream rawstream = new rawsourcewavestream(stream, new waveformat(48000, 16, 2));
                loopingwavestream loopingwavestream=new loopingwavestream(rawstream); 
                // 使用waveoutevent播放音频数据
                waveout waveout = new waveout();
                waveout.init(loopingwavestream);//想要循环播放
                //waveout.init(rawstream);      //不想要循环播放
                waveout.play();
 
                //下边两种方式的循环播放会有爆音,不采用。
                //waveout.playbackstopped += (sender, e) =>
                //   {
                //       if (waveout.playbackstate == playbackstate.stopped)
                //       {
                //           rawstream.position = 0;
                //           waveout.play();
                //       }
                //   };
                //while (waveout.playbackstate == playbackstate.playing)
                //{
                //    if (rawstream.position >= rawstream.length)
                //    {
                //        rawstream.position = 0;
                //        //console.writeline("audio stream reached the end.");
                //        //break;
                //    }                    
                //}
 
                console.writeline("press enter to stop playback.");
                console.readline();   //阻塞线程
 
                waveout.stop();  //停止播放
                waveout.dispose();
            }
 
 
        }
    }
}

以上就是c#播放short或者byte类型的音频的详细内容,更多关于c#播放音频的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com