MP3 recording development

NDK environment configuration

This is mainly to introduce the NDK development environment configuration of Eclipse. As for the configuration of Android Studio is relatively simple, Google it yourself. . .

Download and install CDT

Many do not explain, Eclipse plug-in installation

https://dl.google.com/android/eclipse/

After the installation is complete, restart

Download and install NDK

Similarly, download the corresponding NDK from the official website

NDK download address

After the download is complete, decompress it and put it in the appropriate directory

If the following situation occurs

It means that the NDK version is too high, please download a lower version, the correct one is as follows

At this point, the configuration of the NDK development environment is completed. Of course, this is based on the fact that the installed jdk version is 1.7 or higher. If it is 1.6, cygwin must be installed, and of course there are other configurations

It is really necessary to carry out NDK development in the 1.6 environment, you can read this article
Android NDK Development (1) - Environment Construction

LAME compile

Lame online download address

  1. Create a jni directory under the root directory of the newly created project
  2. Unzip the downloaded lame-3.99.5.tar.gz file, copy the files in the libmp3lame folder to the jni directory
  3. Copy lame.h to the jni directory (under the include directory)
  4. Remove non .c/.h files
  5. Edit jni/util.h, and replace extern ieee754_float32_t fast_log2(ieee754_float32_t x); with extern float fast_log2(float x); on line 574.
  6. Create Android.mk
    LOCAL_PATH := $(call my-dir)

    include $(CLEAR_VARS)

    LOCAL_MODULE := mp3lame

    LOCAL_SRC_FILES := bitstream.c fft.c id3tag.c mpglib_interface.c presets.c quantize.c reservoir.c tables.c util.c VbrTag.c encoder.c gain_analysis.c lame.c newmdct.c psymodel.c quantize_pvt.c set_get.c takehiro.c vbrquantize.c version.c lame_util.c

    LOCAL_LDLIBS += -llog

    include $(BUILD_SHARED_LIBRARY)

  7. Create Application.mk

    APP_PLATFORM := android-9

    APP_ABI := all //output .so version, all means all

    APP_CFLAGS += -DSTDC_HEADERS

Write the code to call the C side in the Java layer

    public class LameUtil {
    
    
        static{
            System.loadLibrary("mp3lame");
        }

    /**
     * Initialize LAME.
     */
    public native static void init(int inSamplerate, int inChannel,
                int outSamplerate, int outBitrate, int quality);


    /**
     * Encode buffer to mp3.
     */
    public native static int encode(short[] bufferLeft, short[] bufferRight,
                                    int samples, byte[] mp3buf);

    /**
     * Flush LAME buffer.
     */
    public native static int flush(byte[] mp3buf);

    /**
     * Close LAME.
     */
    public native static void close();
    }

Compile the header file

jdk_1.7 and above directly to the project src directory, and below to the class directory

After such success, the following files will be generated in the jni directory

Look at the content of the generated file


    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class com_autolink_mp3library_util_LameUtil */

    #ifndef _Included_com_autolink_mp3library_util_LameUtil
    #define _Included_com_autolink_mp3library_util_LameUtil
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     com_autolink_mp3library_util_LameUtil
     * Method:    init
     * Signature: (IIIII)V
     */
    JNIEXPORT void JNICALL Java_com_autolink_mp3library_util_LameUtil_init
      (JNIEnv *, jclass, jint, jint, jint, jint, jint);

    /*
     * Class:     com_autolink_mp3library_util_LameUtil
     * Method:    encode
     * Signature: ([S[SI[B)I
     */
    JNIEXPORT jint JNICALL Java_com_autolink_mp3library_util_LameUtil_encode
      (JNIEnv *, jclass, jshortArray, jshortArray, jint, jbyteArray);

    /*
     * Class:     com_autolink_mp3library_util_LameUtil
     * Method:    flush
     * Signature: ([B)I
     */
    JNIEXPORT jint JNICALL Java_com_autolink_mp3library_util_LameUtil_flush
      (JNIEnv *, jclass, jbyteArray);

    /*
     * Class:     com_autolink_mp3library_util_LameUtil
     * Method:    close
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_com_autolink_mp3library_util_LameUtil_close
      (JNIEnv *, jclass);

    #ifdef __cplusplus
    }
    #endif
    #endif

Write local C language code to realize transcoding of audio files


    #include "lame.h"
    #include "com_autolink_mp3library_util_LameUtil.h"
    #include <stdio.h>
    #include <jni.h>

    static lame_global_flags *lame = NULL;

    JNIEXPORT void JNICALL Java_com_autolink_mp3library_util_LameUtil_init(
            JNIEnv *env, jclass cls, jint inSamplerate, jint inChannel, jint outSamplerate, jint outBitrate, jint quality) {
        if (lame != NULL) {
            lame_close(lame);
            lame = NULL;
        }
        lame = lame_init();
        lame_set_in_samplerate(lame, inSamplerate);
        lame_set_num_channels(lame, inChannel);//杈撳叆娴佺殑澹伴亾
        lame_set_out_samplerate(lame, outSamplerate);
        lame_set_brate(lame, outBitrate);
        lame_set_quality(lame, quality);
        lame_init_params(lame);
    }

    JNIEXPORT jint JNICALL Java_com_autolink_mp3library_util_LameUtil_encode(
            JNIEnv *env, jclass cls, jshortArray buffer_l, jshortArray buffer_r,
            jint samples, jbyteArray mp3buf) {
        jshort* j_buffer_l = (*env)->GetShortArrayElements(env, buffer_l, NULL);

        jshort* j_buffer_r = (*env)->GetShortArrayElements(env, buffer_r, NULL);

        const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);
        jbyte* j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);

        int result = lame_encode_buffer(lame, j_buffer_l, j_buffer_r,
                samples, j_mp3buf, mp3buf_size);

        (*env)->ReleaseShortArrayElements(env, buffer_l, j_buffer_l, 0);
        (*env)->ReleaseShortArrayElements(env, buffer_r, j_buffer_r, 0);
        (*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);

        return result;
    }

    JNIEXPORT jint JNICALL Java_com_autolink_mp3library_util_LameUtil_flush(
            JNIEnv *env, jclass cls, jbyteArray mp3buf) {
        const jsize mp3buf_size = (*env)->GetArrayLength(env, mp3buf);
        jbyte* j_mp3buf = (*env)->GetByteArrayElements(env, mp3buf, NULL);

        int result = lame_encode_flush(lame, j_mp3buf, mp3buf_size);

        (*env)->ReleaseByteArrayElements(env, mp3buf, j_mp3buf, 0);

        return result;
    }

    JNIEXPORT void JNICALL Java_com_autolink_mp3library_util_LameUtil_close
    (JNIEnv *env, jclass cls) {
        lame_close(lame);
        lame = NULL;
    }

Create a new C++ compiler

Right-click the project Properties->Builders and click "New" in the right tab to create a new compiler (select Program):

Configure the Main, Refresh and Build Options tabs, as shown in the figure

After that, after cleaning the project, the .so file will be automatically compiled

Finally, add the following two permissions to the project

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

how to use it


    package com.autolink.mp3library;

    import java.io.File;
    import java.io.IOException;

    import com.autolink.mp3library.util.MP3Recorder;

    import android.app.Activity;
    import android.os.Bundle;
    import android.os.Environment;
    import android.view.View;
    import android.view.View.OnClickListener;


    public class MainActivity extends Activity {
    
    

        private MP3Recorder mRecorder = new MP3Recorder(new File(Environment.getExternalStorageDirectory(), "test.mp3"));

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);

            findViewById(R.id.StartButton).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    try {
                        mRecorder.start();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });

            findViewById(R.id.StopButton).setOnClickListener(new OnClickListener() {

                @Override
                public void onClick(View v) {
                    mRecorder.stop();
                }
            });
        }

        @Override
        protected void onDestroy() {
            super.onDestroy();
            mRecorder.stop();
        }

    }

Reference link:

http://blog.csdn.net/allen315410/article/details/42456661

http://blog.csdn.net/whurs/article/details/45487521

Android studio can see the following

http://www.cnblogs.com/ct2011/p/4080193.html

Guess you like

Origin blog.csdn.net/hehota/article/details/69942080