Simple and clear example of interpolation audio re-sampling algorithm (with complete C code), simple and clear Interpolation
In the recent period, the image algorithm and the audio algorithm were moved back and forth.
There are frequent requirements for audio sampling and transcoding.
Existing well-known open-source libraries, such as webrtc and sox,
Reading the code is really disturbing.
Audio re-sampling is actually an interpolation algorithm.
There is no big difference with the image interpolation algorithm.
Based on bilinear interpolation.
The blogger simply implements a simple re-sampling algorithm,
It is also enough for scenarios with low sampling sound quality requirements.
The codec library uses dr_wav
Https://github.com/mackron/dr_libs/blob/master/dr_wav.h
I am a little obsessive-compulsive recently, implemented in pure c.
Paste the complete code:
# Ifdef _ cplusplusextern "C" {# endif # define _ CRT_SECURE_NO_WARNINGS # include <stdio. h> # include <stdlib. h> # include <stdint. h> // use https://github.com/mackron/dr_libs/blob/master/dr_wav.h decoding # define DR_WAV_IMPLEMENTATION # include "dr_wav.h" void resampler (char * in_file, char * out_file); // write wav file void wavWrite_int16 (char * filename, int16_t * buffer, int sampleRate, uint32_t totalSampleCount) {drwav_data_forma T format; format. container = drwav_container_riff; // <-- drwav_container_riff = normal WAV files, drwav_container_w64 = Sony Wave64. format. format = DR_WAVE_FORMAT_PCM; // <-- Any of the DR_WAVE_FORMAT _ * codes. format. channels = 1; format. sampleRate = (drwav_uint32) sampleRate; format. bitsPerSample = 16; drwav * pWav = drwav_open_file_write (filename, & format); if (pWav) {drwav_uint64 samplesWritt En = drwav_write (pWav, totalSampleCount, buffer); drwav_uninit (pWav); if (samplesWritten! = TotalSampleCount) {fprintf (stderr, "ERROR \ n"); exit (1) ;}}// read the wav file int16_t * wavRead_int16 (char * filename, uint32_t * sampleRate, uint64_t * totalSampleCount) {unsigned int channels; int16_t * buffer = drwav_open_and_read_file_s16 (filename, & channels, sampleRate, totalSampleCount); if (buffer = NULL) {printf ("failed to read wav file. ") ;}// only process single channel audio if (channels! = 1) {drwav_free (buffer); buffer = NULL; * sampleRate = 0; * totalSampleCount = 0;} return buffer ;} // The split path function 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 <end;) * name ++ = * s ++; * name = '\ 0';} if (dir) {for (s = path; s <p;) * dir ++ = * s ++; * dir = '\ 0' ;}} void resampleData (const int16_t * sourceData, int32_t sampleRate, uint32_t srcSize, int16_t * destinationData, I Nt32_t newSampleRate) {if (sampleRate = newSampleRate) {memcpy (destinationData, sourceData, srcSize * sizeof (int16_t); return;} extends 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 = in Dex-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) {// audio sampling rate uint32_t sampleRate = 0; // total number of audio samples required 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 the load is successful if (Data_in! = NULL & data_out! = NULL) {resampleData (data_in, sampleRate, (bytes) totalSampleCount, data_out, sampleRate * 2); values (out_file, data_out, sampleRate * 2, (bytes) 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 ("blog: http://tntmonks.cnblogs.com/410n"); printf ("Audio interpolation sampling \ 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_out % s ", drive, dir, fname, ext); resampler (in_file, out_file); getchar (); printf ("Exit program by any key \ n"); return 0 ;} # ifdef _ cplusplus} # endif
Without comments, the code is simple and clear at a glance.
The specific process is as follows:
Load wav (drag and drop the wav file to the executable file)-> re-sample to twice the original sample-> Save wav
If you have any other questions or requirements, contact us via email.
The email address is:
Gaozhihan@vip.qq.com