我的视频课程(基础):《(NDK)FFmpeg打造Android万能音频播放器》

我的视频课程(进阶):《(NDK)FFmpeg打造Android视频播放器》

我的视频课程(编码直播推流):《Android视频编码和直播推流》

我的视频课程(C++ OpenGL):《Android C++ OpenGL教程》

说到OpenSL ES,不仅能播放和录制PCM音频数据,还能改变声音大小、设置左声道或右声道播放、还能变速播放,可谓是播放音频的王者。但是变速有一点不好的就是,虽然播放音频的速度变了,但是相应的音调也随之变了,这样的用户体验就不那么好了。所以就想到了用开源的SoundTouch来实现PCM音频变速和变调,OpenSL ES只是单纯的播放PCM数据就可以了。先来一张实例镇楼:(实例来自wlmusic),文末有本文实例代码。

一、移植SoundTouch(Android):

1.1、下载SoundTouch源码,当前最新是:v2.0.0

1.2、用Android Studio创建一个C++项目,如果不会可看《Android Studio通过cmake创建FFmpeg项目》的创建过程。

1.3、然后再项目中集成OpenSL ES,可参考《Android通过OpenSL ES播放音频套路详解》。

1.4、在项目cpp文件夹中创建include和SoundTouch文件夹,并把下载好的SoundTouch里面的include和SoundTouch的源码拷贝进去就可以了,目录结构如下:

1.5、在CMakeList里面添加需要编译的cpp文件和include:

include_directories(src/main/cpp/SoundTouch)
include_directories(src/main/cpp/include)
add_library( # Sets the name of the library.native-lib# Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).src/mainp/native-lib.cppsrc/mainp/SoundTouch/AAFilter.cppsrc/mainp/SoundTouch/FIFOSampleBuffer.cppsrc/mainp/SoundTouch/FIRFilter.cppsrc/mainp/SoundTouchu_detect_x86.cppsrc/mainp/SoundTouch/sse_optimized.cppsrc/mainp/SoundTouch/RateTransposer.cppsrc/mainp/SoundTouch/SoundTouch.cppsrc/mainp/SoundTouch/InterpolateCubic.cppsrc/mainp/SoundTouch/InterpolateLinear.cppsrc/mainp/SoundTouch/InterpolateShannon.cppsrc/mainp/SoundTouch/TDStretch.cppsrc/mainp/SoundTouch/BPMDetect.cppsrc/mainp/SoundTouch/PeakFinder.cpp)

这样就把SoundTouch移植到了Android中。

二、用SoundTouch转码PCM源文件:

2.1、因为SoundTouch默认是float(32bit)格式的数据,这里需要先改成short(16bit)的格式。打开STTypes.h文件,修改如下代码:

再注释掉下面这句,不然编译不通过(for x86模拟器):

这样SoundTouch里面处理PCM数据就是用的16bit的数据了。

2.2、SoundTouch使用流程

2.2.1、添加命名空间,并创建SoundTouch指针变量

using namespace soundtouch;
SoundTouch *soundTouch;

2.2.2、设置SoundTouch参数

    soundTouch = new SoundTouch();soundTouch->setSampleRate(44100);//设置采样率,此处为44100,根据实际情况可变soundTouch->setChannels(2);//声道,此处为立体声soundTouch->setPitch(1);//变调不变速,如0.5、1.0、1.5等soundTouch->setTempo(1);//变速不变调,如0.5、1.0、2.0等

2.2.3、向SoundTouch中传入获取到的PCM数据,使用:putSamples函数。

size = fread(pcm_buffer, 1, 4096 * 2, pcmFile);
soundTouch->putSamples((const SAMPLETYPE *) pcm_buffer, size / 4);

这里,pcm_buffer是u_int16_t *类型的,也就是说和SoundTouch处理的PCM数据位数是一致的(16bit),所以可以直接传入SoundTouch中。putSamples的第一个参数就是PCM数据指针,第二个参数是采样点的个数,由于是2声道16bit(2byte),所以PCM数据的采样点个数为:num = 大小(size)/ (2 * 2)。

2.2.3、获取SoundTouch输出的PCM数据:使用receiveSamples函数。

num = soundTouch->receiveSamples(sd_buffer, size / 4);

这里,receiveSamples的第一个参数是SoundTouch(变速或变调)处理后的PCM数据存放的内存地址,第二个参数是可能的最大采样个数,可以和putSamples保持一致,其中sd_buffer是SAMPLETYPE * 类型的,记得要提前分配好内存大小,最后返回值就是SoundTouch处理后的PCM里面所包含的采样个数,由于可能有缓存,所以应循环读取receiveSamples,直到返回值为0为止。

2.2.4、OpenSL ES播放SoundTouch处理后的PCM音频数据。

(*pcmBufferQueue)->Enqueue(pcmBufferQueue, sd_buffer, size * 4);

由于size是采样个数,所以sd_buffer的大小是:size * 2(声道) * 2(16bit==2字节)。

这样,我们听到的声音就是通过SoundTouch转码过后的了,如:变速不变调,变调不变速,变速又变调都可以自己设置。

2.3、FFmpeg解码得到的PCM数据(uint_8 *)利用SoundTouch转码:

这里要处理的就是把uint_8 *(8bit)的数据转换成short(16bit)的数据格式。这里其实就是做bit的位运算,原理如下如:

转换代码如下:

for (int i = 0; i < size / 2 + 1; i++){sd_buffer[i] = (pcm_buffer[i * 2] | (pcm_buffer[i * 2 + 1] << 8));}soundTouch->putSamples((const SAMPLETYPE *) pcm_buffer, size / 4);

后续操作和16bit的一样不变。

三、总结

虽然是简单的移植SoundTouch到Android来播放PCM数据,但是还是让我们了解到了数据在内存中怎么排列的,然后可以怎么操作最小单位的bit来达到我们的要求。

实例源码下载:Github:SoundTouch_OpenSL_Android

OpenSL ES利用SoundTouch实现PCM音频的变速和变调相关推荐

  1. soundtouch android,Android studio NDK + CMake 编译SoundTouch实现wav格式音频的变速、变调功能...

    温馨提示: 本博客不是从零开始的文章,也不是什么高手精贴,只是一个菜鸡踩坑记录贴,建议懂得NDK+CMake流程的人观看,若是从零开始的,推荐先去看一下我之前跑的一个例子: 传送门在此:https:/ ...

  2. 【KAWAKO】audiotsm-使用python对音频进行变速不变调处理

    目录 安装库 导入相关库 定义reader 定义writer 定义WSLOA算法,并运行 官方手册 源码 安装库 pip install audiotsm 导入相关库 import audiotsm ...

  3. Android直播开发之旅(13):使用FFmpeg+OpenSL ES播放PCM音频

    文章目录 1. OpenSL ES原理 1.1 OpenSL ES核心API讲解 1.1.1 对象(Object)与接口(Interface) 1.1.2 [OpenSL ES的状态机制](https ...

  4. Android音视频学习系列(五) — 掌握音频基础知识并使用AudioTrack、OpenSL ES渲染PCM数据

    系列文章 Android音视频学习系列(一) - JNI从入门到精通 Android音视频学习系列(二) - 交叉编译动态库.静态库的入门 Android音视频学习系列(三) - Shell脚本入门 ...

  5. 音频应用(如sip与Voip),编解码API(Ringtone,SoundPool,MediaPlayer),回声消除等(Lame Speex等),OpenSL ES

    3套音频播放API:MediaPlayer,SoundPool,AudioTrack. android录音项目,用单例模式集成了record,并实时转码mp3- https://github.com/ ...

  6. Android 音频 OpenSL ES 录音 采集

    1,创建引擎 2,创建AudioRecorder并开始录音 3,暂停录音 4,释放资源 5,数据是通过回调函数处理的. 好处:缓冲区不用通过AudioRecord.getMinBufferSize获取 ...

  7. android4.0 音频框架 opensl openmax,适用于android的OpenSL ES指南-面向Android的OpenSL ES

    本文将详细说明NDK中OpenSL ES™的实现与OpenSL ES 1.0.1参考规范的不同.在使用规范中的示例代码时,可能需要修改它以在Android上工作. 除非另有说明,所有功能都可以在And ...

  8. 音视频学习 AudioTrack、OpenSL ES 音频渲染

    前言 在讲解音频渲染之前,需要对音频的基础知识有所了解,所以该篇分为基础概念和AudioTrack 以及 OpenSL ES Demo 实例讲解,这样有助于更好的理解 Android 中音频渲染. 音 ...

  9. 适用于Android的OpenSL ES指南-OpenSL ES的Android扩展

    翻译自Android Extensions 针对Android的OpenSL ES扩展了参考OpenSL ES规范,使其与Android兼容,并利用Android平台的强大功能和灵活性. Androi ...

最新文章

  1. Tomcat 调优及 JVM 参数优化
  2. .net 4.0下载
  3. python从入门到实践回顾——字典
  4. CSS3支持box-flex弹性布局
  5. oracle死锁trace,Oracle 学习之性能优化(十)锁
  6. java常见的算法_Java常用算法总结(转)
  7. Redis-学习笔记01【Redis环境搭建】
  8. 程序员的奋斗史(三十五)——人在囧途之应聘篇(五)
  9. mock java_JAVA的mock工具mockito简介
  10. html原文档流样式,html之样式
  11. 华为MatePad Pro 5G平板正式发布:售价5299元起!
  12. svn汉化插件安装步骤
  13. 教孩子编程python 语言 nostarch 下载_教孩子学编程 Python语言版
  14. 【技术快报】9.26-10.2
  15. 点击计算机管理出现找不到文件,win10点击计算机管理时提示找不到文件如何办?...
  16. SYZOJ - sxy的书包(背包)
  17. 企业新闻媒体资源有哪些类型?从哪里找?
  18. Java实现DES加密解密(对称式)
  19. 桌面鼠标右键新建Excel,不能使用?
  20. System.Core, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes”

热门文章

  1. VMware——网络服务IIS配置
  2. 20HUI - 折叠面板(hui-accordion)
  3. Sqlite数据库操作综合及
  4. SHA1算法代码实现
  5. 你问我答,这样的学习方式你喜欢吗
  6. 搭档Cloudera 数澜科技帮企业把数据用起来
  7. GitLab 安装教程
  8. HC项目本地快速部署文档
  9. 直接能源医疗器械行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  10. 分布式共识算法(拜占庭容错算法)的系列整理一:PBFT、PoW、PoS、DPos