简洁明了的插值音频重采样算法例子 (附完整C代码)
近一段时间在图像算法以及音频算法之间来回游走。
经常有一些需求,需要将音频进行采样转码处理。
现有的知名开源库,诸如: webrtc , sox等,
代码阅读起来实在闹心。
而音频重采样其实也就是插值算法。
与图像方面的插值算法没有太大的区别。
基于双线性插值的思路。
博主简单实现一个简洁的重采样算法,
用在对采样音质要求不高的情况下,也是够用了。
编解码库采用dr_wav
https://github.com/mackron/dr_libs/blob/master/dr_wav.h
近期有点强迫症,纯c实现。
贴上完整代码:
#ifdef __cplusplus extern "C" { #endif #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #include <stdint.h> //采用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, int sampleRate, uint32_t totalSampleCount) { drwav_data_format 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 = ; format.sampleRate = (drwav_uint32) sampleRate; format.bitsPerSample = ; 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(); } } } //读取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'; } } 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 - ; uint32_t dstSize = (uint32_t) (srcSize * ((float) newSampleRate / sampleRate)); ; 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 + ; destinationData[idx] = (int16_t) ((1.0f - coef) * sourceData[p1] + coef * sourceData[p2]); } } void resampler(char *in_file, char *out_file) { //音频采样率 uint32_t sampleRate = ; //总音频采样数 uint64_t totalSampleCount = ; int16_t *data_in = wavRead_int16(in_file, &sampleRate, &totalSampleCount); int16_t *data_out = (int16_t *) * sizeof(int16_t)); //如果加载成功 if (data_in != NULL && data_out != NULL) { resampleData(data_in, sampleRate, (uint32_t) totalSampleCount, data_out, sampleRate * ); wavWrite_int16(out_file, data_out,sampleRate * , (uint32_t) totalSampleCount * ); 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"); ) ; ]; ]; ]; ]; ]; ]; 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"); ; } #ifdef __cplusplus } #endif
不多注释,代码比较简单,一看就明了。
示例具体流程为:
加载wav(拖放wav文件到可执行文件上)->重采样为原采样的2倍->保存wav
若有其他相关问题或者需求也可以邮件联系俺探讨。
邮箱地址是:
gaozhihan@vip.qq.com
简洁明了的插值音频重采样算法例子 (附完整C代码)的更多相关文章
- 一种简单高效的音频降噪算法示例(附完整C代码)
近期比较忙, 抽空出来5.1开源献礼. 但凡学习音频降噪算法的朋友,肯定看过一个算法. <<语音增强-理论与实践>> 中提及到基于对数的最小均方误差的降噪算法,也就是LogMM ...
- 基于傅里叶变换的音频重采样算法 (附完整c代码)
前面有提到音频采样算法: WebRTC 音频采样算法 附完整C++示例代码 简洁明了的插值音频重采样算法例子 (附完整C代码) 近段时间有不少朋友给我写过邮件,说了一些他们使用的情况和问题. 坦白讲, ...
- 基于RNN的音频降噪算法 (附完整C代码)
前几天无意间看到一个项目rnnoise. 项目地址: https://github.com/xiph/rnnoise 基于RNN的音频降噪算法. 采用的是 GRU/LSTM 模型. 阅读下训练代码,可 ...
- 音频降噪算法 附完整C代码
降噪是音频图像算法中的必不可少的. 目的肯定是让图片或语音 更加自然平滑,简而言之,美化. 图像算法和音频算法 都有其共通点. 图像是偏向 空间 处理,例如图片中的某个区域. 图像很多时候是以二维数据 ...
- 音频自动增益 与 静音检测 算法 附完整C代码
前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用于评估一定长度音频的音量强度, 而分析之后,很多类似的需求,肯定是做音频增益,提高音量诸如此类做法. ...
- 音频自动增益 与 静音检测 算法 附完整C代码【转】
转自:https://www.cnblogs.com/cpuimage/p/8908551.html 前面分享过一个算法<音频增益响度分析 ReplayGain 附完整C代码示例> 主要用 ...
- 音频算法之小黄人变声 附完整C代码
前面提及到<大话音频变声原理 附简单示例代码>与<声音变调算法PitchShift(模拟汤姆猫) 附完整C++算法实现代码> 都稍微讲过变声的原理和具体实现. 大家都知道,算法 ...
- 经典傅里叶算法小集合 附完整c代码
前面写过关于傅里叶算法的应用例子. <基于傅里叶变换的音频重采样算法 (附完整c代码)> 当然也就是举个例子,主要是学习傅里叶变换. 这个重采样思路还有点瑕疵, 稍微改一下,就可以支持多通 ...
- 自动曝光修复算法 附完整C代码
众所周知, 图像方面的3A算法有: AF自动对焦(Automatic Focus)自动对焦即调节摄像头焦距自动得到清晰的图像的过程 AE自动曝光(Automatic Exposure)自动曝光的是为了 ...
随机推荐
- 使用BEM命名规范来组织CSS代码
BEM 是 Block(块) Element(元素) Modifier(修饰器)的简称 使用BEM规范来命名CSS,组织HTML中选择器的结构,利于CSS代码的维护,使得代码结构更清晰(弊端主要是名字 ...
- MySQL ODBC 3.51 Driver - Access Denied
MySQL ODBC 3.51 Driver - Access Denied 同事反馈在应用服务器上配置MySQL ODBC 3.51 Drive时,测试连接MySQL数据库时报下面错误: ERR ...
- JAVA的helloworld
java环境设置------------- 在环境变量中设置以下三个变量:JAVA_HOME=C:\j2sdk1.4.1 //可以改为相应的目录CLASSPATH=%JAVA_HOME%\lib\to ...
- 八爪鱼采集器︱加载更多、再显示20条图文教程(Xpatth、Ajax)
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 由于代码布置采集器比较麻烦,又很早知道八爪鱼采 ...
- return *this 与return this的区别
return *this返回当前对象的引用(也就是返回当前对象) return this返回当前对象的地址. #include <iostream> using namespace std ...
- Linux显示指定区块大小为1024字节
Linux显示指定区块大小为1024字节 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ df -k 文件系统 1K-blocks 已用 可用 已用% 挂载点 ...
- Filter组件开发中的SDK基类分析
DirectShow SDK提供了一套开发Filter的基类源代码.基于这些基类开发Filter将大大简化开发过程. 1.CBaseObject 大部分SDK类都从CBaseObject类(参见com ...
- ssm+maven多模块项目整合
我的项目一共会分为4个模块:entity.dao.service和web 一.创建父模块 填写GroupId与ArtifactId 填写项目名称和项目保存路径 因为是父模块所以src包可以删除 二.创 ...
- TensorLayer官方中文文档1.7.4:API – 数据预处理
所属分类:TensorLayer API - 数据预处理¶ 我们提供大量的数据增强及处理方法,使用 Numpy, Scipy, Threading 和 Queue. 不过,我们建议你直接使用 Tens ...
- 【BZOJ2882】工艺(后缀数组)
[BZOJ2882]工艺(后缀数组) 题面 BZOJ权限题,我爱良心洛谷 题解 最容易的想法: 把字符串在后面接一份 然后求后缀数组就行了... #include<iostream> #i ...