WAV格式头文件信息介绍与C读取实现
单片机 wav原理
单片机 wav原理
单片机 wav原理是指利用单片机实现wav音频文件的播放和录制功能。
wav是一种无损音频编码格式,广泛应用于音频文件的存储和传输。
通过单片机可以实现对wav文件的读取、解码和输出,从而实现音频的播放。
单片机 wav原理的实现主要包括以下几个步骤:
1. 文件读取:单片机需要通过外部存储介质(如SD卡)读取wav 文件。
通过SPI或I2C等通信协议,单片机可以与外部存储介质进行数据交互,读取wav文件的音频数据和相关信息。
2. 解码处理:单片机读取到wav文件后,需要对文件进行解码处理。
解码过程将音频数据从数字形式转换为模拟形式,以便于音频信号的输出。
3. 数字模拟转换:单片机通过DAC芯片将数字音频数据转换为模拟信号。
DAC芯片将数字信号转换为模拟电压或电流输出,通过耳机、扬声器等输出设备播放音频。
4. 输出控制:单片机可以通过PWM技术调节输出音频信号的幅度和频率,实现音量和音调的控制。
通过PWM输出,可以驱动功放芯片或者直接驱动扬声器,使音频以合适的音量输出。
单片机wav原理的实现需要充分利用单片机的计算和IO控制能力,
对音频数据进行处理和输出。
同时,为了提高音质和播放效果,还需要对音频数据进行滤波、均衡等处理,以达到更好的效果。
总结:单片机 wav原理是通过单片机实现对wav音频文件的读取、解码和输出,实现音频的播放功能。
通过合理的硬件设计和软件编程,可以实现高质量的音频输出效果。
单片机wav原理的实现对于嵌入式音频应用具有重要意义,广泛应用于音频播放器、语音识别、语音合成等领域。
C语言音频处理音频读取处理和播放的技巧
C语言音频处理音频读取处理和播放的技巧音频处理是计算机科学领域的一个重要分支,它涉及到音频信号的获取、处理和播放。
在C语言中,可以利用各种库和技巧来实现音频的读取、处理和播放。
本文将介绍一些C语言中常用的音频处理技巧,帮助读者更好地理解和应用音频处理的方法。
一、音频读取技巧1. 使用库文件:C语言中常用的音频读取库文件有libsndfile、libsndfile、PortAudio等。
这些库文件提供了方便的API接口,可以实现从音频文件中读取数据。
2. 了解音频文件格式:在进行音频读取操作前,先要了解所使用的音频文件的格式,比如WAV、MP3、FLAC等。
不同格式的音频文件在存储数据和读取方式上有所不同,需要根据文件格式进行相应的处理。
3. 使用文件指针:通过使用C语言中的文件指针,可以打开音频文件并读取其中的数据。
可以使用fopen()函数打开文件,使用fread()函数读取文件中的数据,并使用fclose()函数关闭文件。
二、音频处理技巧1. 音频采样率的调整:音频采样率是指音频每秒钟采集的样本数,常见的采样率有44.1kHz、48kHz等。
通过控制采样率,可以调整音频的播放速度和音质。
2. 音频音量的调整:通过对音频信号进行放大或缩小的操作,可以调整音频的音量。
可以通过调整音频的幅度或者应用数字信号处理的技术实现音量的调整。
3. 音频滤波:音频滤波是指对音频信号进行滤波处理,去除不需要的频率成分。
可以使用低通滤波器、高通滤波器、带通滤波器等进行音频滤波操作,以改善音频的质量。
三、音频播放技巧1. 使用库文件:在C语言中,可以使用SDL、OpenAL等音频播放库文件来实现音频的播放。
这些库文件提供了方便的接口函数,可以实现音频的播放和控制。
2. 使用多线程:为了保证音频播放的流畅性,在进行音频播放时可以考虑使用多线程。
将音频播放操作放在一个独立的线程中进行,可以避免音频播放对其他操作的阻塞。
C语言解析WAV音频文件
C语⾔解析WAV⾳频⽂件C语⾔解析WAV⾳频⽂件代码地址:⽬录在计算机中有着各式各样的⽂件,⽐如说EXE这种可执⾏⽂件,JPG这种图⽚⽂件,也有我们平时看的TXT,或者C,CPP,PHP等代码⽂件。
如果把这些⽂件⽤记事本或者其他纯⽂本编辑器打开,会发现前⾯这类⽂件打开之后基本上都是乱码,也就是⾮⼈类可读的字符,⽽后⾯这类代码或者TXT⽂件打开之后都是⼈类可读的字符串。
如果我们把这些⽂件统⼀做⼀个分类,那么前⾯的EXE,JPG之类的这种打开之后都是我们看不懂的外星球⽂字的⽂件叫做⼆进制⽂件,⽽后⾯那些⽂件可以称为是⽂本⽂件。
后⾯那种分类是⽂本⽂件很好理解,毕竟都是我们认识的⽂本⽂字,但是前⾯的那些乱码为什么叫他⼆进制⽂件呢?这些⼆进制⽂件是怎么被计算机识别的,为什么这些乱码就能被计算机识别,并且放出悠扬动听的⾳乐或者栩栩如⽣的图⽚呢?我们学编程,搞计算机的⼈能不能也⾃⼰写⼀个程序把这些数据解析出来呢?请跟听本专栏栏猪⼀起慢慢道来。
前⾔我们将⼀步⼀步来了解C语⾔的⼀些基本库的使⽤,以及如何使⽤这些库来解析⼀个wav格式的⾳频⽂件,将其中的元数据(也就是该⾳频⽂件的⼀些属性)提取出来。
因此您需要有基本的计算机基础知识以及了解C语⾔,最好还对⾳频或者信号处理感兴趣。
了解WAV⾳频⽂件下⾯是百度百科的解释WAV为微软公司(Microsoft)开发的⼀种声⾳⽂件格式,它符合RIFF(Resource Interchange File Format)⽂件规范,⽤于保存Windows平台的⾳频信息资源,被Windows平台及其应⽤程序所⼴泛⽀持,该格式也⽀持MSADPCM,CCITT A LAW等多种压缩运算法,⽀持多种⾳频数字,取样频率和声道,标准格式化的WAV⽂件和CD格式⼀样,也是44.1K的取样频率,16位量化数字,因此在声⾳⽂件质量和CD相差⽆⼏! WAV打开⼯具是WINDOWS的媒体播放器。
通常使⽤三个参数来表⽰声⾳,量化位数,取样频率和采样点振幅。
C#获取WAVE文件文件头信息
C#获取WAVE文件文件头信息C#获取WAVE文件文件头信息前些日子在论坛里问了,没人回答,今天有空自己写了一下文件格式依据网站using System;using System.IO;using System.Text;namespace WAV{/// <summary>/// Summary description for Wav./// </summary>public class Wav{public Wav(){//// TODO: Add constructor logic here//}[STAThread]static void Main(string[] args){//// TODO: Add code to start application here//string strpath=@"C:\Documents and Settings\Administrator\桌面\trojan\怀念战友.wav";//=@"F:\Music";if(args.Length>0){strpath=args[0].Trim();}if(File.Exists(strpath)){GetWavInfo(strpath);Console.WriteLine("GetWavInfo Successfully!");//Console.WriteLine("");}else{Console.Write("Please Enter the write filepath!\n");Console.Write("用法: WAV [Full Path Of Your WAV filepath]");}}public struct WavInfo{public string groupid;public string rifftype;public long filesize;public string chunkid;public long chunksize;public short wformattag; //记录着此声音的格式代号,例如WAVE_FORMAT_PCM,WAVE_F0RAM_ADPCM等等。
WAV文件读取
WAV⽂件读取WAV是⼀种以RIFF为基础的⽆压缩⾳频编码格式,该格式以Header、Format Chunk及Data Chunk三部分构成。
本⽂简要解析了各部分的构成要素,概述了如何使⽤C++对⽂件头进⾏解析以及提取⾳频数据。
上图展⽰了WAV⽂件格式,包括每⼀field的⼤⼩与端序HeaderChunkID: 4字节⼤端序。
⽂件从此处开始,对于WAV或AVI⽂件,其值总为“RIFF”。
ChunkSize: 4字节⼩端序。
表⽰⽂件总字节数减8,减去的8字节表⽰ChunkID与ChunkSize本⾝所占字节数。
Format: 4字节⼤端序。
对于WAV⽂件,其值总为“WAVE”Format ChunkSubchunk1ID: 4字节⼤端序。
其值总为“fmt ”,表⽰Format Chunk从此处开始。
Subchunk1Size: 4字节⼩端序。
表⽰Format Chunk的总字节数减8。
AudioFormat: 2字节⼩端序。
对于WAV⽂件,其值总为1。
NumChannels: 2字节⼩端序。
表⽰总声道个数。
SampleRate: 4字节⼩端序。
表⽰在每个通道上每秒包含多少帧。
ByteRate: 4字节⼩端序。
⼤⼩等于SampleRate * BlockAlign,表⽰每秒共包含多少字节。
BlockAlign: 2字节⼩端序。
⼤⼩等于NumChannels * BitsPerSample / 8,表⽰每帧的多通道总字节数。
BitsPerSample: 2字节⼩端序。
表⽰每帧包含多少⽐特。
Data ChunkSubchunk2ID: 4字节⼤端序。
其值总为“data”,表⽰Data Chunk从此处开始。
Subchunk2Size: 4字节⼩端序。
表⽰data的总字节数。
data:⼩端序。
表⽰⾳频波形的帧数据,各声道按帧交叉排列。
使⽤C++解析WAV⽂件⽂件头结构定义结构体WaveHeader来保存WAV⽂件头,即Header、Format Chunk及Data Chunk的⾮data部分,此外在该结构体中添加了num_frame 字段,⽤来保存⽂件总帧数,由于Header、Format Chunk与Data Chunk之间可能有其他说明信息,所以还添加了start_pos字段⽤来保存真正的data开始的位置。
C读取wav
用基本的C语言文件操作库函数实现的Wave文件读取的实例代码,可以跨Windows和Linux平台#include <stdio.h>#include <stdlib.h>#include <string.h>// define Wave format structuretypedef struct tWAVEFORMATEX{short wFormatTag; /* format type */short nChannels; /* number of channels (i.e. mono, stereo...) */unsigned int nSamplesPerSec; /* sample rate */unsigned int nAvgBytesPerSec; /* for buffer estimation */short nBlockAlign; /* block size of data */short wBitsPerSample; /* number of bits per sample of mono data */short cbSize; /* the count in bytes of the size of *//* extra information (after cbSize) */} WAVEFORMATEX, *PWAVEFORMATEX;char* wavread(char *fname, WAVEFORMATEX *wf);int main(){char fname[] = "test.wav";char *speech;WAVEFORMATEX wf;speech = wavread(fname, &wf);// afterward processing...return 0;}// read wave filechar* wavread(char *fname, WAVEFORMATEX *wf){FILE* fp;char str[32];char *speech;unsigned int subchunk1size; // head sizeunsigned int subchunk2size; // speech data size// check format typefp = fopen(fname,"r");if(!fp){fprintf(stderr,"Can not open the wave file: %s.\n",fname);return NULL;}fseek(fp, 8, SEEK_SET);fread(str, sizeof(char), 7, fp);str[7] = '\0';if(strcmp(str,"WAVEfmt")){fprintf(stderr,"The file is not in WAVE format!\n");return NULL;}// read format headerfseek(fp, 16, SEEK_SET);fread((unsigned int*)(&subchunk1size),4,1,fp);fseek(fp, 20, SEEK_SET);fread(wf, subchunk1size, 1, fp);// read wave datafseek(fp, 20+subchunk1size, SEEK_SET);fread(str, 1, 4, fp);str[4] = '\0';if(strcmp(str,"data")){fprintf(stderr,"Locating data start point failed!\n");return NULL;}fseek(fp, 20+subchunk1size+4, SEEK_SET);fread((unsigned int*)(&subchunk2size), 4, 1, fp); speech = (char*)malloc(sizeof(char)*subchunk2size); if(!speech){fprintf(stderr, "Memory alloc failed!\n");return NULL;}fseek(fp, 20+subchunk1size+8, SEEK_SET);fread(speech, 1, subchunk2size, fp);fclose(fp);return speech;}。
用C写的读取WAV文件信息
#include "stdlib.h"#include "stdio.h"void main(){int i; //用作循环计数unsigned char ch[100]; //用来存储wav文件的头信息FILE *fp;fp=fopen("1.wav","rb");//为读,打开一个wav文件if((fp=fopen("1.wav","rb"))==NULL) //若打开文件失败,退出{printf("can't open this file\n");exit(0);}/**********输出wav文件的所有信息**********/printf("该wav文件的所有信息:");for(i=0;i<58;i++){ch[i]=fgetc(fp); //每次读取一个字符,存在数组ch中if(i%16==0) //每行输出16个字符对应的十六进制数printf("\n");if(ch[i]<16) //对小于16的数,在前面加0,使其用8bit显示出来printf("0%x ",ch[i]);elseprintf("%x ",ch[i]);}/*********RIFF WAVE Chunk的输出*********/printf("\n\nRIFF WA VE Chunk信息:");//输出RIFF标志printf("\nRIFF标志:");for(i=0;i<4;i++){printf("%x ",ch[i]);}//输出size大小printf("\nsize:ox");for(i=7;i>=4;i--) //低字节表示数值低位,高字节表示数值高位{if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出W AVE标志printf("\nWA VE标志:");for(i=8;i<12;i++){if(ch[i]<16)printf("0%x ",ch[i]);elseprintf("%x ",ch[i]);}/*******Format Chunk的输出*******/ printf("\n\nFormat Chunk信息:"); //输出fmt 标志printf("\nfmt 标志:");for(i=12;i<16;i++){if(ch[i]<16)printf("0%x ",ch[i]);elseprintf("%x ",ch[i]);}//输出size段printf("\nsize:ox");for(i=19;i>15;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出编码方式printf("\n编码方式:ox");for(i=21;i>19;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出声道数目printf("\n声道数目:ox");for(i=23;i>21;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}if(ch[i+1]==1) //1表示单声道,2表示双声道printf(" 单声道");elseprintf(" 双声道");//输出采样频率printf("\n采样频率:ox");for(i=27;i>23;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出每秒所需字节数printf("\n每秒所需字节数:ox");for(i=31;i>27;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出数据块对齐单位printf("\n数据块对齐单位:ox");for(i=33;i>31;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出每个采样所需bit数printf("\n每个采样所需bit数:ox");for(i=35;i>33;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出附加信息if(ch[16]==18) //若Format Chunk的size大小为18,则该模块的最后两个字节为附加信息{ //若为16,则无附加信息printf("\n附加信息:ox");for(i=37;i>35;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}}/*******Fact Chunk的输出*******/printf("\n\nFact Chunk信息:");//输出fact标志printf("\nfact标志:");for(i=38;i<42;i++){if(ch[i]<16)printf("0%x ",ch[i]);elseprintf("%x ",ch[i]);}//输出sizeprintf("\nsize:ox");for(i=45;i>41;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}//输出data段数据printf("\ndata段数据:");for(i=46;i<50;i++){if(ch[i]<16)printf("0%x ",ch[i]);elseprintf("%x ",ch[i]);}/*******Data Chunk的输出*******/ printf("\n\nData Chunk信息:"); //输出data标志printf("\ndata标志:");for(i=50;i<54;i++){if(ch[i]<16)printf("0%x ",ch[i]);elseprintf("%x ",ch[i]);}//输出数据大小printf("\n数据大小:ox");for(i=57;i>53;i--){if(ch[i]<16)printf("0%x",ch[i]);elseprintf("%x",ch[i]);}printf("\n");fclose(fp);}。
wav音频文件格式分析与数据获取
wav音频文件格式分析与数据获取作者:罗海涛来源:《电脑知识与技术》2016年第27期摘要:音频文件是把语音信号离散化的数字文件,wav格式的音频文件是常用的二进制音频格式,广泛应用于语音信号处理、语音识别、语音合成等领域;本文详细分析了wav音频文件格式,并用C语言编程,实现对该格式文件的访问,获取音频信息和数据。
关键字:wav;音频文件;音频信息;音频数据中图分类号:TP37 文献标识码:A 文章编号:1009-3044(2016)27-0211-031 概述语言是人们之间进行通讯和交流必不可少的手段。
语音由人的发音器官发出,语音信号是连续的模拟信号,在用计算机来处理时,需要进行数字化,包括采样、量化等过程,转换成离散的数字信号,保存在音频文件中。
现在很多领域要求对语音信号中的音频数据进行进一步的加工和处理。
例如,利用读出的音频信号数据,进行语音信号时域和频域分析、语音压缩、语音编码、解码、语音合成、语音识别、语音增强等,并通过波形观察比较不同编码效果。
另外,利用多媒体语音系统我们还可以用语音数据和波形方便地进行噪声模拟分析,语音特征提取研究,以及语音识别和训练等应用方面的实验。
又如:在人工智能领域,通过设计软件和硬件电路,用声音去控制计算机工作,还有机器人通过语音与人进行简单的对话交流等等。
这些都要求我们对数字语音信号进行一些必要的加工处理。
wav文件格式是一种重要的数字音频文件格式,是目前应用很广泛的一种音频格式。
相比于其他格式如MP3、MP4、RAM等压缩效率更高的音频文件格式,wav文件没有采用压缩技术,因而其文件要大很多,一般都在几兆字节,甚至更大。
但也正因为没有采用压缩技术,wav文件中声音的采样数据很容易被读出来,便于做其他处理。
例如:画出声音的信号波形、作出频谱,进行时域、频域分析,提取语音信号的特征参数用于语音识别等。
现在的应用程序几乎都支持wav文件格式,也有专门软件可以完成从wav文件格式向其他文件格式的转换,或者把其他格式文件转换为wav格式,例如,微软公司的Adobe Audition。
wav文件头详解,看懂wav文件
wav⽂件头详解,看懂wav⽂件⼯作中部门萌新常问的wav⽂件头格式及怎么看wav⽂件,且有时会遇到 “伪.pcm” 格式现总结如下: WAV是最常见的声⾳⽂件格式之⼀,是微软公司专门为Windows开发的⼀种标准数字⾳频⽂件,该⽂件能记录各种单声道或⽴体声的声⾳信息,并能保证声⾳不失真。
但WAV⽂件有⼀个缺点,就是它所占⽤的太⼤(每分钟的⾳乐⼤约需要12兆磁盘空间)。
它符合资源互换⽂件格式(RIFF)规范,⽤于保存Windows平台的⾳频信息资源推荐⼀个好⽤的16进制⽂件查看的⼯具:HxDx64对于完全0基础的,推荐下⾯⽹站中的详细解释,⽐较详细:(侵删)1.RIFF块(RIFF-Chunk)偏移地址字节数数据类型内容&H004String‘RIFF‘⽂件标志&H044UInteger⽂件总长&H08 4 String ‘WAVE‘⽂件标志2.格式化块(Format-Chunk)偏移地址字节数数据类型内容&H0C4String‘fmt‘标志&H104UInteger块长度&H12 2 UShort PCM格式类别&H142 UShort 声道数⽬&H184 UInteger 采样率&H1C 4 UInteger 传输速率&H1E 2UShort 数据块对齐&H202UShort 每样本bit数&H22 2UShort 可选3.附加块(Fact-Chunk) *当前块偏移地址需要根据实际数据变更偏移地址字节数数据类型内容&H264String‘fact‘标志&H2A4UInteger块长度&H2E4UInteger附加信息4.数据块(Data-Chunk) *当前块偏移地址需要根据实际数据变更偏移地址字节数数据类型内容&H324String‘data‘⽂件标志&H364UInteger数据块总长按照相关头格式,来观察字节即可Example:(取⾃上⾯博客)。
WAVE文件头信息以及PCM数据的读取(C++版本)
WA VE文件头信息以及PCM数据的读取/*************文件的处理方法**************/#include "math.h"#include <iostream>using namespace std;#define N 200 //观察前面的200点的PCM数据float *Read_Data(FILE *fp_speech,int front_info);//读取PCM数据的关键函数int main(){FILE *fp;fp=fopen("E:\\aaa.wav","rb");//为读,打开一个wav文件if((fp=fopen(""E:\\aaa.wav"","rb"))==NULL) //若打开文件失败,退出{printf("can't open this file\n");exit(0);}/*********RIFF WA VE Chunk的输出*********//****************************************RIFF WAVE Chunk==================================| |所占字节数| 具体内容|==================================| ID | 4 Bytes | 'RIFF' |----------------------------------| Size | 4 Bytes | |----------------------------------| Type | 4 Bytes | 'WA VE' |******************************************/char id_RIFF[4],type_RIFF[4];int size_RIFF;cout<<endl<<"RIFF WA VE Chunk的输出: "<<endl;//读取ID=RIFF 4字节fseek(fp,0L,0);fread(id_RIFF,sizeof(int),1,fp);cout<<"RIFF标识:"<<id_RIFF[0]<<id_RIFF[1]<<id_RIFF[2]<<id_RIFF[3]<<endl;//读取文件大小4字节fseek(fp,4L,0);fread(&size_RIFF,sizeof(int),1,fp);cout<<"文件大小:"<<size_RIFF<<endl;//读取W AVE标识4字节fseek(fp,8L,0);fread(type_RIFF,sizeof(int),1,fp);cout<<"WA VE标识:"<<type_RIFF[0]<<type_RIFF[1]<<type_RIFF[2]<<type_RIFF[3]<<endl;/*******Format Chunk的输出*******//****************************************Format Chunk================================================================== ==| | 字节数| 具体内容|================================================================== ==| ID | 4 Bytes | 'fmt ' |--------------------------------------------------------------------| Size | 4 Bytes | 数值为16或18,18则最后有附加信息|-------------------------------------------------------------------- ----| FormatTag | 2 Bytes | 编码方式,一般为0x0001 | |-------------------------------------------------------------------- || Channels | 2 Bytes | 声道数目,1--单声道;2--双声道| |-------------------------------------------------------------------- || SamplesPerSec | 4 Bytes | 采样频率| |-------------------------------------------------------------------- || AvgBytesPerSec| 4 Bytes | 每秒所需字节数| |===> W AVE_FORMA T -------------------------------------------------------------------- || BlockAlign | 2 Bytes | 数据块对齐单位(每个采样需要的字节数) | |-------------------------------------------------------------------- || BitsPerSample | 2 Bytes | 每个采样需要的bit数| |-------------------------------------------------------------------- || | 2 Bytes | 附加信息(可选,通过Size来判断有无)| |-------------------------------------------------------------------- ----******************************************/char id_FORMA T[4];int size_FORMA T,SamplesPerSec,AvgBytesPerSec;short int FormatTag,Channels,BlockAlign,BitsPerSample,addinfo;cout<<endl<<"Format Chunk的输出: "<<endl;//读取famt标识4字节fseek(fp,12L,0);fread(id_FORMA T,sizeof(int),1,fp);cout<<"fmt标识:"<<id_FORMAT[0]<<id_FORMAT[1]<<id_FORMAT[2]<<endl;//读取size 4字节//fseek(fp,16L,0);//fread(&id_FORMA T,sizeof(int),1,fp);//cout<<"size大小:"<<size_FORMA T<<endl;//编码方式2字节fseek(fp,20L,0);fread(&FormatTag,sizeof(short),1,fp);cout<<"编码方式:"<<FormatTag<<endl;//声道数2字节fseek(fp,22L,0);fread(&Channels,sizeof(short),1,fp);cout<<"声道数目:"<<Channels<<endl;//采样频率4字节fseek(fp,24L,0);fread(&SamplesPerSec,sizeof(int),1,fp);cout<<"采样频率:"<<SamplesPerSec<<endl;//每秒所需字节数4字节fseek(fp,28L,0);fread(&AvgBytesPerSec,sizeof(int),1,fp);cout<<"每秒所需字节数:"<<AvgBytesPerSec<<endl;//数据块对齐单位2字节fseek(fp,32L,0);fread(&BlockAlign,sizeof(short),1,fp);cout<<"数据块对齐单位:"<<BlockAlign<<endl;//每个采样需要的bit数2字节fseek(fp,34L,0);fread(&BitsPerSample,sizeof(short),1,fp);cout<<"每个采样需要的bit数:"<<BitsPerSample<<endl;//附加信息2字节fseek(fp,36L,0);fread(&addinfo,sizeof(short),1,fp);cout<<"附加信息:"<<addinfo<<endl;/*******Fact Chunk的输出*******//****************************************Fact Chunk==================================| |所占字节数| 具体内容|==================================| ID | 4 Bytes | 'fact' |----------------------------------| Size | 4 Bytes | 数值为4 |----------------------------------| data | 4 Bytes | |----------------------------------******************************************/char index;char id_FACT[4];int size_FACT,data_FACT;/*******Data Chunk的输出*******//****************************************Data Chunk==================================| |所占字节数| 具体内容|==================================| ID | 4 Bytes | 'data' |----------------------------------| Size | 4 Bytes | |----------------------------------| data | | |----------------------------------******************************************/char id_DATA[4];int size_DATA;float *PCMdata;//检验标识的第一个字符,判断是否存在Fact Chunk信息段,如果没有就直接输出Data 段fseek(fp,38L,0);fread(&index,sizeof(char),1,fp);if (index=='f')cout<<endl<<"Fact Chunk的输出: "<<endl;//FACT标识4字节fseek(fp,38L,0);fread(&id_FACT,sizeof(int),1,fp);cout<<"FACT标识:"<<id_FACT[0]<<id_FACT[1]<<id_FACT[2]<<id_FACT[3]<<endl;//size大小4字节fseek(fp,42L,0);fread(&size_FACT,sizeof(int),1,fp);cout<<"size大小:"<<size_FACT<<endl;//FACT段data 2字节fseek(fp,46L,0);fread(&data_FACT,sizeof(int),1,fp);cout<<"FACT段data:"<<data_FACT<<endl;/************Data Chunk的输出***************/cout<<endl<<"Data Chunk的输出: "<<endl;//DATA标识4字节fseek(fp,50L,0);fread(&id_DATA,sizeof(int),1,fp);cout<<"DATA标识:"<<id_DATA<<endl;//PCM数据长度4字节fseek(fp,54L,0);fread(&size_DATA,sizeof(int),1,fp);cout<<"PCM数据长度:"<<size_DATA<<endl;/*******以下为重要的PCM数据输出*******/fseek(fp,46L,0);PCMdata=Read_Data(fp,46);cout<<"PCM数据:"<<endl;for (int i=0;i<N;i++){cout<<PCMdata[i]<<" ";if((i+1)%5==0)cout<<endl;}}if (index=='d') //为真,则为只存在data数据段cout<<endl<<"Data Chunk的输出: "<<endl;//DATA标识4字节fseek(fp,38L,0);fread(&id_DATA,sizeof(int),1,fp);cout<<"DATA标识:"<<id_DATA[0]<<id_DA TA[1]<<id_DATA[2]<<id_DATA[3]<<endl;//PCM数据长度4字节fseek(fp,42L,0);fread(&size_DATA,sizeof(int),1,fp);cout<<"PCM数据长度:"<<size_DATA<<endl;/*******以下为重要的PCM数据输出*******/fseek(fp,46L,0);PCMdata=Read_Data(fp,46);cout<<"PCM数据:"<<endl;for (int i=0;i<N;i++){cout<<PCMdata[i]<<" ";if((i+1)%5==0)cout<<endl;}}fclose(fp);return 0;}float *Read_Data(FILE *fp_speech,int front_info){short data; //为什么用short?参看文献中的相应wav文件的pcm数据存放格式。
C++标准库实现WAV文件读写的操作
C++标准库实现WAV⽂件读写的操作在上⼀篇⽂章中对WAV的⽂件格式做了介绍,本⽂将使⽤标准C++库实现对数据为PCM格式的WAV⽂件的读写操作,只使⽤标准C++库函数,不依赖于其他的库。
WAV⽂件结构WAV是符合RIFF标准的多媒体⽂件,其⽂件结构可以如下:WAV ⽂件结构RIFF块WAVE FOURCCfmt 块fact 块(可选)data块(包含PCM数据)⾸先是⼀个RIFF块,有块标识RIFF,指明该⽂件是符合RIFF标准的⽂件;接着是⼀个FourCC,WAVE,该⽂件为WAV⽂件;fmt块包含了⾳频的⼀些属性:采样率、码率、声道等;fact 块是⼀个可选块,不是PCM数据格式的需要该块;最后data块,则包含了⾳频的PCM数据。
实际上,可以将⼀个WAV⽂件看着由两部分组成:⽂件头和PCM数据,则WAV⽂件头各字段的意义如下:本⽂实现的是⼀个能够读取PCM数据格式的单声道或者双声道的WAV⽂件,是没有fact块以及扩展块。
结构体定义通过上⾯的介绍发现,WAV的头⽂件所包含的内容有两种:RIFF⽂件格式标准中需要的数据和关于⾳频格式的信息。
对于RIFF⽂件格式所需的信息,声明结构体如下:// The basic chunk of RIFF file formatstruct Base_chunk{FOURCC fcc; // FourCC iduint32_t cb_size; // 数据域的⼤⼩Base_chunk(FOURCC fourcc): fcc(fourcc){cb_size = 0;}};chunk是RIFF⽂件的基本单元,⾸先⼀个4字节的标识FOURCC,⽤来指出该块的类型;cb_size则是改块数据域中数据的⼤⼩。
⽂件头中另⼀个信息则是⾳频的格式信息,实际上是frm chunk的数据域信息,其声明如下:// Format chunk data fieldstruct Wave_format{uint16_t format_tag; // WAVE的数据格式,PCM数据该值为1uint16_t channels; // 声道数uint32_t sample_per_sec; // 采样率uint32_t bytes_per_sec; // 码率,channels * sample_per_sec * bits_per_sample / 8uint16_t block_align; // ⾳频数据块,每次采样处理的数据⼤⼩,channels * bits_per_sample / 8uint16_t bits_per_sample; // 量化位数,8、16、32等uint16_t ex_size; // 扩展块的⼤⼩,附加块的⼤⼩Wave_format(){format_tag = 1; // PCM format dataex_size = 0; // don't use extesion fieldchannels = 0;sample_per_sec = 0;bytes_per_sec = 0;block_align = 0;bits_per_sample = 0;}Wave_format(uint16_t nb_channel, uint32_t sample_rate, uint16_t sample_bits):channels(nb_channel), sample_per_sec(sample_rate), bits_per_sample(sample_bits)format_tag = 0x01; // PCM format databytes_per_sec = channels * sample_per_sec * bits_per_sample / 8; // 码率block_align = channels * bits_per_sample / 8;ex_size = 0; // don't use extension field};关于各个字段的信息,在上⾯图中有介绍,这⾥主要说明两个字段:format_tag表⽰以何种数据格式存储⾳频的sample值,这⾥设置为0x01表⽰⽤PCM格式,⾮压缩格式,不需要fact块。
VC++中播放声音wav
VC++中播放声音wav本文链接:https:///sky04/article/details/7696003因为只需在Windows上执行,先想到用MCI接口。
试了一下,用mciSendCommand可以实现基本的播放wav文件的功能。
但循环播放wav就麻烦了,必须向窗口传送MM_MCINOTIFY消息。
google了一下,才发现原来有更简单的方法——用sndPlaySound。
一条语句sndPlaySound(filename, SND_ASYNC | SND_LOOP)就可以循环播放声音文件,完全满足我的要求。
简单吧。
函数定义是:BOOL sndPlaySound(LPCSTR lpszSound, UINT fuSound);其中,lpszSound一般是wav文件的文件名,fuSound是参数。
常见的fuSound参数有:SND_ASYNC 异步播放,即程序不等播放结束就继续执行,播放背景声。
SND_SYNC 同步播放,即播放结束才继续执行SND_LOOP 循环播放SND_NODEFAULT 如果找不到指定文件,保持安静。
如不指定此参数,则播放系统默认警告音。
如没有默认警告音,则为失败。
执行成功返回TRUE,失败返回FALSE。
要停止播放只需再执行一遍lpszSound参数为NULL的sndPlaySound函数。
要求:程序要加入Mmsystem.h,编译时链入Winmm.lib库。
限制:sndPlaySound只能播放wav文件。
wav文件在播放前将被装入内存,所以不能太大。
只能同时播放一个声音。
后一个声音会关闭前一个声音。
函数PlaySound是sndPlaySound的增强版,支持更多声音类型和fuSound参数,并可以播放内存和资源中的声音。
或者增加以下:#include <Mmsystem.h>#pragma comment(lib, "Winmm.lib")PlaySound(...)第一种方法是直接播出声音文件,相应的代码为:PlaySound("c:\win95\media\The Microsoft Sound.wav", NULL, SND_FILENAME | SND_ASYNC);注意参数中的路径使用两个连续的反斜杠转义代表一个反斜杠。
VC中使用低级音频函数WaveX播放声音文件
VC中使用低级音频函数WaveX播放声音文件王结太2004.08.08---------------------------------------------------------------------------------------------------------------------文章摘要:本文讨论并实现了在VC++中使用低级音频函数WaveX播放声音文件的方法。
--------------------------------------------------------------------------------------------------------------------- Windows通过高级音频函数、媒体控制接口MCI设备驱动程序;低级音频函数MIDI Mapper、低级音频设备驱动;以及DirectSound提供了音频服务,可以从声卡获取音频流。
1. 播放声音文件的其它方法在介绍wavex系列之前,我先来介绍之外的其它几种方法:1.1 MCI方法简介用MCI方法是很方便的,它对媒体设备控制主要通过命令接口函数mciSendCommand()或者字符串接口函数mciSendString()来完成的,这两个函数的作用相同。
命令接口函数比命令字符串使用起来要复杂,但它为MCI提供了更为强大的控制能力,两个接口函数的原型:MCIERROR mciSendCommand(MCIDEVICEID IDDevice,UINT uMsg,DWORD fdwCommand,DWORD dwParam);MCIERROR mciSendString(LPCTSTR lpszCommand, LPTSTR lpszReturnString, UINT cchReturn, HANDLE hwndCallback);比如要使用mciSendCommand方法,我们先在MCI_OPEN_PARMS中设置要播放的文件并发送MCI_OPEN 命令打开声音设备,发送MCI_PLAY命令消息播放,结束后发送MCI_STOP命令关闭设备。
C语言中的音频处理和音频编解码技术
C语言中的音频处理和音频编解码技术音频处理是计算机科学领域中的一个重要分支,它涉及到对音频信号进行捕获、处理、分析和合成等多个方面。
在C语言中,我们可以利用各种音频处理库和编程技术来实现音频处理功能。
本文将介绍C语言中常用的音频处理和编解码技术。
一、音频处理库1.1 WAV文件格式处理:WAV是一种常见的音频文件格式,它使用PCM编码来存储音频数据。
我们可以使用C语言中的音频处理库来读取、写入和处理WAV文件。
其中,libsndfile是一个强大的音频处理库,它提供了一系列的函数来访问和处理WAV文件。
1.2 FFT和频谱分析:FFT(快速傅里叶变换)是一种常用的数字信号处理算法,可以将时域的音频信号转换为频域的频谱分析。
在C语言中,我们可以利用开源的FFT库,如FFTW(快速傅里叶变换库),实现音频信号的频谱分析和处理。
1.3 滤波器设计和应用:在音频处理中,滤波器是一种常用的处理工具,它可以通过改变音频信号的频率响应来实现降噪、增强音频特定频率的功能。
在C语言中,我们可以使用数字滤波器设计库,如IIR和FIR滤波器设计库,来设计和应用各种类型的滤波器。
二、音频编解码技术2.1 压缩编码:音频编解码是将音频信号从原始数据压缩成更小的格式,以便于存储和传输。
目前最常用的音频编码格式包括MP3、AAC和OGG等。
在C语言中,我们可以利用音频编解码库,如libavcodec(FFmpeg)库,实现音频编解码功能。
2.2 编码器参数设置:音频编解码器通常具有许多参数,可以通过设置这些参数来调整编码和解码的质量和性能。
在C语言中,我们可以使用音频编解码库提供的API来设置编码器的参数,例如比特率、声道数、采样率等。
2.3 实时音频流处理:实时音频流处理是音频编解码的一种应用场景,它要求对实时音频数据进行解码和处理,并在实时性要求较高的场景下输出。
在C语言中,我们可以利用音频编解码库提供的API和技术,如缓冲队列、多线程编程等,实现实时音频流的处理和输出。
wav文件的文件头信息详解
wav⽂件的⽂件头信息详解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形式的声⾳数据) 16H 2 int 通道数,单声道为1,双声道为2 18H 2 int 采样率(每秒样本数),表⽰每个通道的播放速度, 1CH 4 long int 波形⾳频数据传送速率,其值为通道数×每秒数据位数×每样本的数据位数/8。
播放软件利⽤此值可以估计缓冲区的⼤⼩。
20H 2 int 数据块的调整数(按字节算的),其值为通道数×每样本的数据位值/8。
播放软件需要⼀次处理多个该值⼤⼩的字节数据,以便将其值⽤于缓冲区的调整。
22H 2 每样本的数据位数,表⽰每个声道中各个样本的数据位数。
如果有多个声道,对每个声道⽽⾔,样本⼤⼩都⼀样。
24H 4 char 数据标记符"data" 28H 4 long int 语⾳数据的长度楼主的帖⼦,⽂件头长度加起来是42字节,但是实际长度是44个字节(⽤UltraEdit打开⼀个WAVE⽂件,数⼀下就知道了)。
如果⽤以个结构体来定义WAVE⽂件头应该为: struct WAVEFILEHEADER { char chRIFF[4]; DWORD dwRIFFLen; char chWAVE[4]; char chFMT[4]; DWORD dwFMTLen; PCMWAVEFORMAT pwf; char chDATA[4]; DWORD dwDATALen; };但是实际测试,并不是所有的wave⽂件头都⼀样。
⽐较⿇烦的就是windows下⾃带的那个录⾳机录下的wav,⽂件头有58个Byte。
C语言如何应用于音频处理?
C语言如何应用于音频处理?在当今数字化的时代,音频处理技术在众多领域都发挥着重要作用,如音乐制作、语音识别、音频特效等。
而 C 语言,作为一种经典的编程语言,在音频处理中也有着广泛的应用。
要理解 C 语言在音频处理中的应用,首先需要了解音频数据的基本概念。
音频数据本质上是一系列随时间变化的数字信号,这些数字代表了声音的各种特性,如振幅、频率、相位等。
在计算机中,音频通常以特定的格式进行存储和处理,常见的有 WAV、MP3 等格式。
C 语言在音频处理中的一个重要应用是音频文件的读取和写入。
通过使用 C 语言的文件操作函数,如`fopen`、`fread`、`fwrite` 等,可以打开音频文件,读取其中的数据,并进行相应的处理,处理完成后再将结果写回到新的文件中。
例如,对于 WAV 格式的音频文件,其文件头包含了音频的一些基本信息,如采样率、声道数、位深度等。
使用 C 语言可以读取这些信息,并根据其来正确解析后续的音频数据。
在音频数据的处理方面,C 语言能够实现各种算法来对音频进行修改和优化。
比如,可以进行音频的滤波处理。
滤波可以去除或增强特定频率范围内的信号成分。
常见的滤波器有低通滤波器、高通滤波器、带通滤波器等。
通过 C 语言实现这些滤波器的算法,可以改变音频的频率特性,实现诸如降噪、音频均衡等效果。
再比如,音频的压缩也是音频处理中的一个重要环节。
通过 C 语言,可以实现一些音频压缩算法,如 MP3 压缩算法。
在压缩过程中,需要对音频数据进行分析和编码,以减少数据量,同时尽量保持音频的质量。
另外,C 语言还可以用于音频的实时处理。
在一些需要实时响应的应用场景,如音频直播、实时语音通信等,C 语言的高效性能可以确保音频数据的及时处理和传输。
通过使用操作系统提供的底层接口,如音频驱动接口,C 语言程序可以直接获取音频输入设备采集到的数据,并进行实时处理后输出到音频输出设备。
在音频特效的实现上,C 语言也大有用武之地。
WAV格式头文件信息介绍与C读取实现
二、具体介绍 RIFF WAVE Chunk
==================================
|
|所占字节数| 具体内容 |
==================================
| ID | 4 Bytes | 'RIFF' |
----------------------------------
-----------------------------------------------------------
----------
|
取样 1 | 取样 2 |
| 单声道 |------------------------
--------------------------------
| 16bit 量化 | 声道 0
Fact Chunk
==================================
|
|所占字节数| 具体内容 |
==================================
基于c语言的wav文件读写程序
实现 wav 文件的数据结构…………………............……04
程序的具体实现………………….............................……05
程序流程图……………….....................................………05
软件测试…………………….........................................…06
源程序清单………………….....................................……08
第 2 页 共 13 页
《软件技术基础》2014 实验报告_031220725_闫冬
一、综述
WAV 格式是微软公司开发的一种声音文件格式,也叫波形声音文件,是最早的数字音频格式,被 Windows 平台及其应用程序广泛支持。WAV 来源于对声音模拟波形的采样。用不同的采样频率对声音 的模拟波形进行采样可以得到一系列离散的采样点,以不同的量化位数(8 位或 16 位)把这些采样点 的值转换成二进制数,然后存入磁盘,这就产生了声音的 WAV 文件,即波形文件。该格式记录声音的 波形,故只要采样率高、采样字节长、机器速度快,利用该格式记录的声音文件能够和原声基本一致, 质量非常高,但这样做的代价就是文件太大。 Wav 文件结构由若干 chunk(块)组成。每一个块由各自的辨识码和块大小信息为起始。以下是 各个数据块以及辨识码的介绍。 1、RIFF RIFF 是英文 Resource Interchange File Format 的缩写,是 wave 文件所使用的标准格式,作为 wav 文件的开头,紧接其后的是描述文件总大小的四字节 32 位二进制数据。 2、WAVE 辨识码 Wave 作为 wav 文件的格式说明。 3、fmt Fmt 块包含波形文件的大小、采样频率、采样位、声道数、编码格式等重要信息。描述了文件全部 的基本参数。 4、Data Data 块包以辨识码 data 开头,后接 4 字节数据表示数据块大小,存储了全部的波形采样数据。 其 中数据的排列与采样位数、声道数有密切关联。 各个数据块的存储顺序和内容由下表详细给出:
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
| BlockAlign | 2 Bytes | 数据块对齐单位(每个采样需要的字节数) |
--------------------------------------------------------------------
------------------------------------------------
| Fact Chunk(optional) |
| ID = 'fact' |
------------------------------------------------
| Data Chunk |
则最后多了2个字节的附加信息。主要由一些软件制成的wav格式中含有该2个字节的
附加信息。
结构定义如下:
struct WAVE_FORMAT
{
WORD wFormatTag;
WORD wChannels;
DWORD dwSamplesPerSec;
DWORD dwAvgBytesPerSec;
字节便是“RIFF”。
WAVE文件是由若干个Chunk组成的。按照在文件中的出现位置包括:
RIFF WAVE Chunk, Format Chunk, Fact Chunk(可选), Data Chunk。具体见下图:
------------------------------------------------
--------------------------------
| 16bit量化 | 声道0 | 声道0 | 声道0 | 声道0 |
和Size所占用的字节数,即FileLen - 8 = Size。然后是Type字段,为'WAVE',表
示是wav文件。
结构定义如下:
struct RIFF_HEADER
{
char szRiffID[4]; // 'R','I','F','F'
--------------------------------------------------------------------
图3 Format Chunk 24/26 Bytes
以'fmt '作为标示。一般情况下Size为16,此时最后附加信息没有;如果为18
Data Chunk是真正保存wav数据的地方,以'data'作为该Chunk的标示。然后是
数据的大小。紧接着就是wav数据。根据Format Chunk中的声道数以及采样bit数,
wav数据的bit位置可以分成以下几种形式:
---------------------------------------------------------------------
| |所占字节数| 具体内容 |
==================================
| ID | 4 Bytes | 'RIFF' |
----------------------------------
| Size | 4 Bytes | |
};
Fact Chunk
==================================
| |所占字节数| 具体内容 |
==================================
| ID | 4 Bytes | 'fact' |
----------------------------------
| ID = 'data' |
------------------------------------------------
图1 Wav格式包含Chunk示例
其中除了Fact Chunk外,其他三个Chunk是必须的。每个Chunk有各自的ID,位
于Chunk最开始位置,作为标示,而且均为4个字节。并且紧跟在ID后面的是Chunk大
--------------------------------------------------------------------
| Channels | 2 Bytes | 声道数目,1--单声道;2--双声道 |
--------------------------------------------------------------------
Fact Chunk是可选字段,一般当wav文件由某些软件转化而成,则包含该Chunk。
结构定义如下:
struct FACT_BLOCK
{
char szFactID[4]; // 'f','a','c','t'
DWORD dwFactSize;
| RIFF WAVE Chunk |
| ID = 'RIFF' |
| RiffType = 'WAVE' |
------------------------------------------------
| Format Chunk |
| ID = 'fmt ' |
| SamplesPerSec | 4 Bytes | 采样频率 |
--------------------------------------------------------------------
| AvgBytesPer
Sec| 4 Bytes | 每秒所需字节数 |===> WAVE_FORMAT
| BitsPerSample | 2 Bytes | 每个采样需要的bit数 |
--------------------------------------------------------------------
| | 2 Bytes | 附加信息(可选,通过Size来判断有无) |
| Size | 4 Bytes | 数值为16或18,18则最后又附加信息 |
--------------------------------------------------------------------
| FormatTag | 2 Bytes | 编码方式,一般为0x0001 |
wav音频:WAV格式头文件信息
一、综述
WAVE文件作为多媒体中使用的声波文件格式之一,它是以RIFF格式为标准的。
RIFF是英文Resource Interchange File Format的缩写,每个WAVE文件的头四个
----------------------------------
| Type | 4 Bytes | 'WAVE' |
----------------------------------
图2 RIFF WAVE Chunk 12 Bytes
以'FIFF'作为标示,然后紧跟着为size字段,该size是整个wav文件大小减去ID
| Size | 4 Bytes | |
----------------------------------
| data | | |
----------------------------------
图5 Data Chunk 8 Bytes
};
Data Chunk
==================================
| |所占字节数| 具体内容 |
==================================
| ID | 4 Bytes | 'data' |
----------------------------------
DWORD dwRiffSize;
char szRiffFormat[4]; // 'W','A','V','E' ===========================================================
| | 字节数 | 具体内容 |
====================================================================
| ID | 4 Bytes | 'fmt ' |
--------------------------------------------------------------------
小(去除ID和Size所占的字节数后剩下的其他字节数目),4个字节表示,低字节
表示数值低位,高字节表示数值高位。下面具体介绍各个Chunk内容。
PS:
所有数值表示均为低字节表示低位,高字节表示高位。