近期一直不间断学习音频处理,一直也没想着要去碰音频编解码相关。
主要是觉得没什么实际的作用和意义。
不管视频编解码,图像编解码,音频编解码,都有很多组织基金在推动。
当然,在一些特定的情景下,需要用起来编解码库,
而一般这些库都会有编译困难,使用困难等等困难综合症。
图像方面,已经有stb_image,spot,freeimage等编解码库系列,做得特别赞。
https://github.com/nothings/stb/
https://github.com/r-lyeh-archived/spot
http://freeimage.sourceforge.net/index.html
当然有一段时间,jpeg的编码库也是个头疼的事情,直到tinyjpg的出现。
视频这块有libav,ffmpeg
而音频这块,就有点差强人意了。
当然dr_libs 也已经做了不少工作了。
https://github.com/mackron/dr_libs
可惜的是,他做了wav的编解码库,mp3的解码库,就是没有mp3的编码库。
而一般mp3 的编码库,大众使用最多的是lame
在一阵寻寻觅觅之后,俺找到了一个mp3的编码库。
其原官网已经成为历史资源了。
https://web.archive.org/web/20060102002813/http://www.everett9981.freeserve.co.uk/pete.htm
也是相当历史久远了。
也有人对其进行了回炉重造。
https://github.com/toots/shine
俺一直惦念着,找个时间,进行代码整合,blabla
秉承着简洁简单的态度,就这么新鲜出炉了。
在写示例代码的时候,踩了几个小坑。
贴上完整代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <string.h> 4 #include <time.h> 5 #include "timing.h" 6 #include "shine_mp3.h" 7 8 #define DR_WAV_IMPLEMENTATION 9 10 #include "dr_wav.h" 11 12 #define DR_MP3_IMPLEMENTATION 13 14 #include "dr_mp3.h" 15 16 void error(char *s); 17 18 19 int16_t *wavRead_int16(char *filename, uint32_t *sampleRate, uint32_t *channels, uint64_t *totalSampleCount) { 20 int16_t *buffer = drwav_open_and_read_file_s16(filename, channels, sampleRate, totalSampleCount); 21 if (buffer == NULL) { 22 drmp3_config pConfig; 23 float *mp3_buffer = drmp3_open_and_decode_file_f32(filename, &pConfig, totalSampleCount); 24 if (mp3_buffer != NULL) { 25 buffer = (int16_t *) calloc(*totalSampleCount, sizeof(int16_t)); 26 *channels = pConfig.outputChannels; 27 *sampleRate = pConfig.outputSampleRate; 28 if (buffer != NULL) 29 drwav_f32_to_s16(buffer, mp3_buffer, *totalSampleCount); 30 free(mp3_buffer); 31 } else { 32 printf("read file [%s] error. ", filename); 33 } 34 } 35 return buffer; 36 } 37 38 39 /* Some global vars. */ 40 char *infname, *outfname; 41 FILE *outfile; 42 int quiet = 0; 43 int stereo = STEREO; 44 int force_mono = 0; 45 46 /* Write out the MP3 file */ 47 int write_mp3(long bytes, void *buffer, void *config) { 48 return fwrite(buffer, sizeof(unsigned char), bytes, outfile) / sizeof(unsigned char); 49 } 50 51 /* Output error message and exit */ 52 void error(char *s) { 53 fprintf(stderr, "Error: %s ", s); 54 exit(1); 55 } 56 57 static void print_usage() { 58 printf("Audio Processing "); 59 printf("mp3 encoder && decoder "); 60 printf("blog: http://cpuimage.cnblogs.com/ "); 61 printf("Usage: mp3 encoder && decoder [options] <infile> <outfile> "); 62 printf("Use "-" for standard input or output. "); 63 printf("Options: "); 64 printf(" -h this help message "); 65 printf(" -b <bitrate> set the bitrate [8-320], default 64 kbit "); 66 printf(" -m force encoder to operate in mono "); 67 printf(" -c set copyright flag, default off "); 68 printf(" -j encode in joint stereo (stereo data only) "); 69 printf(" -d encode in dual-channel (stereo data only) "); 70 printf(" -q quiet mode "); 71 printf(" -v verbose mode "); 72 } 73 74 /* Use these default settings, can be overridden */ 75 static void set_defaults(shine_config_t *config) { 76 shine_set_config_mpeg_defaults(&config->mpeg); 77 } 78 79 /* Parse command line arguments */ 80 static int parse_command(int argc, char **argv, shine_config_t *config) { 81 int i = 0; 82 83 if (argc < 3) return 0; 84 85 while (argv[++i][0] == '-' && argv[i][1] != '