最近收到几个24位的PCM录音源文件,Recoder库原有的PCM转WAV工具只支持8位和16位,于是就升级一下支持了24位的PCM源文件。

可能是搜索方法不对,搜索了半天没有找到24位转成16位的算法,但好在运气还不错看到一篇标题不太想关的文章里面有成套的转换算法。

算法来源

24位PCM转成32位浮点数参考文章:https://www.codeproject.com/articles/501521/how-to-convert-between-most-audio-formats-in-net 里面的Convert24BitToFloat函数,转成了32位浮点数就很容易转成16位或8位了。

js版24位PCM转8位、16位代码

var pcm24=... Uint8Array二进制数组 ...;
var pcm16=new Int16Array(pcm24.length/3);
var pcm8=new Uint8Array(pcm24.length/3); for(var i=0,j=0;j<pcm24.length;i++){
//24bit pcm转成浮点数
var n=((pcm24[j++] | (pcm24[j++]<<8) | (pcm24[j++]<<16))<<8)>>8;
n=n/16777216; //浮点数转成16位
pcm16[i]=n*0x7FFF; //浮点数转成8位
pcm8[i]=((n*0x7FFF) >> 8) + 128;
};

代码里面已经实现了24位PCM转成16位和8位,代码非常简单,移植到其他语言也很容易。

js版8位、16位PCM转成24位

根据上面代码,做一次逆运算就可以了:

var pcm16=... Int16Array ...;
var pcm24=new Uint8Array(pcm16.length*3); for(var i=0,j=0;i<pcm16.length;i++){
var n=pcm16[i] / 0x7FFF * 16777216;
//var n=((pcm8[i]-128) << 8) / 0x7FFF * 16777216; //8位的多一步先转成16位 pcm24[j++]=n & 0xff;
pcm24[j++]=(n & 0xff00) >> 8;
pcm24[j++]=(n & 0xff0000) >> 16;
}

附:浏览器控制台下载数据文件代码

var b=new Blob([pcm16]);
var a=document.createElement("a");
a.href=URL.createObjectURL(b)
a.download="test.pcm";
a.click();

相关实现

本代码已用在了H5录音开源库 Recorder裸(RAW、WAV)PCM转WAV播放测试和转码在线工具中,点此可以在线转换PCM文件。

【完】.

24位PCM采样数据转成16位算法,已实现PCM转WAV在线工具源码支持24bits、16bits、8bits的更多相关文章

  1. GUID转换成16位字符串或19位唯一字符串

    整理几个经常使用GUID转换成16位字符串或19位唯一字符串方法: /// <summary> /// 依据GUID获取16位的唯一字符串 /// Author : 付义方 /// < ...

  2. GUID转换成16位字符串或19位数据(确保唯一)

    // <summary> /// 根据GUID获取16位的唯一字符串 /// </summary> /// <param name=\"guid\"& ...

  3. 将两个byte型拼接成16位二进制,再转化为十进制

    short s = 0; //一个16位整形变量,初值为 0000 0000 0000 0000 byte b1 = 1; //一个byte的变量,作为转换后的高8位,假设初值为 0000 0001 ...

  4. C# GUID转换成16位字符串或19位数字并确保唯一

    /// <summary> /// 根据GUID获取16位的唯一字符串 /// </summary> /// <param name=\"guid\" ...

  5. Android 音视频深入 一 AudioRecord录音生成pcm转换为wav(附源码下载)

    本篇项目地址,名字是AudioRecord录音(能暂停,将pch转换为wav),求starhttps://github.com/979451341/Audio-and-video-learning-m ...

  6. Scala实战高手****第16课:Scala implicits编程彻底实战及Spark源码鉴赏

    隐式转换:当某个类没有具体的方法时,可以在该类的伴生对象或上下文中查找是否存在隐式转换,将其转换为可以调用该方法的类,通过代码简单的描述下 一:隐式转换 1.定义类Man class Man(val ...

  7. Android系统移植与调试之------->如何使用PhotoShop转换24位的bmp图片为16位bmp图片

    使用Android移植时候,很多图片都需要16为的bmp格式,所以研究了一下如何从24位转换成16位,供大家参阅 step1:查看bmp图片的属性,如下图所示,是24位的 step2:用PhotoSh ...

  8. 如何将24位RGB颜色转换16位RGB颜色

    有许多朋友第一次使用16位彩色显示屏会遇到如何将24位RGB颜色转换为对应的16位RGB颜色的问题, 通过查阅相关资料,就写一下其中的转换原理吧,希望对大家会有所帮助. 我们知道24位RGB是分别由8 ...

  9. 16位模式/32位模式下PUSH指令探究——《x86汇编语言:从实模式到保护模式》读书笔记16

    一.Intel 32 位处理器的工作模式 如上图所示,Intel 32 位处理器有3种工作模式. (1)实模式:工作方式相当于一个8086 (2)保护模式:提供支持多任务环境的工作方式,建立保护机制 ...

随机推荐

  1. 记一次bug思考过程:HibernateException: Could not obtain transaction-synchronized Session for current thread

    场景:把从客户端提交的任务放到线程池执行 异常:HibernateException: Could not obtain transaction-synchronized Session for cu ...

  2. 第7.14节 Python类中的实例方法详析

    第7.14节 Python类中的实例方法详析 一.    实例方法的定义 在本章前面章节已经介绍了类的实例方法,实例方法的定义有三种方式: 1.    类体中定义实例方法 第一种方式很简单,就是在类体 ...

  3. Python中函数是否能使用全局变量?

    Python函数中的变量,既可以使用局部变量(本地名字空间的变量),也可以使用全局变量(全局名字空间的变量),函数在执行查找变量只读时,先在局部变量中查找,找不到再查到全局变量中查找.因此当局部变量和 ...

  4. PyQt(Python+Qt)学习随笔:QTreeView树形视图的uniformRowHeights属性

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 uniformRowHeights属性用于控制视图中所有数据项是否保持相同高度,所有高度都与视图中第 ...

  5. PyQt(Python+Qt)学习随笔:Qt Designer中部件的调色板palette属性和字体font属性设置

    一.调色板 在Qt Designer的部件属性中,有个部件调色板(palette)的属性,进入后,如下图所示: 1.调色板palette Qt中提供的调色板palette用于管理控件的外观显示,对应P ...

  6. PyQt(Python+Qt)学习随笔:Designer中PushButton按钮flat属性

    flat属性用于确认按钮边框是否凸起,如果为False则凸起,如果为True则边框与背景是平坦的. 默认值为False,如果设置为True,则除非按下按钮,否则大多数样式都不会绘制按钮背景.通过使用s ...

  7. [GKCTF2020]CheckIN 注意了解多方面的东西

    打开之后是这样的,没有发现反序列化函数,但是发现有一个@eval,想到了一句话,这是用base64进行传参首先传参phpinfo();看看,需要经过base64编码 http://e0cc90ac-d ...

  8. datagrip2020最新安装破解教程方法激活码安装参数

    现在,datagrip的版本已更新至2020.3,尚未升级的用户请赶快升级. 本文教您如何安装datagrip2020.3版本并破解它. 此方法可以100%永久激活datagrip2020.3(低版本 ...

  9. AcWing 316 .减操作

    题目链接 大型补档计划 没想出来去看题解了... 关键是发现无论怎样括号嵌套,每个元素始终只有对答案的贡献为 + a[i] 或者 - a[i]. 而且第一个必然贡献是 +1, 第二个必然是 -1. 所 ...

  10. STL—— 容器(vector)的各种功能方法

    1. 获取容器的元素个数 size() 使用 vectorName.size() 可以输出这个容器中类型的个数,如下代码: 1 #include <iostream> 2 #include ...