PCM

自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。

采样率

采样频率,也称为采样速度或者采样率,定义了每秒从连续信号中提取并组成离散信号的采样个数,它用赫兹(Hz)来表示。采样频率的倒数是采样周期或者叫作采样时间,它是采样之间的时间间隔。通俗的讲采样频率是指计算机每秒钟采集多少个信号样本。

工业界常用的16K,就是1s有16000个采样点。

WAV

PCM是原始语音,依据采样率的定义,我们知道要播放PCM,需要知道采样率,因此需要一个文件格式可以封装PCM,wav就是微软公司专门为Windows开发的一种标准数字音频文件,该文件能记录各种单声道或立体声的声音信息。

wav文件前44个字节,定义了采样率,channel等参数,播放器通过这个数据就可以播放PCM数据了。

MP3

wav 很好的解决了PCM播放的问题,但是PCM实在是太大了,因此出现了mp3等音频格式,通过一定的压缩算法压缩语音,以便于互联网传输分享。

Ogg 与 Opus

随着音视频应用的越来越广泛,工业界有了越来越多的编解码器,比如Speek,Opus

Opus编解码器是专门设计用于互联网的交互式语音和音频传输。它是由IETF的编解码器工作组设计的,合并了Skype的SILK和Xiph. Org的CELT技术。

OPUS编解码

https://github.com/lostromb/concentus 是一个纯java库,可以编解码OPUS。

OPUS一般是分帧编码,比如一个320采样点(640字节)的数据,编码后为70多个字节,和PCM一样,编码后的OPUS不能直接播放:

  • 无法从文件本身获取音频的元数据(采样率,声道数,码率等)
  • 缺少帧分隔标识,无法从连续的文件流中分隔帧(尤其是vbr情况)

伴随着HTML5的发展,出现了OGG媒体文件格式,Ogg是一个自由且开放标准的多媒体文件格式,由Xiph.Org基金会所维护。Ogg格式并不受到软件专利的限制,并设计用于有效率地流媒体和处理高质量的数字多媒体。“Ogg”意指一种文件格式,可以纳入各式各样自由和开放源代码的编解码器,包含音效、视频、文字(像字幕)与元数据的处理。

OGG音频

压缩类型 格式 说明
有损 Speek 以低比特率处理语音数据(〜2.1-32 kbit / s /通道)
Vorbis 处理中高级可变比特率(每通道≈16-500kbit / s)的一般音频数据
Opus: 以低和高可变比特率处理语音,音乐和通用音频(每通道≈6-510kbit / s)
无损 FLAC 处理文件和高保真音频数据
未压缩 OggPCM 处理未压缩的PCM音频,与WAV类似

参考: https://juejin.cn/post/6844904016254599175

借博主的图:

java 解码OPUS文件

通过ffmpeg可以轻松的将wav转换为opus文件,本质是一个ogg封装的opus,我们可以通过vorbis-java 来读取opus文件。

通过OpusInfoTool,可以打印OPUS文件信息:

Processing file "C:\Users\jqpeng\Downloads\opus\wav16k.opus"

Opus Headers:
Version: 1
Vendor: Lavf58.27.103
Channels: 1
Rate: 16000Hz
Pre-Skip: 104
Playback Gain: 0dB User Comments:
encoder=Lavc58.53.100 libopus Logical stream 81c1bbc0 (-2118009920) completed Opus Audio:
Total Data Packets: 579
Total Data Length: 41406
Audio Length Seconds: 11.564333333333334
Audio Length: 00:00:11.56
Packet duration: 20.0ms (max), 20.0ms (avg), 20.0ms (min)
Page duration: 1000.0ms (max), 965.0ms (avg), 580.0ms (min)
Total data length: 41406 (overhead: 2.34%)
Playback length: 00:00:11.56
Average bitrate: 28.70 kb/s, w/o overhead: 27.97 kb/s

再借助concentus ,我们来解码OPUS文件为PCM文件。


public void testDecode() throws IOException, OpusException {
FileInputStream fs = new FileInputStream("\\wav16k.opus");
OggFile ogg = new OggFile(fs);
OpusFile of = new OpusFile(ogg);
OpusAudioData ad = null; System.out.println(of.getInfo().getSampleRate());
System.out.println(of.getInfo().getNumChannels()); OpusDecoder decoder = new OpusDecoder(of.getInfo().getSampleRate(),
of.getInfo().getNumChannels());
System.out.println(of.getTags());
FileOutputStream fileOut = new FileOutputStream("wav16k.pcm");
//
byte[] data_packet = new byte[of.getInfo().getSampleRate()];
int samples = 0;
while ((ad = of.getNextAudioPacket()) != null) {
// NOTE: samplesDecoded 是decode出来的short个数,byte需要*2
int samplesDecoded =
decoder.decode(ad.getData(), 0, ad.getData().length
, data_packet, 0, of.getInfo().getSampleRate() / 2,
false); fileOut.write(data_packet, 0, samplesDecoded * 2);
samples += samplesDecoded;
} System.out.println("samples: " + samples);
System.out.println("durationSeconds: " + (samples / 16000f));
fileOut.close();
}

感谢您的认真阅读。

如果你觉得有帮助,欢迎点赞支持!

不定期分享软件开发经验,欢迎关注作者, 一起交流软件开发:

从wav到Ogg Opus 以及使用java解码OPUS的更多相关文章

  1. OGG的孩子-有损音频编码opus

    Opus是一个有损声音编码的格式,由Xiph.Org基金会开发,之后由互联网工程任务组(IETF)进行标准化,目标用希望用单一格式包含声音和语音, 取代Speex和Vorbis,且适用于网络上低延迟的 ...

  2. 关于Java无法解码(ajax编码 Java解码)

    今天遇到了一个非常奇~~~~~~葩的问题,无解! 一向前端碰到中文,请求都使用encodeURI(encodeURI("中文"))编码,然后后端使用URLDecoder.decod ...

  3. ffmpeg mp4 mp3 wav flac webm aac ac3 ogg格式转换

    版权声明:本文为博主原创文章,未经允许不得转载. ffmpeg是Linux中转换音频视频文件的常用工具. mp4 to mp3: ffmpeg -i $ID.mp4 -acodec libmp3lam ...

  4. 【JNI】OPUS压缩与解压的JNI调用(.DLL版本)

    OPUS压缩与解压的JNI调用(.DLL版本) 一.写在开头: 理论上讲,这是我在博客园的第一篇原创的博客,之前也一直想找个地方写点东西,把最近做的一些东西归纳总结下,但是一般工程做完了一高兴就把东西 ...

  5. 转 ogg组件介绍

    应用场景:数据分发   ogg的组件: (1) OGG 程序和工具说明 convchk   转换ogg版本的信息 ,该程序可以将checkpoint files 转换成新版本: convprm :OG ...

  6. 音频压缩(Speex使用&Opus简介)--转

    博客地址:http://blog.csdn.net/kevindgk GitHub地址:https://github.com/KevinDGK/MyAudioDemo 一简介 二局域网语音配置 三Sp ...

  7. encodeURIComponent编码后java后台的解码 (AJAX中文解决方案)

    encodeURIComponent编码后java后台的解码 (AJAX中文解决方案) 同学的毕业设计出现JavaScript用encodeURIComponentt编码后无法再后台解码的问题. 原来 ...

  8. Js编码和Java后台解码

    1.java.将resultMsg 转为utf-8 (1) resultMsg = URLEncoder.encode(resultMsg, "utf-8"); (2) new S ...

  9. java中的字符集和编码

    前言 上次对计算机中的“字符集”和“编码”分别进行了总结,并指出二者之间的区别,不要搞混了,不清楚的再回到上一章看一下.今天再总结下java中是如何使用字符集(主要是Unicode字符集,其他常用字符 ...

随机推荐

  1. Union international INC评德意志联邦投入十亿欧元重启文化娱乐产业

    当地时间6月4日,德国联邦政府宣布了一项名为"重启文化"(Neustart Kultur)的计划,将投入总计10亿欧元,用以支持德国文化及创意产业的恢复和重建. Union int ...

  2. JVM元空间(Metaspace)

    本文转载自JVM学习--元空间(Metaspace) 从方法区(PermGen)到元空间(Metaspace) 方法区(PermGen) JDK1.8以前的HotSpot JVM有方法区,也叫永久代( ...

  3. JS相关基础

    1. ES5和ES6继承方式区别 ES5定义类以函数形式, 以prototype来实现继承 ES6以class形式定义类, 以extend形式继承 2. Generator了解 ES6 提供的一种异步 ...

  4. Linux 网络分析必备技能:tcpdump 实战详解

    大家好,我是肖邦,这是我的第 11 篇原创文章. 今天要分享的是 tcpdump,它是 Linux 系统中特别有用的网络工具,通常用于故障诊断.网络分析,功能非常的强大. 相对于其它 Linux 工具 ...

  5. Linux就该这样学--之常用linux命令及bash基础

    Linux就该这样学--之常用linux命令及bash基础 Linux命令 管道 重定向 环境变量 常用命令 常用系统工作命令 系统状态检测命令 工作目录切换命令 文本文件编辑命令 文件目录管理命令 ...

  6. Tango with django 1.9 中文——3.Django基础

    让我们开始运用Django.本章主要是给你一个关于创建新项目和新应用过程的概览.在本章的末尾,你将建立起一个简单的由Django驱动的网站. 3.1 配置测试 让我们测试以下你的Python和Djan ...

  7. HBase 数据存储结构

    在HBase中, 从逻辑上来讲数据大概就长这样: 单从图中的逻辑模型来看, HBase 和 MySQL 的区别就是: 将不同的列归属与同一个列族下 支持多版本数据 这看着感觉也没有那么太大的区别呀, ...

  8. .NET Core中的Worker Service

    当你想到ASP.NET Core时,可能会想到Web应用程序后端代码,包括MVC和WebAPI.MVC视图和Razor页面还允许使用后端代码生成带有HTML元素的前端UI.全新的Blazor更进一步, ...

  9. 原生js日历选择器,学习js面向对象开发日历插件

    在web开发过程中经常会碰到需要选择日期的功能,一般的操作都是在文本框点击,然后弹出日历选择框,直接选择日期就可以在文本框显示选择的日期.开发好之后给用户使用是很方便,但如果每一个日历选择器都要临时开 ...

  10. .Net Core 处理跨域问题Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource

    网页请求报错: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Or ...