wav文件的采样频率修改(C实现)

本文介绍了wav文件的采样频率修改原理,包括采样频率的概念、奈奎斯特采样定理,以及下采样和上采样的概念。作者通过研究其他人的代码,分享了一个使用C语言实现的wav文件采样频率修改的程序,涉及到音频重采样、滤波器函数以及相关代码实现。
摘要由CSDN通过智能技术生成

实现思路

复习

(1)采样频率的概念:采样频率是指每秒钟采集音频数据的次数。例如:一个wav文件的采样频率是44100Hz,说明本文件每一秒钟采集了44100个数据点。然后每个数据点又与采样位数有关,比如当我们的采样位数是16位,则每个数据点的取值范围就是-32768~32767。当然,一个文件采样频率越高,采样位数越多,得到的音频文件效果也就会越好。
(2)采样定理(奈奎斯特采样定理):简单理解就是,采样时,采样的频率大于信号最高频率的两倍,之后就可以成功的完全恢复原本的信号。采样之后的数字信号完整地保留了原始信号中的信息。

实现思路

然后接下来我们想实现wav文件的采样频率的修改,从其概念来说,比如44100Hz要变为8000Hz,只需要原先每秒的44100个数据点变为8000个就可以了。这个叫做下采样,通过抽取的方式实现。与之对应的上采样,通过内插实现。

下面来说说我在网上查到的有关采样频率修改的资料:
1、采样频率修改又可以叫做音频重采样,相当于对原有的音频数据重新采样了一次。

2、我打算先去找个别人写好的关于wav文件采样率修改的软件,看看一般可以将wav采样率修改为多少比较合适。下载了一款名叫Cool Edit的软件,可以进行下面几种采样率的修改:
在这里插入图片描述
3、在一个http://www.pudn.com/上找到一些有关wav采样修改的代码,准备下载一些来看看别人怎么实现的。
首先来看看main.c中代码:


#include "StructData.h" //wav头文件结构体
#include "dsp_filter.h" //用到的滤波器头文件
#include <string.h>
#include <stdio.h>
  
int sampleRate=8000*UP/DOWN, bytelength=16; //AD(模拟转数字)采样频率及字长
//#define DOWN 5
//#define UP 3 
																								
short int Data_temp[IN_DATA_LEN*UP]={
   0};  //临时数据
short int low_filter_dataout[IN_DATA_LEN*UP]={
   0};  //低通滤波器数据输出
short int Out_data[IN_DATA_LEN*UP/DOWN]={
   0}; // 输出data
short int In_data[IN_DATA_LEN]={
   0}; //输入data,定为了150个数据点

short filter_coeff[FILTER_LEN]={
   0};  //滤波器系数 #define FILTER_LEN 100

//wav文件头定义并初始化
struct RIFF_HEADER m_riff={
   0}; 
struct FMT_BLOCK  m_fmt={
   0};
struct DATA_BLOCK m_data={
   0};

void DSP_low_fir(short *x,short *y,short *h,int x_length,int hn) ; //DSP低通滤波器???
																														 
void main()																																			  
{
     
   int i=0,j=0;
   int data_length=0;
   int total_data_length=0;
	
   FILE *fp,*fwav;
	

/*	
	fp=fopen("coeff1.txt","r+");
	for(i=0;i<92;i++)	// 输入输出函数
	{
		fscanf(fp,"%lf",&coeff1[i]);  //输入92个系数? 
	}
	fclose(fp);
	
	i=0;
	fp=fopen("coeff2.txt","r+");
	while(i<272)	// 输入输出函数
	{
		fscanf(fp,"%lf",&coeff2[i++]);
	}
	fclose(fp);
*/


//将浮点的滤波器系数转化为定点数系数 (定点数:数据中小数点位置固定不变的数,编程容易实现,但需要考虑溢出)

	for(i=0;i<FILTER_LEN;i++)
    {
   
      filter_coeff[i]=filter_coeff_float[i
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
可以使用采样率转换的方法,将频率高的序列采样率降低到与频率低的序列相同的采样率,然后再进行比较。具体实现可以使用数字信号处理库,如FFTW、libsndfile等库来实现。 以下是一个简单的C语言示例: ```c #include <stdio.h> #include <stdlib.h> #include <math.h> #include <sndfile.h> #define INPUT_FILE "input.wav" #define OUTPUT_FILE "output.wav" int main(int argc, char* argv[]) { SNDFILE *infile, *outfile; SF_INFO sfinfo; double *inbuf, *outbuf; int i, j, k; double ratio; /* 打开输入文件 */ infile = sf_open(INPUT_FILE, SFM_READ, &sfinfo); if (!infile) { printf("Error opening input file\n"); return -1; } /* 打开输出文件 */ outfile = sf_open(OUTPUT_FILE, SFM_WRITE, &sfinfo); if (!outfile) { printf("Error opening output file\n"); return -1; } /* 读取输入文件中的数据 */ inbuf = (double*) malloc(sfinfo.frames * sizeof(double)); sf_read_double(infile, inbuf, sfinfo.frames); /* 计算采样率的比例 */ ratio = sfinfo.samplerate / 44100.0; /* 计算输出数据的长度 */ int outlen = sfinfo.frames / ratio; /* 创建输出缓冲区 */ outbuf = (double*) malloc(outlen * sizeof(double)); /* 降采样 */ for (i = 0; i < outlen; i++) { outbuf[i] = inbuf[(int)(i * ratio)]; } /* 写入输出文件 */ sf_write_double(outfile, outbuf, outlen); /* 关闭文件 */ sf_close(infile); sf_close(outfile); /* 释放内存 */ free(inbuf); free(outbuf); return 0; } ``` 该示例使用libsndfile库,可以通过以下命令安装: ``` sudo apt-get install libsndfile1-dev ``` 使用以下命令编译并执行该示例: ``` gcc -o sample_rate_conversion sample_rate_conversion.c -lsndfile ./sample_rate_conversion ``` 该示例将输入文件采样率降低到44100Hz,并将结果输出到输出文件中。您可以根据需要修改采样率
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值