Android uses the LAME mp3 files pcm file transfer

Android uses the LAME pcm format to mp3 format

lame description: LAME is an open source MP3 encoder, is considered to be of high bit rate and the best MP3 VBR encoder improve quality and speed continues to be the only possible cause LAME MP3 encoder still being actively developed device. Carried out using lame mp3 encoder, NDK need to know some relevant knowledge, such as jni and cmake.

Ready to work:

  • Download lame Source: https: //lame.sourceforge.io/ directly download the latest version, as used herein, it is version 3.100
  • android studio c ++ support a new project

Integrated lame Source

In cpp directory, create a new folder lamemp3, download the source code file \ all .c and .h files lame-3.100 \ libmp3lame folder are copied to the lamemp3 and \ under \ lame-3.100 include the lame.h be copied in, here, LAME source have been copied, the next, and the need to modify the source content portion gradle configuration parameters.

1) Delete line 47 fft.c file "include" vector / lame_intrin.h ""

2) #include modify set_get.h file 24 line "lame.h"

3) The line 574 util.h file "extern ieee754_float32_t fast_log2 (ieee754_float32_t x) ;"
is replaced with "extern float fast_log2 (float x) ;"

Build.gradle need to modify files in the app

android {
...
    defaultConfig {
    ...
        externalNativeBuild{
            cmake{
                cFlags "-DSTDC_HEADERS"
            }
        }
    }
}

Next, we edit cmake, later edited, click on the refresh linked c ++ project at build android studio, and on cmake part, see cmake file comments section, written in a way not cmake limits of a single, depending on your understanding of the relevant methods of cmake

# Sets the minimum version of CMake required to build the native library.
#设置构建本地库所需的最低cmake版本
cmake_minimum_required(VERSION 3.4.1)
#设置库文件导出目录
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lameLibs/${ANDROID_ABI})
#批量导入c文件和cpp文件
file(GLOB lame lamemp3/*.c)
file(GLOB lame2 lamemp3/*.cpp)
#批量导入头文件
include_directories(${CMAKE_CURRENT_LIST_DIR}/lamemp3)
# 创建和给一个库命名,可以设置为静态库
# 或动态库,并且提供它源码的相关路径
# 你可以定义多个库,然后cmake为你构建他们
# gradle会自动打包共享库到你的apk中
add_library( # Sets the name of the library.
        native-lib

        # Sets the library as a shared library.
        SHARED

        # 导入所有源文件
        native-lib.cpp
        ${lame}
        ${lame2}
        )

#所有指定的预构建库,并将路径定义为变量,用于后面引入
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)

#指令cmake需要链接到的库
target_link_libraries(
        #指定目标library
        native-lib
        #链接目标库到log库
        ${log-lib})

Write MP3 conversion c ++ implementation,

In cpp / lamemp3 folder download new pcm2pm3.cpp and pcm2pm3.h files posted here to achieve some complete source code reference projects

//初始化lame
int pcm2mp3::init(const char *pcm_path, const char *mp3_path, int sample_rate, int channel,
                  int bitRate) {
    int result=-1;
    pcm_file=fopen(pcm_path,"rb");
    if(pcm_file!= NULL){
        mp3_file=fopen(mp3_path,"wb");
        if (mp3_file!= NULL){
            //开始初始化
            lame_client=lame_init();
            lame_set_in_samplerate(lame_client,sample_rate);
            lame_set_out_samplerate(lame_client,sample_rate);
            lame_set_num_channels(lame_client,channel);
            lame_set_brate(lame_client,bitRate);
            lame_set_quality(lame_client,2);
            lame_init_params(lame_client);
            result=0;
        }
    }
    return result;
}
//pcm文件转mp3文件
void pcm2mp3::pcm_to_mp3() {
    int bufferSize = 1024 * 256;
    short *buffer = new short[bufferSize / 2];
    short *leftBuffer = new short[bufferSize / 4];
    short *rightBuffer = new short[bufferSize / 4];
    unsigned char* mp3_buffer = new unsigned char[bufferSize];
    size_t readBufferSize = 0;
    while ((readBufferSize = fread(buffer, 2, bufferSize / 2, pcm_file)) > 0) {
        for (int i = 0; i < readBufferSize; i++) {
            if (i % 2 == 0) {
                leftBuffer[i / 2] = buffer[i];
            } else {
                rightBuffer[i / 2] = buffer[i];
            }
        }
        size_t wroteSize = lame_encode_buffer(lame_client, (short int *) leftBuffer, (short int *) rightBuffer, (int)(readBufferSize / 2), mp3_buffer, bufferSize);
        fwrite(mp3_buffer, 1, wroteSize, mp3_file);
    }

    delete [] buffer;
    delete [] leftBuffer;
    delete [] rightBuffer;
    delete [] mp3_buffer;


}

The next step is to write jni call c ++ method defines three native method, get a version for testing lame loading is successful, pcmTomp3 file conversion, destroy carry out the release of related objects

public class LameJni {
    static {
        System.loadLibrary("native-lib");
    }
    public native String getVersion();
    //初始化lame
    public native int pcmTomp3(String pcmPath,String mp3Path,int sampleRate, int channel,  int bitRate);
    public native void destroy();

}

Then is to achieve native method, here only posted achieve conversion, as well as rules regarding the naming jni type conversion rules, there is not much to say, you can view the relevant information jni

pcm2mp3 *mp3_encoder;
extern "C"
JNIEXPORT int JNICALL
Java_com_david_sampling_util_LameJni_pcmTomp3(JNIEnv *env, jclass clazz, jstring pcm_path,
                                          jstring mp3_path, jint sample_rate, jint channel,
                                          jint bit_rate) {
    int result=-1;
    const char *pcm_path_=env->GetStringUTFChars(pcm_path,0);
    const char *mp3_path_=env->GetStringUTFChars(mp3_path,0);
    mp3_encoder=new pcm2mp3();
    mp3_encoder->init(pcm_path_,mp3_path_,sample_rate,channel,bit_rate);
    mp3_encoder->pcm_to_mp3();
    env->ReleaseStringUTFChars(pcm_path,pcm_path_);
    env->ReleaseStringUTFChars(mp3_path,mp3_path_);
    return result;
}

Then call java jni layer can be realized by encoded mp3 file

//注:本例经过尝试,发现如果采样率不缩小,那么声音会变快,原因还未找到
lameJni.pcmTomp3(pcmFile.getAbsolutePath(),mp3File.getAbsolutePath(),mSampleRate/2,mChannel==AudioFormat.CHANNEL_IN_MONO?1:2,128);

Above, can be converted into pcm mp3, pcm on access can be a reference on: https: //blog.csdn.net/s591628545/article/details/104525958

Project address: https: //github.com/kingdavidsun/AudioSampling.git

Released two original articles · won praise 0 · Views 8

Guess you like

Origin blog.csdn.net/s591628545/article/details/104526112