java pcm 重采样_简洁明了的插值音频重采样算法例子 (附完整C代码)

#ifdef __cplusplusextern "C"{#endif

#define _CRT_SECURE_NO_WARNINGS#include#include#include

//采用https://github.com/mackron/dr_libs/blob/master/dr_wav.h 解码

#define DR_WAV_IMPLEMENTATION#include"dr_wav.h"

void resampler(char *in_file, char *out_file);//写wav文件

void wavWrite_int16(char *filename, int16_t *buffer, intsampleRate, uint32_t totalSampleCount) {

drwav_data_format format;

format.container= drwav_container_riff; //

format.format = DR_WAVE_FORMAT_PCM; //

format.channels = 1;

format.sampleRate=(drwav_uint32) sampleRate;

format.bitsPerSample= 16;

drwav*pWav = drwav_open_file_write(filename, &format);if(pWav) {

drwav_uint64 samplesWritten=drwav_write(pWav, totalSampleCount, buffer);

drwav_uninit(pWav);if (samplesWritten !=totalSampleCount) {

fprintf(stderr,"ERROR\n");

exit(1);

}

}

}//读取wav文件

int16_t *wavRead_int16(char *filename, uint32_t *sampleRate, uint64_t *totalSampleCount) {

unsignedintchannels;

int16_t*buffer = drwav_open_and_read_file_s16(filename, &channels, sampleRate, totalSampleCount);if (buffer ==NULL) {

printf("读取wav文件失败.");

}//仅仅处理单通道音频

if (channels != 1) {

drwav_free(buffer);

buffer=NULL;*sampleRate = 0;*totalSampleCount = 0;

}returnbuffer;

}//分割路径函数

void splitpath(const char *path, char *drv, char *dir, char *name, char *ext) {const char *end;const char *p;const char *s;if (path[0] && path[1] == ':') {if(drv) {*drv++ = *path++;*drv++ = *path++;*drv = '\0';

}

}else if(drv)*drv = '\0';for (end = path; *end && *end != ':';)

end++;for (p = end; p > path && *--p != '\\' && *p != '/';)if (*p == '.') {

end=p;break;

}if(ext)for (s = end; (*ext = *s++);)

ext++;for (p = end; p >path;)if (*--p == '\\' || *p == '/') {

p++;break;

}if(name) {for (s = p; s

}if(dir) {for (s = path; s

}

}void resampleData(const int16_t *sourceData, int32_t sampleRate, uint32_t srcSize, int16_t *destinationData,

int32_t newSampleRate) {if (sampleRate ==newSampleRate) {

memcpy(destinationData, sourceData, srcSize* sizeof(int16_t));return;

}

uint32_t last_pos= srcSize - 1;

uint32_t dstSize= (uint32_t) (srcSize * ((float) newSampleRate /sampleRate));for (uint32_t idx = 0; idx < dstSize; idx++) {float index = ((float) idx * sampleRate) /(newSampleRate);

uint32_t p1=(uint32_t) index;float coef = index -p1;

uint32_t p2= (p1 == last_pos) ? last_pos : p1 + 1;

destinationData[idx]= (int16_t) ((1.0f - coef) * sourceData[p1] + coef *sourceData[p2]);

}

}void resampler(char *in_file, char *out_file) {//音频采样率

uint32_t sampleRate = 0;//总音频采样数

uint64_t totalSampleCount = 0;

int16_t*data_in = wavRead_int16(in_file, &sampleRate, &totalSampleCount);

int16_t*data_out = (int16_t *) malloc(totalSampleCount * 2 * sizeof(int16_t));//如果加载成功

if (data_in != NULL && data_out !=NULL) {

resampleData(data_in, sampleRate, (uint32_t) totalSampleCount, data_out, sampleRate* 2);

wavWrite_int16(out_file, data_out,sampleRate* 2, (uint32_t) totalSampleCount * 2);free(data_in);free(data_out);

}else

{if(data_in) free(data_in);if(data_out) free(data_out);

}

}int main(int argc, char *argv[]) {

printf("Audio Processing\n");

printf("博客:http://tntmonks.cnblogs.com/\n");

printf("音频插值重采样\n");if (argc < 2)return -1;char *in_file = argv[1];char drive[3];char dir[256];char fname[256];char ext[256];char out_file[1024];

splitpath(in_file, drive, dir, fname, ext);

sprintf(out_file,"%s%s%s_out%s", drive, dir, fname, ext);

resampler(in_file, out_file);

getchar();

printf("按任意键退出程序 \n");return 0;

}

#ifdef __cplusplus

}#endif

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值