使用DirectX播放音频数据流

使用DirectX播放音频数据流

使用directX插件可以播放音频数据流
现在做一个测试项目,首先将信号发生器产生的正弦波(cw波)输入到语音编码器编码,再讲编码的数据用解码算法解码,解码输出的数据流就是cw波。这个过程主要目的为了测试解码算法是否能恢复cw波。暂时不考虑这个目的
项目流程
信号发生器(cw波)—->语音编码(encode)—–>解码算法(cw波)—->解码算法(cw波)——>写入到DirectX缓冲区 —->播放

本文是要实现用DirectX音频数据流,其实就是将音频数据流写到DirectX的缓冲区并播放,分为以下三步。
1.首先分析音频文件wav的格式,wav格式
2. 将音频数据流写到wav格式中data chunk
3. DirectX播放wav数据流。
代码如下

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;
using System.IO;

namespace playwav
{
    public partial class Form1 : Form
    {
        public const int SampleBitWidth = 16;     //每个sample 包含 16bits
        public const int SampleByteWidth = 16 >> 3;// 每个sample 包含 2个byte, 每帧包含160 sample
        public const int SampleRate = 8000;       //每秒采样8000个sample。每秒读取 8000*2 =16000bytes
        BinaryWriter writer;
        MemoryStream mes;
        byte[] voice;                    

        public Form1()
        {
            InitializeComponent();
        }

        private void buttonPlay_Click(object sender, EventArgs e)
        {

            write_wavfmt(9,1);    //9*frame=9*160samples

            BinaryReader stream = new BinaryReader(mse);
            Stream a = stream.BaseStream;

            Device dev = new Device();
            dev.SetCooperativeLevel(this, CooperativeLevel.Normal);
            SecondaryBuffer sec = new SecondaryBuffer(a,Convert.ToInt32(a.Length),dev);
            sec.Play(0, BufferPlayFlags.Looping);

        }

        public void write_wavfmt(int framecount, int channelcount)
        {
            int datalength = framecount * 160 * 2 * channelcount;   //每帧160sample =160*2bytes

            int riffLength = datalength + 46;

            voice = new byte[riffLength];
            mes = new MemoryStream(voice);
            writer = new BinaryWriter(mes);
            //////////////wavfmt///////
            this.writer.Write(ASCIIEncoding.ASCII.GetBytes("RIFF"));
            this.writer.Write((int)riffLength);
            this.writer.Write(ASCIIEncoding.ASCII.GetBytes("WAVEfmt"));
            this.writer.Write((int)16);
            this.writer.Write((short)1);
            this.writer.Write((short)channelcount);
            this.writer.Write((int)SampleRate);
            this.writer.Write((int)SampleRate * SampleByteWidth * channelcount);//byteRate = SampleRate * SampleByteWidth
            this.writer.Write((short)SampleBitWidth * channelcount);
            this.writer.Write((short)SampleBitWidth);

            this.writer.Write(ASCIIEncoding.ASCII.GetBytes("data"));
            this.writer.Write((int)datalength);
            byte[] data = Get_cw_Content(datalength);//读取cw音频数据。
            this.writer.Write(data);
            this.writer.BaseStream.Seek(0, SeekOrigin.Begin);
        }
        public byte[] Get_cw_Content(int datalength)
        {
            List<short> listData = new List<short>();
            string cw_path2 = System.Environment.CurrentDirectory+ "\\tone.txt";
            string read = string.Empty;
            using (StreamReader sr = new StreamReader(cw_path2))
            {
                read = sr.ReadLine();
                while (read != null) 
                {
                    listData.Add(Convert.ToInt16(read));
                    read = sr.ReadLine();
                }
            }
            byte[] cw_data = new byte[datalength];
            MemoryStream mestream = new MemoryStream(cw_data);
            BinaryWriter bwriter = new BinaryWriter(mestream);
            for (int i = 0; i < datalength/2; i++)
                bwriter.Write(listData[i]);
            bwriter.Close();
            return cw_data;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/sophiemantela/article/details/78913955