目录
一、API简介
二、实验
1. matlab
2. C语言
一、API简介
链接如下:
读取音频文件 - MATLAB audioread- MathWorks 中国
也可以浏览最新的英文版API说明:

简单说明如下:
1. 读取wav格式的文件,会自动跳过44个字节的文件头
2. audioread()使用来代替wavread()的,新版本的Matlab已经不再支持wavread();所以在使用的时候需要注意返回的参数:wavread()返回三个参数,而audioread()只返回两个参数,少了“位深度”这个信息。
3. audioread()读出来的音频数据流有“归一化”操作,默认是除以32768归一化每个样本点,之后用double类型空间进行存储。
例如:假设对于一个音频文件,每个样本点都是用16位来量化而得到的数字信号,一般是用short类型进行存储,用audioread()读出来后,每个样本点其实都做了归一化, 比如对于数值为-417的样本点, 读出来的值是-417/(32768.0)=0.012725830078125,约为0.01273。
4. 如果不希望归一化,则第二个参数可设置为’native’,调用形式为:
| [x,fs] = audioread('input.wav', ‘native’); | 
二、实验
假设音频源来自一个音频文件,采样率是8KHz,16bit的单声道数据。
1. matlab
[x,fs] = audioread('input.wav'); %自动跳过44个字节的文件头
fprintf('fs:%d\n', fs)
fprintf('row:%d\n', size(x, 1))%矩阵的行数
fprintf('col:%d\n', size(x, 2))%矩阵的列数
len=256;
noise_mean = zeros(len,1);
j=1;
noise_mean = x(j:j+len-1); %读取前面256个样本点
audiowrite('outFile.wav', x, fs);noise_mean这个矩阵的值如下:

假设不进行归一化操作:
[x,fs] = audioread('input.wav', 'native'); %自动跳过44个字节的文件头
fprintf('len(x):%d\n', size(x))%28019
len=256
noise_mean = zeros(len,1);
j=1;
noise_mean = x(j:j+len-1) %读取前面256个样本点
audiowrite('outFile.wav', x, fs);noise_mean这个矩阵的值如下:

注:
(1) 这就是最原始的音频数据,可以手动验算该API的“归一化数值”操作。
(2)可以直接用C语言读出,进行对比。
2. C语言
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
	int i;
	int count=0;
	FILE *fpin = fopen("input.wav", "rb");
	if (fpin == NULL) {
		printf("input data read fail\n");
		return 0;
	}
	fseek(fpin, 0, SEEK_END);
	long inputdata_length = ftell(fpin);
	//偏移,跳过文件头
	inputdata_length = inputdata_length - 44;
	inputdata_length /= 2;
	printf("input_file_len:% ld\n", inputdata_length);
	rewind(fpin);
	short* x = (short*)calloc(inputdata_length, sizeof(short));
	//偏移,跳过文件头
	fseek(fpin, 44, SEEK_SET);
	count = fread(x, sizeof(short), inputdata_length, fpin);
	printf("count:% d\n", count);
	for (i = 0; i < 256; i++) {
		printf("x_tmp[%d]=%d\n", i, x[i]);
	}
	return 0;
}打印如下:
| input_file_len: 28019 count: 28019 x[0]=-417 x[1]=-14 x[2]=-17 x[3]=-112 x[4]=1319 x[5]=1512 x[6]=-987 x[7]=-1046 x[8]=550 x[9]=342 x[10]=212 x[11]=-182 x[12]=192 x[13]=175 x[14]=-1268 x[15]=-952 x[16]=-786 x[17]=-759 x[18]=473 x[19]=950 x[20]=603 .................................................... | 
实际算法开发,为防止计算过程中,数据过大,一般也会做归一化操作。注意,读取实际音频数据长度,以及读出实际音频数据之前,都要先跨过文件头(如果是PCM格式,就不需要)。
完整示例代码:
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
	int i;
	int count=0;
	FILE *fpin = fopen("input.wav", "rb");
	if (fpin == NULL) {
		printf("input data read fail\n");
		return 0;
	}
	FILE *fpout = fopen("output.wav", "wb");
	if (fpin == NULL) {
		printf("open output file fail\n");
		return 0;
	}
	fseek(fpin, 0, SEEK_END);
	long inputdata_length = ftell(fpin);
	//偏移,跳过文件头
	inputdata_length = inputdata_length - 44;
	inputdata_length /= 2;
	printf("input_file_len:% ld\n", inputdata_length);
	rewind(fpin);
	short* x = (short*)calloc(inputdata_length, sizeof(short));
	//偏移,跳过文件头
	fseek(fpin, 44, SEEK_SET);
	count = fread(x, sizeof(short), inputdata_length, fpin);
	printf("count:% d\n", count);
//	for (i = 0; i < 256; i++) {
//		printf("x[%d]=%d\n", i, x[i]);
//	}
#if 0  /* 无数值归一化操作 */
	fwrite(x, sizeof(short), inputdata_length, fpout);
	free(x);
	fclose(fpin);
	fclose(fpout);
#else	/* 进行数值归一化操作 */
	float* x_in = (float*)calloc(inputdata_length, sizeof(float));
	short* x_out = (short*)calloc(inputdata_length, sizeof(short));
	//输入
	for(i=0; i<inputdata_length; i++) {
		x_in[i]=x[i]/32768.0;
	}
	//处理
	//输出
	for(i=0; i<inputdata_length; i++) {
		x_out[i]=(short)(x_in[i]*32768.0);
	}
	fwrite(x_out, sizeof(short), inputdata_length, fpout);
	free(x);
	free(x_in);
	free(x_out);
	fclose(fpin);
	fclose(fpout);
#endif
	return 0;
}输出的音频文件和源文件一致:




















