读取Wave格式语音头信息的实现
来源:互联网 发布:广西广电网络企业邮箱 编辑:程序博客网 时间:2024/05/21 01:55
/* *================================================================= * FNAME: test.cc * DESCP: <+Brief Descripation+> * CREAT: 2015-08-18 15:39:21 * LC_AT: 2015-08-18 15:45:57 * VERNO: 1.0.4 * CNOTE: <+Latest Change+> *================================================================= */#include <stdio.h>#include <stdlib.h>#include <string.h>#define FOURCC_RIFF "RIFF"#define FOURCC_WAVE "WAVE"#define FOURCC_FMT "fmt "#define FOURCC_DATA "data"#define SUPPORTED_SAMPLE_RATE_8K 8000#ifndef WAVE_FORMAT_PCM#define WAVE_FORMAT_PCM 0x0001#define WAVE_FORMAT_ALAW 0x0006#define WAVE_FORMAT_MULAW 0x0007#endif//#ifdef DEBUG//#define tDebug printf//#else /* ----- not DEBUG ----- *///#define tDebug //printf//#endif /* ----- not DEBUG ----- */#define tDebug printf/** * @brief * 获取语音文件的头信息(包含 采样点数,语音文件的编码格式,声轨数目) * @param fpWav * @param nSampleNum * @param nChanns * @param nWavType * @return * 0, WAVE文件头正常,且此时文件指针(fpWav)指向实际声音数据的起始位置 * -1, 不是RIFF格式的文件 * -2, 文件是RIFF格式的非WAVE文件 * -3, 此WAVE文件的编码格式不是 PCM,ALAW,ULAW * -4, 此WAVE文件的音轨数不是 1 也不是 2 * -5, 此WAVE文件的采样率不是 8K * -6, 此WAVE文件的采样点的大小不是 8bit 也不是16bit * -7, 此WAVE文件的具体格式 不是 8K_16BIT_PCM 也不是 8K_8BIT_ALAW */int GetWaveHeader(FILE *fpWav, int &nSampleNum, short &nChanns, short &nWavType){ nSampleNum = -1; nWavType = -1; char magic[4] = {0}; fseek(fpWav, 0L, SEEK_SET); //确保输入的文件指针 fpWav 的位置是文件的初始位置 fread((void*) magic, 4, 1, fpWav); if (0 != strncmp(FOURCC_RIFF, magic, 4)) { tDebug("[Tip] Input file is not in RIFF format\n"); return -1; } int lng = 0; fread((void*) &lng, 4, 1, fpWav); fread((void*) magic, 4, 1, fpWav); if (0 != strncmp(FOURCC_WAVE, magic, 4)) { tDebug("[Tip] Input file is not in WAVE format\n"); return -2; } //look for FOURCC_FMT/FOURCC_DATA before end of file int len = 0; short blockAlign = 0, sampleSize = 0; while (0 == feof(fpWav)) //not reach the end of this file { fread((void*) magic, 4, 1, fpWav); //read ChunkID fread((void*) &len, 4, 1, fpWav); //read ChunkSize if (0 == strncmp(FOURCC_DATA, magic, 4)) {//reach DATA Chunk,exit the while loop nSampleNum = len / (sampleSize / 8); // 声音数据的采样点数目 break; } if (0 == strncmp(FOURCC_FMT, magic, 4)) { //reach Fmt Chunk,and parse format informations fread(&nWavType, 2, 1, fpWav); // 读取数据类型,例如: PCM, ALaw,Mulaw等 if (nWavType != WAVE_FORMAT_PCM && nWavType != WAVE_FORMAT_MULAW && nWavType != WAVE_FORMAT_ALAW) { tDebug("[Tip] Only standard PCM and ALAW supported.\n"); return -3; } fread(&nChanns, 2, 1, fpWav); //Number of Channels, 单通道或双通道 if (nChanns != 1 && nChanns != 2) { tDebug("[Tip] Wave file's channels is %d,NOT SUPPORTED\n", nChanns); nChanns = -1; return -4; } fread(&lng, 4, 1, fpWav); // Sample Rate , 采样率 if (lng != SUPPORTED_SAMPLE_RATE_8K) { tDebug("[Tip] Wave file's SampleRate(SR) is %d, NOT SUPPORTED! \n", lng); return -5; } fread(&lng, 4, 1, fpWav); // 每秒的字节数。例如:8k16bit时为 8000×2=16000 fread(&blockAlign, 2, 1, fpWav); // Block align , Chunk 的对齐单位 fread(&sampleSize, 2, 1, fpWav); // Data size ,一个采样点的大小(比特数) if (sampleSize != 16 && sampleSize != 8) { tDebug("[Tip] Only 8/16 bit audio supported!\n"); return -6; } // 类型检查 if ((nWavType == WAVE_FORMAT_PCM && sampleSize != 16) || ((nWavType == WAVE_FORMAT_MULAW || nWavType == WAVE_FORMAT_ALAW) && sampleSize != 8)) { tDebug("[Tip] Only 8K_16BIT_PCM and 8K_8BIT_ALAW supported!\n"); return -7; } // 如果是扩展的RIFF格式,则"fmt "块的大小可能大于16字节 len -= 16; }//end of if (0 == strncmp(FOURCC_FMT, magic, 4)) //fmt子块多余的信息,我们不感兴趣. 直接跳过剩余的fmt字节 for (char c; len > 0; len--) { fread(&c, 1, 1, fpWav); } } return 0;}
0 0
- 读取Wave格式语音头信息的实现
- 常用语音编码的WAVE文件头格式剖析
- 常用语音编码的WAVE文件头格式剖析
- 语音编码的WAVE文件头格式剖析
- 常用语音编码的WAVE文件头格式剖析--各种编码
- 常用语音编码的WAVE文件头格式剖析--各种编码
- VB实现远程读取音频(Wave格式)的播放时间
- 嵌入式 PCM WAVE格式详解及用C语言实现wave文件的读取
- PCM WAVE格式详解及用C语言实现wave文件的读取
- WAVE头格式
- (5): 获取 Wave 文件的格式信息
- WAVE音频文件格式分析--实现C语言读写文件头
- WAVE文件的头格式(例如PCM文件)
- WAVE文件的头格式(例如PCM文件)
- Android_语音出现格式不支持的信息
- WAVE文件的头实现(例如PCM文件)
- wave文件的格式
- WAVE文件头格式剖析以及pcm2wav
- 15OJ——爱你多少年呢
- Labeling Balls POJ3687 【拓扑排序反向建边】【邻接表】
- xmpp相关资料链接
- IL指令集
- 【grub默认启动项修改方式】亲测可用
- 读取Wave格式语音头信息的实现
- Guava学习笔记:EventBus
- Flex简单小程序
- WPF控件简介
- c#通过app.manifest使程序以管理员身份运行
- Spring Mvc集合的传值
- 转:Spring使用静态工厂方法创建Bean
- 闭包中js的作用域链【scope chain】
- 1Two Sum