Android录音-SoundTouch移植到Android
文章目录
一、SoundTouch介绍
- SoundTouch是一个音频处理库
- SoundTouch的主要功能是通过改变音速、音调使用功能变音。
- 官网(http://www.surina.net/soundtouch)
- SoundTouch 处理的的是PCM 数据。
二、移植SoundTouch(Android)
1. 下载源码
下载源码后解压可以得到SoundTouch
的源码和Android demo,demo是基本功能都有。
当然我们需要自己写,因为demo 只处理wav
文件处理,我们需要进行实时处理音频流;
2. 移植工作 (CMake)
运行环境:Win 10
NDK: 21.4.7075529
Gradle: 7.0.3
1. 新建Module
我们也取名 soundTouch
,建立cpp
文件夹
2.源码移植
把上面下载的源码的include
中的头文件(.h)和 source\SoundTouch
以及 source\SoundStretch
中的文件.c
,.h
文件移植到cpp
文件夹下
3. 配置CMake-bulid.gradle
android {
defaultConfig {
//..省略
//配置输出abi
externalNativeBuild {
cmake {
abiFilters 'armeabi-v7a','arm64-v8a','x86_64', 'x86'
cppFlags ''
}
}
}
//配置CMakeLists 位置和版本
externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.10.2'
}
}
}
4. 配置CMake-CmakeList.txt
编写CmakeList.txt
,配置输出路径,配置编译的文件等等
cmake_minimum_required(VERSION 3.10.2)
# Declares and names the project.
project("soundTouch")
#// ${PROJECT_SOURCE_DIR} 实际当前module 但是有些AS 会有问题
#设置生成的so动态库最后输出的路径
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../libs/${ANDROID_ABI})
##当前../jni目录的所有.c .cpp源文件,并且赋值到SRC_LIST
AUX_SOURCE_DIRECTORY(soundtouch SRC_LIST)
# 2. 添加头文件目录
include_directories(soundtouch)
add_library( # Sets the name of the library.
soundTouch
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
soundtouch-jni.cpp
${SRC_LIST})
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
target_link_libraries( # Specifies the target library.
soundTouch
# Links the target library to the log library
# included in the NDK.
${log-lib} )
5. *(重要)源码修改
需要源码修改,否则会出现很奇怪的噪音
因为SoundTouch默认是处理float(32bit)格式的数据,这里需要先改成short(16bit)的格式。
因为AudioRecord
的只可以是byte(8bit)和 short(16bit),不支持32位
打开STTypes.h文件,修改如下代码:
3. 代码编写
这里我们只讲主要需要添加实时处理的2个方法的实现,putSamples
和receiveSamples
,通过可以看官方的demo的main.cpp
,大部分功能已经有了,其中支持可以创建多个soundTouch
的操作好骚啊,说真的我只看的懂C/C++,但是实战懂得很少,这个操作是真的6。
extern "C" DLL_PUBLIC jlong jlong Java_xxxxxx_SoundTouch_newInstance(JNIEnv *env, jobject thiz)
{
return (jlong)(new SoundTouch());
}
用的时候把这个long 转成地址
SoundTouch *pSoundTouch = (SoundTouch*)handle;
其中通过demo,我们可以知道 putSamples
的次数是有可能小于receiveSamples
我们使用JNI 进行调用,首先编写SoundTouch
编写
class SoundTouch {
//其他省略,可以看demo
//设置数据
external fun putSamples(samples: ShortArray, len: Int)
//读取数据
external fun receiveSamples(outputBuf: ShortArray): Int
}
cpp部分:
4. 配合AudioRecord
调用
var processSamples: Int
soundTouch.putSamples(pcmBuffer,pcmSize)
do {
processSamples = soundTouch.receiveSamples(mSTBuffer)
//不等于0,说明得到了处理后的数据
if (processSamples != 0) {
//输出保存,或者做其他出来
processBuffer(mSTBuffer,processSamples)
}
} while (processSamples != 0)
5. 遇到的问题
移植完成后测试全是噪音,发现是因为SoundTouch默认是处理float(32bit)格式的数据,这里需要先改成short(16bit)的格式。已在前面标注重要了
6. 移植soundTouch的demo
7.应用移植soundTouch的demo
当前应用开源库:Mp3Recorder:实时录音->变音->转MP3