Android recording - porting SoundTouch to Android

Android recording - porting SoundTouch to Android

1, SoundTouch introduction

  • SoundTouch is an audio processing library
  • The main function of SoundTouch is to change the sound speed and tone.
  • Official website( http://www.surina.net/soundtouch)
  • SoundTouch processes PCM data.

2, Porting SoundTouch(Android)

1. Download the source code

After downloading the source code and decompressing it, you can get the source code of SoundTouch and Android demo. Demo has basic functions.
Of course, we need to write it ourselves, because the demo only processes wav files, and we need to process audio streams in real time;

2. Migration (CMake)

Operating environment: Win 10
NDK: 21.4.7075529
Gradle: 7.0.3

1. Create a new Module. We also name it soundTouch and create a cpp folder
2. Source code transplantation

Migrate the header file (. h) in the include of the source code downloaded above and the files. c,.h in source\SoundTouch and source\SoundStretch to the cpp folder

3. Configure cmake bulid gradle
 android {
    defaultConfig {
       //.. ellipsis
        //Configure output abi
        externalNativeBuild {
            cmake {
                abiFilters  'armeabi-v7a','arm64-v8a','x86_64', 'x86'
                cppFlags ''
            }
        }
    }
    //Configure CMakeLists location and version
    externalNativeBuild {
        cmake {
            path file('src/main/cpp/CMakeLists.txt')
            version '3.10.2'
        }
    }
}

4. Configure cmake cmakelist txt

Write cmakelist Txt, configure the output path, configure the compiled file, and so on

cmake_minimum_required(VERSION 3.10.2)

# Declares and names the project.

project("soundTouch")

#//${PROJECT_SOURCE_DIR} is actually the current module, but some AS will have problems
#Set the path of the last output of the generated so dynamic library
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/../libs/${ANDROID_ABI})

##Current/ All of the jni directory c .cpp source file and assign it to SRC_LIST
AUX_SOURCE_DIRECTORY(soundtouch SRC_LIST)

# 2. Add header file directory
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. * (important) source code modification

The source code needs to be modified, otherwise there will be strange noise
Because SoundTouch processes data in float (32bit) format by default, it needs to be changed to short(16bit) format first.
Because AudioRecord can only be byte(8bit) and short(16bit), 32-bit is not supported
Open sttypes H file, modify the following code:

3. Coding

Here we only talk about the implementation of two methods that mainly need to add real-time processing, putSamples and receiveSamples. You can see the main of the official demo CPP, most of the functions already exist. It supports the operation of creating multiple soundTouch. Really, I only understand C/C + +, but I know very little in actual combat. This operation is true 6.

extern "C" DLL_PUBLIC jlong jlong Java_xxxxxx_SoundTouch_newInstance(JNIEnv *env, jobject thiz)
{
   return (jlong)(new SoundTouch());
}

Turn this long into an address when you use it

  SoundTouch *pSoundTouch = (SoundTouch*)handle;

Through the demo, we can know that the number of putSamples may be less than that of receiveSamples

We use JNI to call. First, we write SoundTouch

class SoundTouch {
   //For other omissions, see the demo
   //Set data
   external fun putSamples(samples: ShortArray, len: Int)
   //Read data
   external fun receiveSamples(outputBuf: ShortArray): Int
}

cpp part:

4. Call with AudioRecord

   var processSamples: Int
   soundTouch.putSamples(pcmBuffer,pcmSize)
   do {
       processSamples = soundTouch.receiveSamples(mSTBuffer)
       //Not equal to 0, indicating that the processed data has been obtained
   	if (processSamples != 0) {
   		//Save the output, or do something else
   		processBuffer(mSTBuffer,processSamples)
       }
   } while (processSamples != 0)

5. Problems encountered

After the migration, the test is full of noise. It is found that SoundTouch processes data in float (32bit) format by default. Here, it needs to be changed to short(16bit) format. It has been marked important in the front

6. Migrate soundTouch demo

SoundTouch migration demo

7. Application migration soundTouch demo

Current application open source library: Mp3Recorder : real time recording - > voice change - > to MP3

Keywords: Java Android Apache

Added by nhan on Thu, 16 Dec 2021 03:08:07 +0200