精华内容
下载资源
问答
  • 读取 wav 格式声音文件 http://bigsec.net/b52/scipydoc/wave_pyaudio.html Python 支持 wav 文件的读写,实时的声音输入输出需要安装 pyAudio,pyMedia 进行 MP3 的解码和播放。 wav 是 Microsoft 开发的一种声音...

    读取 wav 格式声音文件

    http://bigsec.net/b52/scipydoc/wave_pyaudio.html

    Python 支持 wav 文件的读写,实时的声音输入输出需要安装 pyAudiopyMedia 进行 MP3 的解码和播放。

    wav 是 Microsoft 开发的一种声音文件格式,通常被用来保存未压缩的声音数据 (Pulse Code Modulation,PCM,脉冲编码调制)。wav 有三个重要的参数:声道数、采样频率和量化位数。

    声道数:单声道 (mono) 或者是双声道 (stereo)。
    采样频率:每秒钟声音信号的采集次数。常用的有 8kHz、16kHz、32kHz、48kHz、11.025kHz、22.05kHz、44.1kHz 等。
    量化位数:用多少 bit 表达一次采样所采集的数据,通常有 8bit、16bit、24bit 和 32bit 等。CD 中所储存的声音信号是双声道、44.1kHz、16bit。

    如果你需要自己录制和编辑声音文件,推荐使用 Audacity。它是一款开源的、跨平台、多声道的录音编辑软件。在工作中使用 Audacity 进行声音信号的录制,然后再输出成 wav 文件供 Python 程序处理。

    1. C:\Windows\media

    在这里插入图片描述

    (base) yongqiang@yongqiang:~$ cd /mnt/f/yongqiang_work/
    (base) yongqiang@yongqiang:/mnt/f/yongqiang_work$ ll
    total 260
    drwxrwxrwx 1 yongqiang yongqiang   4096 Jun  4 00:47 ./
    drwxrwxrwx 1 yongqiang yongqiang   4096 Jun  3 22:11 ../
    -rwxrwxrwx 1 yongqiang yongqiang 191788 Sep 15  2018 Windows_Ding.wav*
    -rwxrwxrwx 1 yongqiang yongqiang  70060 Sep 15  2018 ding.wav*
    (base) yongqiang@yongqiang:/mnt/f/yongqiang_work$
    (base) yongqiang@yongqiang:/mnt/f/yongqiang_work$ pwd
    /mnt/f/yongqiang_work
    (base) yongqiang@yongqiang:/mnt/f/yongqiang_work$
    

    2. 读 wav 格式声音文件

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # yongqiang cheng
    
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    
    import wave
    import numpy as np
    
    # WAV file
    audio_file = "/mnt/f/yongqiang_work/ding.wav"
    object = wave.open(audio_file, "rb")
    
    # (nchannels, sampwidth, framerate, nframes, comptype, compname)
    params = object.getparams()
    nchannels, sampwidth, framerate, nframes, comptype, compname = params[:6]
    print("nchannels = ", nchannels)
    print("sampwidth = ", sampwidth)
    print("framerate = ", framerate)
    print("nframes = ", nframes)
    print("comptype = ", comptype)
    print("compname = ", compname)
    
    # Returns number of audio channels (1 for mono, 2 for stereo).
    print("object.getnchannels() = ", object.getnchannels())
    
    # Returns sample width in bytes.
    print("object.getsampwidth() = ", object.getsampwidth())
    
    # Returns sampling frequency.
    print("object.getframerate() = ", object.getframerate())
    
    # Returns number of audio frames.
    print("object.getnframes() = ", object.getnframes())
    
    # Returns compression type ('NONE' is the only supported type).
    print("object.getcomptype() = ", object.getcomptype())
    
    # Human-readable version of getcomptype(). Usually 'not compressed' parallels 'NONE'.
    print("object.getcompname() = ", object.getcompname())
    
    # Reads and returns at most n frames of audio, as a bytes object.
    str_data = object.readframes(nframes)
    object.close()
    
    
    /home/yongqiang/miniconda3/envs/tf_cpu_1.4.1/bin/python /home/yongqiang/pycharm_work/yongqiang.py
    nchannels =  2
    sampwidth =  2
    framerate =  44100
    nframes =  17504
    comptype =  NONE
    compname =  not compressed
    object.getnchannels() =  2
    object.getsampwidth() =  2
    object.getframerate() =  44100
    object.getnframes() =  17504
    object.getcomptype() =  NONE
    object.getcompname() =  not compressed
    
    Process finished with exit code 0
    

    3. 读 wav 格式声音文件

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # yongqiang cheng
    
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    
    import wave
    import numpy as np
    import matplotlib.pyplot as plt
    
    # WAV file
    audio_file = "/mnt/f/yongqiang_work/ding.wav"
    object = wave.open(audio_file, "rb")
    
    # (nchannels, sampwidth, framerate, nframes, comptype, compname)
    params = object.getparams()
    nchannels, sampwidth, framerate, nframes, comptype, compname = params[:6]
    print("nchannels =", nchannels)
    print("sampwidth =", sampwidth)
    print("framerate =", framerate)
    print("nframes =", nframes)
    print("comptype =", comptype)
    print("compname =", compname)
    
    # Returns number of audio channels (1 for mono, 2 for stereo).
    print("object.getnchannels() =", object.getnchannels())
    
    # Returns sample width in bytes.
    print("object.getsampwidth() =", object.getsampwidth())
    
    # Returns sampling frequency.
    print("object.getframerate() =", object.getframerate())
    
    # Returns number of audio frames.
    print("object.getnframes() =", object.getnframes())
    
    # Returns compression type ('NONE' is the only supported type).
    print("object.getcomptype() =", object.getcomptype())
    
    # Human-readable version of getcomptype(). Usually 'not compressed' parallels 'NONE'.
    print("object.getcompname() =", object.getcompname())
    
    # Reads and returns at most n frames of audio, as a bytes object.
    str_data = object.readframes(nframes)
    # nframes = 17504,  channels = 2, sampwidth = 2
    # str_data (bytes: 70016) = nframes * channels * sampwidth = 17504 * 2 * 2 = 70016
    object.close()
    
    wave_data = np.fromstring(str_data, dtype=np.short)
    wave_data.shape = -1, 2
    wave_data = wave_data.T
    time = np.arange(0, nframes) * (1.0 / framerate)
    
    plt.subplot(211)
    plt.plot(time, wave_data[0])
    plt.xlabel("left channel - time (seconds)")
    plt.subplot(212)
    plt.plot(time, wave_data[1], c="g")
    plt.xlabel("right channel - time (seconds)")
    plt.show()
    
    
    /home/yongqiang/miniconda3/envs/pt-1.4_py-3.6/bin/python /home/yongqiang/pycharm_work/yongqiang.py
    nchannels = 2
    sampwidth = 2
    framerate = 44100
    nframes = 17504
    comptype = NONE
    compname = not compressed
    object.getnchannels() = 2
    object.getsampwidth() = 2
    object.getframerate() = 44100
    object.getnframes() = 17504
    object.getcomptype() = NONE
    object.getcompname() = not compressed
    
    Process finished with exit code 0
    

    在这里插入图片描述

    Python 调用 wave.open 打开 wav 文件,注意需要使用 "rb" (二进制模式) 打开文件:

    audio_file = "/mnt/f/yongqiang_work/ding.wav"
    object = wave.open(audio_file, "rb")
    

    open 返回一个 Wave_read 类的实例,通过调用它的方法读取 wav 文件的格式和数据:

    getparams:一次性返回所有的 wav 文件的格式信息,它返回的是一个组元 (tuple):声道数,量化位数 (byte 单位),采样频率,采样点数,压缩类型,压缩类型的描述。wave 模块只支持非压缩的数据,因此可以忽略最后两个信息。

    # (nchannels, sampwidth, framerate, nframes, comptype, compname)
    params = object.getparams()
    nchannels, sampwidth, framerate, nframes, comptype, compname = params[:6]
    

    nchannels, sampwidth, framerate, nframes, comptype, compname 等方法可以单独返回 wav 文件的特定的信息。

    readframes:读取声音数据,传递一个参数指定需要读取的长度 (以取样点为单位),readframes 返回的是二进制数据 (bytes),在 Python 中用字符串表示二进制数据。

    # Reads and returns at most n frames of audio, as a bytes object.
    str_data = object.readframes(nframes)
    # nframes = 17504,  channels = 2, sampwidth = 2
    # str_data (bytes: 70016) = nframes * channels * sampwidth = 17504 * 2 * 2 = 70016
    

    接下来需要根据声道数和量化单位,将读取的二进制数据转换为一个可以计算的数组:

    wave_data = np.fromstring(str_data, dtype=np.short)
    

    通过 fromstring 函数将字符串转换为数组,通过其参数 dtype 指定转换后的数据格式,由于我们的声音格式是以两个字节表示一个取样值,因此采用 short 数据类型转换。现在得到的 wave_data 是一个一维的 short 类型的数组,但是因为我们的声音文件是双声道的,因此它由左右两个声道的取样交替构成:LRLRLRLR....LR (L 表示左声道的取样值,R 表示右声道取样值)。修改wave_datasharp 之后:

    wave_data.shape = -1, 2
    

    将其转置得到:

    wave_data = wave_data.T
    

    最后通过取样点数和取样频率计算出每个取样的时间:

    time = np.arange(0, nframes) * (1.0 / framerate)
    

    4. sample width in bytes

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    # yongqiang cheng
    
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    
    import wave
    import numpy as np
    import matplotlib.pyplot as plt
    
    # WAV file
    audio_file = "/mnt/f/yongqiang_work/ding.wav"
    object = wave.open(audio_file, "rb")
    
    # (nchannels, sampwidth, framerate, nframes, comptype, compname)
    params = object.getparams()
    nchannels, sampwidth, framerate, nframes, comptype, compname = params[:6]
    print("nchannels =", nchannels)
    print("sampwidth =", sampwidth)
    print("framerate =", framerate)
    print("nframes =", nframes)
    print("comptype =", comptype)
    print("compname =", compname)
    
    # Returns number of audio channels (1 for mono, 2 for stereo).
    print("object.getnchannels() =", object.getnchannels())
    
    # Returns sample width in bytes.
    print("object.getsampwidth() =", object.getsampwidth())
    
    # Returns sampling frequency.
    print("object.getframerate() =", object.getframerate())
    
    # Returns number of audio frames.
    print("object.getnframes() =", object.getnframes())
    
    # Returns compression type ('NONE' is the only supported type).
    print("object.getcomptype() =", object.getcomptype())
    
    # Human-readable version of getcomptype(). Usually 'not compressed' parallels 'NONE'.
    print("object.getcompname() =", object.getcompname())
    
    # Reads and returns at most n frames of audio, as a bytes object.
    str_data = object.readframes(nframes)
    # nframes = 17504,  channels = 2, sampwidth = 2
    # str_data (bytes: 70016) = nframes * channels * sampwidth = 17504 * 2 * 2 = 70016
    num_bytes = len(str_data) # num_bytes = 70016
    print("num_bytes =", num_bytes, "bytes")
    object.close()
    
    wave_data = np.fromstring(str_data, dtype=np.short)
    wave_data.shape = -1, 2
    wave_data = wave_data.T
    time = np.arange(0, nframes) * (1.0 / framerate)
    
    plt.subplot(211)
    plt.plot(time, wave_data[0])
    plt.xlabel("left channel - time (seconds)")
    plt.subplot(212)
    plt.plot(time, wave_data[1], c="g")
    plt.xlabel("right channel - time (seconds)")
    plt.show()
    
    
    /home/yongqiang/miniconda3/envs/pt-1.4_py-3.6/bin/python /home/yongqiang/pytorch_work/end2end-asr-pytorch-example/yongqiang.py
    nchannels = 2
    sampwidth = 2
    framerate = 44100
    nframes = 17504
    comptype = NONE
    compname = not compressed
    object.getnchannels() = 2
    object.getsampwidth() = 2
    object.getframerate() = 44100
    object.getnframes() = 17504
    object.getcomptype() = NONE
    object.getcompname() = not compressed
    num_bytes = 70016 bytes
    
    Process finished with exit code 0
    

    在这里插入图片描述

    在这里插入图片描述

    在这里插入图片描述

    References

    http://bigsec.net/b52/scipydoc/wave_pyaudio.html

    展开全文
  • 1. 读取WAV声音文件

    千次阅读 2012-11-18 09:05:36
    1. 读取WAV声音文件 [plain] view plaincopy % wavread(filename) 读取一个WAVE文件,并返回采样数据到向量y中,Fs表示采样频率, bits表示采样位数 [y, Fs, bits] = wavread('drum.wav');   %假设...
    1. 读取WAV声音文件
    [plain] view plaincopy
    % wavread(filename) 读取一个WAVE文件,并返回采样数据到向量y中,Fs表示采样频率, bits表示采样位数  
    [y, Fs, bits] = wavread('drum.wav');  
     
    %假设声音文件有两个声道,我们只分析第一个声道,如果要分析第二个声道可以改为:ft=y(:,2);  
    ft = y(:,1);  
    sigLength = length(ft); %获取声音长度  
     
    %可以使用sound函数来播放声音  
    sound(y, Fs, bits)  

    >> left = y(:,1);
    >> leftSigLength = length(left)

    leftSigLength =

          106764

    >> sound(y, Fs, bits)
    >> ydown10=y./10;
    >> sound(ydown10, Fs, bits)
    >> yup10=y.*10;
    >> sound(yup10, Fs, bits)
    >> sound(ydown10, Fs, bits)
    >> sound(y, Fs, bits)
    >> sound(yup10, Fs, bits)
    >> sound(y, Fs, bits)
    >> sound(ydown10, Fs, bits)
    >> yleftHirightLow=[yup10(:,1);ydown10(:,1)];
    >> yleftHirightLow=[yup10(:,1),ydown10(:,1)];
    >> sound(yleftHirightLow, Fs, bits)
    >> sound(yleftHirightLow, Fs, bits)
    >> yleftLowrightHi=[ydown10(:,1),yup10(:,1)];
    >> sound(yleftLowrightHi, Fs, bits)
    >>
    >> wavwrite(ydown10,Fs,'ydown10.wav');
    >> wavwrite(yup10,Fs,'yup10.wav');
    Warning: Data clipped during write to file:yup10.wav
    > In wavwrite>PCM_Quantize at 248
      In wavwrite>write_wavedat at 272
      In wavwrite at 114
    >> wavwrite(yleftHirightLow,Fs,'yleftHirightLow.wav');
    Warning: Data clipped during write to file:yleftHirightLow.wav
    > In wavwrite>PCM_Quantize at 248
      In wavwrite>write_wavedat at 272
      In wavwrite at 114
    >> wavwrite(yleftLowrightHi,Fs,'yleftLowrightHi.wav');
    Warning: Data clipped during write to file:yleftLowrightHi.wav
    > In wavwrite>PCM_Quantize at 248
      In wavwrite>write_wavedat at 272
      In wavwrite at 114
    >>
    展开全文
  • 使用DirectX播放wav声音文件

    千次阅读 2017-11-17 19:14:58
    再次运行项目,就可以听到.wav文件播放出的声音了 代码如下 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System....

    1.    使用 DirectX ,主要用到 MicroSoft.DirectX.dll 和 Microsoft.Directx.DirectSound.dll。

            a. 可以下载安装DirectX,下载地址https://www.microsoft.com/en-us/download/details.aspx?id=6812

                 然后添加引用MicroSoft.DirectX.dll和Microsoft.Directx.DirectSound.dll。

            b. 也可以直接下载dll文件,下载地址https://www.dllme.com/dll/download/7588/Microsoft.DirectX.dll

    2.    安装DirectX SDK时,无法安装成功,遇到 Error Code : S1023,  打开文件 C:\Users\用户名\AppData\Local\Temp\Microsoft Visual C++ 2010  x86             Redistributable .html

              

         也就是说: VS已经安装了更高版本的Microsoft Visual C++ 2010 Redistributable ,所以导致无法成功安装DirectX SDK,在控制面板中卸载高版本的 这个文件,重新安装directX SDK 即可。

    3.    安装完成后,新建一个winform项目,添加引用MicroSoft.DirectX.dll 和 Microsoft.Directx.DirectSound.dll, 却无法找到这个两个dll文件, 实际上这  两  个dll文件不在安装目录下。在C:\Windows\Microsoft.NET\DirectX for Managed Code\  ..文件下可以找到各个版本的DirectX.dll    


             


              


    将这两文件添加引用即可。

     4   开始写代码

              (1).引入DirectX 的DLL文件的名字空间:

    using Microsoft.DirectX;
    using Microsoft.DirectX.DirectSound;

      (2)建立设备。在Microsoft.DirectX.DirectSound空间中,有个Device的类。这个是表示系统中的声音设备。

    Device dev=new Device();

      (3).设置CooperativeLevel。因为windows是多任务的系统,设备不是独占的,所以在使用设备前要为这个设备设置CooperativeLevel。调用Device的SetCooperativeLevel方法:其中,第一个参数是一个Control,可以用this代替,第二个参数是个枚举类型,设置优先级。         

    dev.SetCooperativeLevel(this,CooperativeLevel.Normal);

      (4).开辟缓冲区。系统中,一个设备有唯一的主缓冲区。由于windows是多任务,所以可以有几个程序同时利用一个设备播放声音,所以每个程序都自己开辟一个二级缓冲区,播放自己的声音。
      系统根据各个程序的优先级别,按照相应的顺序分别去各个二级缓冲区中读取内容到主缓冲区中播放。
      其中,第一个参数表示(要播放的.wav)文件名,第二个就是需要使用的设备。

    SecondaryBuffer buf=new SecondaryBuffer("hello.wav",dv);

      (5).接下来就可以播放啦。第一个参数表示优先级别,0是最低的。第2个参数是播放方式,这里是循环播放。

    buf.Play(0,BufferPlayFlags.Looping);

      代码完成,可以编译运行了。

      5.     运行项目时,debug模式下报出异常 

           Mixed mode assembly is built against version 'v1.1.4322' of the runtime and cannot be loaded in the 4.0 runtime without additional configuration information.

    解决方案:
            https://stackoverflow.com/questions/14508627/mixed-mode-assembly-is-built-against-version-2-0-50727-of-the-runtime-and-cann

    项目--->右键------>add new Item----->App config file  即添加App.config文件,文件中输入下面内容。
    <?xml version="1.0" encoding="utf-8" ?> 
    <configuration> 
      <startup useLegacyV2RuntimeActivationPolicy="true"> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> 
      </startup> 
    </configuration> 

      

      再次运行项目,就可以听到.wav文件播放出的声音了吐舌头

    代码如下

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
    using Microsoft.DirectX;
    using Microsoft.DirectX.DirectSound;
    namespace directXTest
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                Device dev = new Device();//系统中的声音设备。
                dev.SetCooperativeLevel(this, CooperativeLevel.Normal);// 设置设备优先级。
                SecondaryBuffer buf = new SecondaryBuffer("music.wav", dev);//wav文件可以放在debug文件下。
                buf.Play(0, BufferPlayFlags.Looping);
            }
        }
    }
    







       



    展开全文
  • 画出wav文件声音数据的波形曲线

    千次阅读 2013-03-25 17:34:47
    WAV文件格式 波形音频文件(*.WAV)是Microsoft为Windows设计的多媒体文件格式RIFF(The Resource Interchange File Format,资源交换文件格式)中的一种(另一种常用的为AVI)。RIFF由文件头、数据类型标识及若干块...

         WAV文件格式

    波形音频文件(*.WAV)是Microsoft为Windows设计的多媒体文件格式RIFF(The Resource Interchange File Format,资源交换文件格式)中的一种(另一种常用的为AVI)。RIFF由文件头、数据类型标识及若干块(chunk)组成。
     
    WAV文件的基本格式
    内容
    变量名
    大小
    取值
    RIFF头文件标识符串fileId4B“RIFF”
    头后文件长度fileLen4B非负整数(=文件长度-8)
    数据类型标识符波形文件标识符waveId4B“WAVE”
    格式块块头格式块标识符串chkId4B

    “fmt ”

    头后块长度chkLen4B非负整数(= 16或18)
    块数据格式标记wFormatTag2B非负短整数(PCM=1)
    声道数wChannels2B非负短整数(= 1或2)
    采样率dwSampleRate4B非负整数(单声道采样数/秒)
    平均字节率dwAvgBytesRate4B非负整数(字节数/秒)
    数据块对齐wBlockAlign2B非负短整数(不足补零)
    采样位数wBitsPerSample2B非负短整数(PCM时才有)
    扩展域大小wExtSize2B非负短整数可选(根据chkLen=16or 18判断)
    扩展域extraInfo

    extSize B

    扩展信息
    数据块块头数据块标识符串chkId4B

    “data”

    头后块长度chkLen4B非负整数
    块数据波形采样数据x或xl、xr

    chkLen B

    左右声道样本交叉排列
    样本值为整数(整字节存储,不足位补零),
    整个数据块按blockAlign对齐
     
    注意:

           wFormatTag = 1时为无压缩的PCMPulse Code Modulation, 脉冲编码调制)标准格式(即等间隔采样、线性量化)。

          单字节样本值v为无符号整数(0~255),实际样本值应为v-128;多字节样本值本身就是有符号的,可直接使用。

    有些wav文件在data块之前,fmt块之后还有一个fact块..

    |  ID    |  4 Bytes |   'fact'          |
            ----------------------------------
          | Size  |  4 Bytes |   数值为4    |
           ----------------------------------
          | data  |  4 Bytes |  ?? ?? ?? ??  | 

    因此要根据读到的ID进行判断

    参考: http://www.snowcn.net/?action/viewspace/itemid/260.html  wav文件格式分析详解


    Wav文件 所有数值表示均为低字节表示低位,高字节表示高位。

    通过CArchive的>>读入, 会自动转化(把高字节的作为高位)

    如读入地址为0000000的双字(DWORD)到变量dw中 :

    0000000: 52 49 46 46 

    则dw会等于0x46464952

     
    为了简化RIFF文件中的4字符标识的读写与比较,Windows SDK在多媒体头文件mmsystem.h中定义了类型
    FOURCC(Four-Character Code四字符代码):

    typedef DWORD FOURCC;

    及其构造宏(用于将4个字符转换成一个FOURCC数据)

    FOURCC mmioFOURCC(CHAR ch0, CHAR ch1, CHAR ch2, CHAR ch3);

    其定义为MAKEFOURCC宏:

    #define  mmioFOURCC(ch0, ch1, ch2, ch3)  MAKEFOURCC(ch0, ch1, ch2, ch3);

    而MAKEFOURCC宏定义为:

    #define MAKEFOURCC(ch0, ch1, ch2, ch3)  /

        ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) |  /

        ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ));

    例如:

    #include <mmsystem.h>

    #define ID_RIFF    mmioFOURCC('R', 'I', 'F', 'F')

    #define ID_WAVE   mmioFOURCC('W', 'A', 'V', 'E')

    ……

    FOURCC id;

    ……

                  ar >> id;

                  if (id != ID_RIFF) {

           ……

    }

    ……

    l         播放波形声音文件

    函数PlaySound可以播放系统声音、声音资源和声音文件,其函数原型为:

    BOOL PlaySound(

      LPCSTR pszSound, 

      HMODULE hmod,    

      DWORD fdwSound

    );

    例如:

    PlaySound(“c://sounds//sample.wav”, NULL, SND_ASYNC);

                  PlaySound(ar.GetFile()->GetFilePath(), NULL, SND_ASYNC);

     

    下面是完整步骤:

    新建MFC应用程序, 单文挡(SDI)项目WavePlayer.

    为了使包含PlaySound的程序能够编译通过,必须包含多媒体头文件: #include <mmsystem.h>, 而且需要注意头文件包含的次序.. 否则会提示找不到标识符..

    并在项目中添加多媒体库:在项目区中任何页中选中顶部的项目名,选“项目/属性”菜单项或按Alt+F7组合键,弹出“[项目名]属性页”对话框,在该其左上角的“配置”栏的下拉式列表中,选择“所有配置”项,在其左边的“配置”目录栏中,选中“配置属性/链接器/输入”项,在右边顶行的“附加依赖项”栏中键入winmm.lib,按“确定”钮关闭对话框。

     

    文件过滤

    可通过修改资源视图页的“项目名/项目名.rc/String Table/String Table”串表资源中的ID:IDR_MAINFRAME(SDI)所对应的串,为应用程序的文件I/O对话框增加文件过滤器。为WavePlayer程序增加*.wav的过滤器:

    将原来的串

    IDR_MAINFRAME  “WavePlayer/n/nWavePlayer/n/n/nWavePlayer.Document/nWavePlayer.Document”

    修改成

    “WavePlayer/n/nWavePlayer/nWave Files (*.wav)/n.wav/nWavePlayer.Document/nWavePlayer.Document”

     

     

    文档类cpp 添加如下宏

    #define ID_RIFF mmioFOURCC('R''I''F''F')

    #define ID_WAVE mmioFOURCC('W''A''V''E')

    #define ID_data mmioFOURCC('d''a''t''a')

    #define ID_fmt  mmioFOURCC('f''m''t',  '/x20')

    #define ID_fact mmioFOURCC('f''a''c',  't')

     

     

    文档类添加如下变量

    public:

        int num;         // 样本数

        LONG* data;      // 样本数据

        LONG *Ldata, *Rdata;     // 双声道数据

        WORD BytesPerSample, wChannel;     // 一个样本的字节数,  声道数

     

    Serialize函数添加如下代码:

    if  (ar.IsStoring())

        
    {

            
    // TODO: 在此添加存储代码

        }


        
    else

        
    {

            
    // TODO: 在此添加加载代码

            FOURCC id, chkLen,  dw;    
    // 无符号双字

            BYTE b;               
    // 无符号字节

            WORD w;              
    // unsined short  无符号单字长

            WORD fmtTag;           
    //格式标记

            WORD wBitsPerSample;   
    //样本位数

            FOURCC dwAvgBytesRate;  

            FOURCC Len;          
    // 数据块大小,  BYTE

            ar
    >>id;

            
    if(id!=ID_RIFF)  return;

            ar
    >>dw>>id;

            
    if(id!=ID_WAVE) return;

            ar
    >>id; if(id!=ID_fmt)  return;

            ar
    >>chkLen;            // 16或

            ar
    >>fmtTag;            // 只处理PCM(Pulse Code Modulation, 脉冲编码调制)情况

            
    if(fmtTag!=1)

                
    return;

            ar
    >>wChannel;           //声道数

            ar
    >>dw;                 //采样率

            ar
    >>dwAvgBytesRate;     //平均字节率

            ar
    >>w;                  //数据块对齐

            ar
    >>wBitsPerSample;     //样本位数

            
    if(chkLen==18)

            
    {

                ar
    >>w;               // 扩展域大小

                
    for(int i=0; i<w; i++)  // 读走扩展域的内容

                    ar
    >>b;

            }


            ar
    >>id;            // data or fact

            
    if(id==ID_fact)

            
    {

                ar
    >>dw>>dw;        // 读走fact块内容

                ar
    >>id;    //      data  ID

            }


            
    if(id!=ID_data)

                
    return;

            ar
    >>Len;          

            BytesPerSample
    =wBitsPerSample/8;         // 一个样本的字节数

            num
    =Len/BytesPerSample;              // 样本数

            
    if(wChannel==1)                 // 单音道

            
    {

                data
    =new LONG[num];

                
    if(BytesPerSample==1)

                    
    for(int i=0; i<num; i++)

                    
    {

                        ar
    >>b;

                        data[i]
    =b-128;

                    }


                
    else if(BytesPerSample==2)

                    
    for(int i=0; i<num; i++)

                    
    {

                        ar
    >>w;

                        data[i]
    = (SHORT)w;         // 无符号数转成有符号数

                    }


                
    else if(BytesPerSample==4)

                    
    for(int i=0; i<num; i++)

                    
    {

                        ar
    >>dw;

                        data[i]
    =(LONG)w;          // 无符号数转成有符号数

                    }


                
    else if(BytesPerSample==3)

                    
    for(int i=0; i<num; i++)

                    
    {

                        ar
    >>b>>w;

                        data[i]
    =w+b;

                    }


            }


            
    else if(wChannel==2)             // 双音道

            
    {

                Ldata
    =new LONG[num/2];     // 左声道

                Rdata
    =new LONG[num/2];      // 右声道

                
    if(BytesPerSample==1)

                
    {

                    
    for(int i=0; i<num/2; i++)  // 一个声道的样本数为num/2, 左右声道交替

                    
    {

                        ar
    >>b;            

                        Ldata[i]
    =b-128;        

                        ar
    >>b;

                        Rdata[i]
    =b-128;

                    }


                }


                
    else if(BytesPerSample==2)

                    
    for(int i=0; i<num/2; i++)

                    
    {

                        ar
    >>w;

                        Ldata[i]
    =(SHORT)w;         // 无符号数转成有符号数

                        ar
    >>w;

                        Rdata[i]
    =(SHORT)w;

                    }


                
    else if(BytesPerSample==4)

                    
    for(int i=0; i<num/2; i++)

                    
    {

                        ar
    >>dw;

                        Ldata[i]
    =(LONG)dw;

                        ar
    >>dw;

                        Rdata[i]
    =(LONG)dw;

                    }


                
    else if(BytesPerSample==3)

                    
    for(int i=0; i<num/2; i++)

                    
    {

                        ar
    >>b>>w;

                        Ldata[i]
    =w+b;

                        ar
    >>b>>w;

                        Rdata[i]
    =w+b;

                    }


            }


            PlaySound(ar.GetFile()
    ->GetFilePath(), NULL, SND_ASYNC);  // 播放声音

        }


     

     

    视图类OnDraw函数添加如下代码:

    CRect rect;                 //  客户区大小

        GetClientRect(
    & rect);        

        CPen gpen(PS_SOLID, 
    1 , RGB( 0 250 0 ));           //  绿色笔

        pDC
    -> SelectObject( & gpen);

        
    if (pDoc -> data != NULL  ||  pDoc -> Ldata != NULL)         //  数据非空时才画

        
    {

            
    float A=pow(2.08.0*pDoc->BytesPerSample-1);  // 将样本的高度映射到所需高度,

                                                           
    // 先算出样本的最大值

            
    if(pDoc->wChannel==1)                         // 单声道

            
    {  

                
    int x=0, y=rect.Height()/2;               

                
    while(x < rect.Width())         

                
    {

                    
    int min=INT_MAX, max=INT_MAX+1;      // 让min初始为最大的int, 让max初始化最小的int

                    
    // 一个象素x映射(样本数/客户区宽度)个样本点, 用其中最大最小值, 画一竖直的线段

                    
    for(int j=x*pDoc->num/rect.Width(); j<(x+1)*pDoc->num/rect.Width(); j++)

                    
    {

                        
    if(pDoc->data[j]<min)

                            min
    =pDoc->data[j];

                        
    if(pDoc->data[j]>max)

                            max
    =pDoc->data[j];

                    }


                    pDC
    ->MoveTo(x, y+(max*rect.Height()/2.0/A));

                    pDC
    ->LineTo(x, y+(min*rect.Height()/2.0/A));

                    x
    ++;

                }


                CPen pen(PS_SOLID, 
    1, RGB(20000));          // 客户区中间画一横线

                pDC
    ->SelectObject(&pen);

                pDC
    ->MoveTo(0, rect.Height()/2);

                pDC
    ->LineTo(rect.Width(), rect.Height()/2);    

            }


            
    else if(pDoc->wChannel==2)

            
    {

                
    // 在客户区上半部分画左声道, 原理同单声道,

                
    int x=0, y=rect.Height()/4;

                
    while(x<rect.Width())

                
    {

                    
    int min=INT_MAX, max=INT_MAX+1;

                    
    for(int j=x*pDoc->num/2/rect.Width(); j<(x+1)*pDoc->num/2/rect.Width(); j++)

                    
    {

                        
    if(pDoc->Ldata[j]<min)

                            min
    =pDoc->Ldata[j];

                        
    if(pDoc->Ldata[j]>max)

                            max
    =pDoc->Ldata[j];

                    }


                    pDC
    ->MoveTo(x, y+(max*rect.Height()/4.0/A));

                    pDC
    ->LineTo(x, y+(min*rect.Height()/4.0/A));

                    x
    ++;

                }


                
    // 在客户区下半部分画右声道

                x
    =0, y=3*rect.Height()/4;

                
    while(x<rect.Width())

                
    {

                    
    int min=INT_MAX, max=INT_MAX+1;

                    
    for(int j=x*pDoc->num/2/rect.Width(); j<(x+1)*pDoc->num/2/rect.Width(); j++)

                    
    {

                        
    if(pDoc->Rdata[j]<min)

                            min
    =pDoc->Rdata[j];

                        
    if(pDoc->Rdata[j]>max)

                            max
    =pDoc->Rdata[j];

                    }


                    gpen.DeleteObject();

                    gpen.CreatePen(PS_SOLID, 
    1, RGB(25500));

                    pDC
    ->SelectObject(&gpen);

                    pDC
    ->MoveTo(x, y+(max*rect.Height()/4.0/A));

                    pDC
    ->LineTo(x, y+(min*rect.Height()/4.0/A));

                    x
    ++;

                }


                
    // 画客户区中央横线

                CPen pen(PS_SOLID, 
    1, RGB(000));

                pDC
    ->SelectObject(&pen);

                pDC
    ->MoveTo(0, rect.Height()/2);

                pDC
    ->LineTo(rect.Width(), rect.Height()/2);

     

               

                pen.DeleteObject();

                pen.CreatePen(PS_SOLID, 
    1, RGB(00255));

                pDC
    ->SelectObject(&pen);

                
    // 画左声道横线

                pDC
    ->MoveTo(0, rect.Height()/4);

                pDC
    ->LineTo(rect.Width(), rect.Height()/4);

                
    // 右声道横线

                pDC
    ->MoveTo(03*rect.Height()/4);

                pDC
    ->LineTo(rect.Width(), 3*rect.Height()/4);

            }


        }

    OnDraw 用到了pow函数, 添加头文件包含指令

    #include<cmath>      // double pow(double, double);

    展开全文
  • 前言 本次毕业设计的初步设想是想通过C语言解析并提取出wav格式文件的相关元数据,然后设计一种...WAV是最常见的声音文件格式之一,是微软公司专门为Windows开发的一种标准数字音频文件,该文件能记录各种单声道或...
  • wav文件文件

    千次阅读 2012-09-18 14:50:22
    wav文件文件头 wave文件的格式: 00H 4 char "RIFF"标志 04H 4 long int 文件长度 08H 4 char "WAVE"标志 0CH 4 char "fmt"标志 10H 4 过渡字节(不定) 14H 2 int 格式类别(10H为PCM形式的...
  • 数字化波形声音wav文件浅析

    千次阅读 2017-04-17 17:26:13
    —windows下一种通用格式叫做RIFF(资源互换文件格式),wav文件也是RIFF格式支持的音频文件结构。 RIFF基本结构图 wav文件格式归纳 注:本图摘自北京电子科技学院学报第12卷第2期举例分析在网上下载了一段12...
  • WAV文件

    2017-04-13 16:43:11
    本文从定义、格式、特点等三个方面对WAV文件进行了简单地描述。
  • 在计算之前,我们要知道一下wav文件中的三个参数 采样频率、音频通道数、每次采样得到的样本位数 ,这三个参数用来表示声音,同时决定了wav文件的音质,大小。下面简单介绍一下这三个参数。采样频率 指每秒钟取得...
  • WAV文件格式解析

    万次阅读 2017-04-16 15:31:02
    本文通过翻译分析了WAV的...WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持。
  • wav文件详解

    2019-02-11 09:30:27
    wav文件详解
  • wav文件格式

    2017-06-15 16:53:34
    WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范,用于保存Windows平台的音频信息资源,被Windows平台及其应用程序所广泛支持,该格式也支持MSADPCM,...
  • WAV文件格式简称WAV格式是一种存储声音波形的数字音频格式,是由微软公司和IBM联合设计的,WAV文件还原而成的声音的音质取决于声音卡采样样本的尺寸,采样频率越高,音质就越好,但开销就越大,WAV文件也就
  • WAV文件作为最经典的Windows多媒体音频格式,应用非常广泛,使用三个参数来表示声音:采样位数、采样频率和声道数;Windows Media Player和Winamp都可以播放。本文环境:windows10系统、thinkpad t480电脑。WAV文件...
  • WAV文件格式

    2017-04-17 17:56:04
    WAV文件格式
  • wav文件分析

    2017-05-02 14:45:55
     WAV音频文件格式,是微软和IBM的音频文件格式存储在pc上的音频码流标准。 它是一个应用程序的资源交换文件格式( riff )码流格式方法将数据存储在" chunks "。 它主要是用于Windows系统,通常为无压缩音频格式。 ...
  • wav音频文件解析

    2021-05-14 14:29:59
      Waveform Audio File Format(WAVE,又或者是因为WAV后缀而被大众所知的)是最常见的声音文件格式之一,是微软公司专门为Windows开发的一种标准数字音频文件,该文件能记录各种单声道或立体声的声音信息,并能...
  • WAV 文件格式分析

    千次阅读 2017-04-11 12:28:50
     波形音频文件格式 (WAV / WAVE)是Microsoft开发的一种数字化声音文件格式,用于在PC上存储音频比特流,文件扩展名为“*.wav”。  WAV文件采用RIFF文件格式结构,即具有特定的容器格式。RIFF文件结构由“块”...
  • wav文件格式解析

    千次阅读 2017-04-29 16:42:36
    WAV文件本身由三个“块”信息组成:将文件标识为WAV文件的RIFF块,识别采样率等参数的FORMAT块和包含实际数据(样本)的DATA块。 WAV文件格式说明 采样率:声音信号在“模数转换”过程中单位时间内采样...
  • WAV文件分析

    千次阅读 2017-04-16 15:54:39
    WAV为微软公司(Microsoft)开发的一种声音文件格式,它符合RIFF(Resource Interchange File Format)文件规范。一个RIFF文件的开始部分是由一系列的数据块(data chunks)组成的头部文件。一个WAVE文件通常就是一个包含...
  • Qt 之 WAV文件解析

    千次阅读 2016-10-10 15:25:05
    简介最近看了一下Qt的处理音频方面的资料,本身利用QAudioInput 和 QAudioOutput 就可以实现录音和播放功能,代码也很简单,但是录音生成的文件并不能用播放器打开,就算更改后缀名也无法识别(有时候下载的一些音频...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 10,208
精华内容 4,083
关键字:

wav表示声音文件