基于开源库speexdsp, 可以简单实现重采样。
简单实现的代码如下:
需要的三方库: speexdsp ,libsndfile
#include <stdlib.h>
#include <sndfile.h>
#include <speex_resampler.h>
#define BUFFER_SIZE 2048
int main(int argv, const char *args[]) {
if (argv != 4) {
printf("usage: %s <input file path> <to samplerate> <output file path> \n", args[0]);
return 1;
}
const char *in_path = args[1];
int output_sr = atoi(args[2]);
const char *out_path = args[3];
SF_INFO info;
SNDFILE *in = sf_open(in_path, SFM_READ, &info);
if (!in) {
fprintf(stderr, "cannot open file %s\n", in_path);
return 2;
}
SF_INFO onfo;
onfo.channels = 1;
onfo.samplerate = output_sr;
onfo.format = SF_FORMAT_WAV | SF_FORMAT_PCM_16 ;
onfo.sections = 0;
onfo.seekable = 1;
SNDFILE *out = sf_open(out_path, SFM_WRITE, &onfo);
if (!out) {
fprintf(stderr, "cannot open file %s\n", out_path);
sf_close(in);
return 2;
}
int err = 0;
SpeexResamplerState *resampler = speex_resampler_init(info.channels, info.samplerate, output_sr, 1, &err);
printf("=====================\nchannels: %d\nsample rate:%d\n", info.channels, info.samplerate);
if (info.channels != 1) {
fprintf(stderr, "only support mono wav.\n");
sf_close(in);
sf_close(out);
return 3;
}
short in_buffer[BUFFER_SIZE] = {0};
uint32_t size = BUFFER_SIZE * output_sr/ info.samplerate;
printf("new buffer size: %d\n", size);
short *out_buffer = (short *) calloc(size, sizeof(short));
uint32_t read = 0;
do {
read = sf_read_short(in, in_buffer, BUFFER_SIZE);
err = speex_resampler_process_int(resampler, 0, (const spx_int16_t *)in_buffer, (spx_uint32_t *)&read, (spx_int16_t *)out_buffer, &size);
if (err) {
fprintf(stderr, "err:%d\n", err);
}
sf_write_short(out, out_buffer, size);
} while(read>0);
free(out_buffer);
sf_close(in);
sf_close(out);
return 0;
}
上述代码只在centos上编译测试,不过后来也有移植到windows下的。
如果需要成品的可以在这里下载windows版本,有需要可以自取。
https://download.youkuaiyun.com/download/mimiduck/12465600