与《分享用于学习C++图像处理的代码示例》为姊妹篇。

为了便于学习C++音频处理并研究音频算法,

俺写了一个适合初学者学习的小小框架。

麻雀虽小五脏俱全,仅仅考虑单通道处理。

采用Decoder:dr_wav

https://github.com/mackron/dr_libs/blob/master/dr_wav.h

采用Encoder:原本计划采用dr_wav的Encode,但是dr_wav保存的文件头忘记修正音频数据的大小,

采用博主自己实现的代码,仅供学习之用。

dr_wav用于解析wav文件格式.

关于wav格式的解析移步至:

http://soundfile.sapp.org/doc/WaveFormat/

个人习惯,采用int16的处理方式,也可以通过简单的修改,改为float类型。

wav音频样本可以从维基百科上(https://en.wikipedia.org/wiki/WAV)下载。

注:少数wav格式不支持

Format Bitrate (kbit/s) 1 minute (KiB) Sample
11,025 Hz 16 bit PCM 176.4 1292 11k16bitpcm.wav
8,000 Hz 16 bit PCM 128 938 8k16bitpcm.wav
11,025 Hz 8 bit PCM 88.2 646 11k8bitpcm.wav
11,025 Hz µ-Law 88.2 646 11kulaw.wav
8,000 Hz 8 bit PCM 64 469 8k8bitpcm.wav
8,000 Hz µ-Law 64 469 8kulaw.wav
11,025 Hz 4 bit ADPCM 44.1 323 11kadpcm.wav
8,000 Hz 4 bit ADPCM 32 234 8kadpcm.wav
11,025 Hz GSM 06.10 18 132 11kgsm.wav
8,000 Hz MP3 16 kbit/s 16 117 8kmp316.wav
8,000 Hz GSM 06.10 13 103 8kgsm.wav
8,000 Hz Lernout & Hauspie SBC 12 kbit/s 12 88 8ksbc12.wav
8,000 Hz DSP Group Truespeech 9 66 8ktruespeech.wav
8,000 Hz MP3 8 kbit/s 8 60 8kmp38.wav
8,000 Hz Lernout & Hauspie CELP 4.8 35 8kcelp.wav

附带处理耗时计算,示例演示了一个简单的将音频前面一半静音处理,并简单注释了一下部分逻辑。

完整代码:

 #include <stdio.h>
 #include <stdlib.h>
 #include <stdint.h>
 #include <time.h>
 #include <iostream>
 //采用https://github.com/mackron/dr_libs/blob/master/dr_wav.h 解码
 #define DR_WAV_IMPLEMENTATION
 #include "dr_wav.h"

 auto const epoch = clock();
 static double now()
 {
     return  (clock() - epoch);
 };

 template <typename FN>
 static double bench(const FN &fn)
 {
     auto took = -now();
     ;
 }

 //写wav文件
 void wavWrite_int16(char* filename, int16_t* buffer, int sampleRate, uint32_t totalSampleCount) {

     FILE* fp = fopen(filename, "wb");
     if (fp == NULL) {
         printf("文件打开失败.\n");
         return;
     }
     //修正写入的buffer长度
     totalSampleCount *= sizeof(int16_t);
     ;
     ;
     ;
     ] = { 'R', 'I', 'F', 'F' };
     uint32_t long_number =  + totalSampleCount;
     fwrite(text, , , fp);
     fwrite(&long_number, , , fp);
     text[] = 'W';
     text[] = 'A';
     text[] = 'V';
     text[] = 'E';
     fwrite(text, , , fp);
     text[] = 'f';
     text[] = 'm';
     text[] = 't';
     text[] = ' ';
     fwrite(text, , , fp);

     long_number = ;
     fwrite(&long_number, , , fp);
     int16_t short_number = FORMAT_PCM;//默认音频格式
     fwrite(&short_number, , , fp);
     short_number = ; // 音频通道数
     fwrite(&short_number, , , fp);
     long_number = sampleRate; // 采样率
     fwrite(&long_number, , , fp);
     long_number = sampleRate * nbyte; // 比特率
     fwrite(&long_number, , , fp);
     short_number = nbyte; // 块对齐
     fwrite(&short_number, , , fp);
     short_number = nbit; // 采样精度
     fwrite(&short_number, , , fp);
     ] = { 'd', 'a', 't', 'a' };
     fwrite(data, , , fp);
     long_number = totalSampleCount;
     fwrite(&long_number, , , fp);
     fwrite(buffer, totalSampleCount, , fp);
     fclose(fp);
 }
 //读取wav文件
 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("读取wav文件失败.");
     }
     //仅仅处理单通道音频
     )
     {
         drwav_free(buffer);
         buffer = NULL;
         *sampleRate = ;
         *totalSampleCount = ;
     }
     return buffer;
 }

 //分割路径函数
 void splitpath(const char* path, char* drv, char* dir, char* name, char* ext)
 {
     const char* end;
     const char* p;
     const char* s;
     ] && path[] == ':') {
         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';
     }
 }

 int main(int argc, char* argv[])
 {
     std::cout << "Audio Processing " << std::endl;
     std::cout << "博客:http://tntmonks.cnblogs.com/" << std::endl;
     std::cout << "支持解析单通道wav格式." << std::endl;

     ) ;
     ];

     //音频采样率
     uint32_t sampleRate = ;
     //总音频采样数
     uint64_t totalSampleCount = ;
     int16_t* wavBuffer = NULL;
     double nLoadTime = bench([&]
     {
         wavBuffer = wavRead_int16(in_file, &sampleRate, &totalSampleCount);
     });
     std::cout << ) << " 毫秒" << std::endl;

     //如果加载成功
     if (wavBuffer != NULL)
     {
         //将前面一般进行静音处理,直接置零即可
         ; i < totalSampleCount / ; i++)
         {
             wavBuffer[i] = ;
         }
     }
     //保存结果
     double nSaveTime = bench([&]
     {
         ];
         ];
         ];
         ];
         ];
         splitpath(in_file, drive, dir, fname, ext);
         sprintf(out_file, "%s%s%s_out%s", drive, dir, fname, ext);
         wavWrite_int16(out_file, wavBuffer, sampleRate, totalSampleCount);
     });
     std::cout << ) << " 毫秒" << std::endl;

     getchar();
     std::cout << "按任意键退出程序 \n" << std::endl;
     ;
 }

示例具体流程为:

加载wav(拖放wav文件到可执行文件上)->简单静音处理->保存wav

并对 加载,保存 这2个环节都进行了耗时计算并输出。

若有其他相关问题或者需求也可以邮件联系俺探讨。

邮箱地址是: 
gaozhihan@vip.qq.com

若此博文能帮到您,欢迎扫码小额赞助。

微信:

支付宝:

分享用于学习C++音频处理的代码示例的更多相关文章

  1. 分享用于学习C++图像处理的代码示例

    为了便于学习图像处理并研究图像算法, 俺写了一个适合初学者学习的小小框架. 麻雀虽小五脏俱全. 采用的加解码库:stb_image 官方:http://nothings.org/ stb_image. ...

  2. 分享一些学习资料-大量PDF电子书

    分享一些学习用的电子书籍,给那些喜欢看书而不一定有机会买书的童鞋. 反对积分下载,提倡自由分享. 分享地址: http://pan.baidu.com/s/1qWK5V0g 提取密码:   np33 ...

  3. 嵌入式 十个最值得阅读学习的C开源项目代码

    开源世界有许多优秀的开源项目,我选取其中十个最优秀的.最轻量级的C语言的项目,希望可以为C语言开发人员提供参考. 十个最值得阅读学习的C开源项目代码 1. Webbench 2. Tinyhttpd ...

  4. Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)

    *Delphi之通过代码示例学习XML解析.StringReplace的用法 这个程序可以用于解析任何合法的XML字符串. 首先是看一下程序的运行效果: 以解析这样一个XML的字符串为例: <? ...

  5. 分享非常有用的Java程序(关键代码)(八)---Java InputStream读取网络响应Response数据的方法!(重要)

    原文:分享非常有用的Java程序(关键代码)(八)---Java InputStream读取网络响应Response数据的方法!(重要) Java InputStream读取数据问题 ======== ...

  6. ffmpeg音频播放代码示例-avcodec_decode_audio4

    一.概述 最近在学习ffmpeg解码的内容,参考了官方的教程http://dranger.com/ffmpeg/tutorial03.html,结果发现这个音频解码的教程有点问题.参考了各种博客,并同 ...

  7. 音频增益响度分析 ReplayGain 附完整C代码示例

    人们所熟知的图像方面的3A算法有: AF自动对焦(Automatic Focus)自动对焦即调节摄像头焦距自动得到清晰的图像的过程 AE自动曝光(Automatic Exposure)自动曝光的是为了 ...

  8. 音频增益响度分析 ReplayGain 附完整C代码示例【转】

    转自:http://www.cnblogs.com/cpuimage/p/8846951.html 人们所熟知的图像方面的3A算法有: AF自动对焦(Automatic Focus)自动对焦即调节摄像 ...

  9. .net reactor 学习系列(三)---.net reactor代码自动操作相关保护功能

    原文:.net reactor 学习系列(三)---.net reactor代码自动操作相关保护功能         接上篇,上篇已经学习了界面的各种功能以及各种配置,这篇准备学习下代码控制许可证. ...

随机推荐

  1. hdu 4109 dfs+剪枝优化

    求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己添加的)出发,0到1~n个节点之间的距离为1.mt[i]表示从0点到第i个节点眼下所得的最长路径 #include<iost ...

  2. 【树状数组】POJ 2352 Stars

    /** * @author johnsondu * @time 2015-8-22 * @type Binary Index Tree * ignore the coordinate of y and ...

  3. zephyr初始化流程

    1.调用应用层main()函数         kernel/init.c      181行 /** * * @brief Mainline for kernel's background task ...

  4. 【Java系列】Eclipse与Tomcat

    描述 本篇文章简要讲述Eclipse和Tomcat搭建,具体包括如下内容: (1)Eclipse安装和汉化 (2)Tomcat安装和CATALIAN_HOME变量配置 (3)在Eclipse中配置To ...

  5. 前端笔记---塌陷top

    一.在设置盒子div的子元素的外边框margin-top,子元素属性不起作用,父元素下沉: <!DOCTYPE html> <html lang="en"> ...

  6. effective java笔记之java服务提供者框架

    博主是一名苦逼的大四实习生,现在java从业人员越来越多,面对的竞争越来越大,还没走出校园,就TM可能面临失业,而且对那些增删改查的业务毫无兴趣,于是决定提升自己,在实习期间的时间还是很充裕的,期间自 ...

  7. Android项目实战(三十五):多渠道打包

    多渠道打包: 可以理解为:同时发布多个渠道的apk.分别上架不同的应用商店.这些apk带有各自渠道的标签,用于统计分析各个商店的下载次数等数据. 实现步骤 一.添加友盟渠道标签 添加位置:app目录下 ...

  8. 《Google软件测试之道》【PDF】下载

    <Google软件测试之道>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382198 内容介绍 每天,Google都要测试和发布 ...

  9. android 网络请求Volley的简单使用

    下载到本地jar包或者在线导入,jar地址:链接:http://pan.baidu.com/s/1gf3VZAb 密码:mmye //定义变量 private RequestQueue mQueue= ...

  10. iOS开发之Xcode常用调试技巧总结

    转载自:iOS开发之Xcode常用调试技巧总结 最近在面试,面试过程中问到了一些Xcode常用的调试技巧问题.平常开发过程中用的还挺顺手的,但你要突然让我说,确实一脸懵逼.Debug的技巧很多,比如最 ...