# # # introduction

We use this time is fMOD this library, FMOD is sound engine game development revolution engine, the famous game development engine CosCos2D, U3D package this library.

The purpose of learning NDK is to enable our apps to use the excellent libraries that have been open source for many years in C/C++. For example, our Android itself has already packaged OpenGL, SQLite and other excellent C/C++ open source libraries into the Android platform, we only need to use the upper Java Native interface can be very convenient to use these functions.

###NDK process for using the open source library FMOD

The main thing in this process is to learn how to introduce a completely unused C/C++ library, rather than the use of the library itself.

#### Create native Support APP project

Open Android Studio and create a native Support project.

### Copy resources

Register on fMOD’s website and download the official Android VERSION of the API.

Fsbank, lowlevel, studio:

  1. Fsbank, bank is an FMOD concept, including some sound events, can also be made through FMOD Studio, here is to make by code.
  2. Lowlevel, where all the files we need are here, includes basic sound processing.
  3. Studio, the API that’s stored here is related to the interface, we don’t need to use the interface.

We need in fmodstudioapi10903android \ API \ lowlevel of resources, there are three folders:

  1. CPP: CPP: CPP: CPP: CPP: CPP: CPP: CPP: CPP
  2. The required INC directory, which we need to copy directly into our Android project.
  3. The lib directory contains some pre-compiled so libraries and a JAR package that needs to be copied into our project.

Then create the CPP directory and add the header files and source files required by fMOD. (Copy what you need, analyze the fMOD header file and read it carefully.)

Fmod provides some pre-compiled so libraries and jar packages, so we need to copy them to the libs directory, and then remember to add them to the build.gradle script of our app:

sourceSets {
    main {
        jniLibs.srcDirs = ['libs']
    }
}
Copy the code

### Modify the cmakelists.txt file

In this file, in addition to adding our own libraries, we also need to add fMOD’s precompiled libraries and link them to our own library.

The minimum VERSION # configure CMake cmake_minimum_required (VERSION 3.4.1 track) # configuration project path # set (path_project/home/wuhuannan/AndroidPrj/VoiceChange) Set (path_project D: / AndroidStudio/VoiceChange) # add write their own library add_library (effect - lib SHARED SRC/main/CPP/effect_fix CPP) Add_library (fmod SHARED with IMPORTED) add_library(fmod SHARED with IMPORTED) Set_target_properties (fMOD PROPERTIES IMPORTED_LOCATION ${path_project}/app/libs/${ANDROID_ABI}/libfmod.so) set_target_properties( libfmodL PROPERTIES IMPORTED_LOCATION ${path_project}/app/libs/${ANDROID_ABI}/libfmodL.so ) Find_library (log-lib log) # Link the required library to your own target_link_libraries(effect-lib ${log-lib} fmod libfmodL )Copy the code

Note the differences with NDK-build:

Ndk-build can be written as follows:

Android. Mk file:

LOCAL_PATH := $(call my-dir) ## Add two precompiled libraries include $(CLEAR_VARS) LOCAL_MODULE := fmod LOCAL_SRC_FILES := libfmod include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) LOCAL_MODULE := fmodL LOCAL_SRC_FILES := libfmodL.so include $(PREBUILT_SHARED_LIBRARY) include $(CLEAR_VARS) # LOCAL_MODULE := effect_fix. CPP LOCAL_SHARED_LIBRARIES := fmod fmodL LOCAL_LDLIBS := LOCAL_CPP_FEATURES := exceptions include $(BUILD_SHARED_LIBRARY)Copy the code

Application. Mk file:

## support C++ exception handling, standard mo plate (STL) APP_STL := gnustl_staticCopy the code

### Sync projects

In the process of synchronization, we may encounter many problems, such as:

  1. The required header file was not added.
  2. Include header file path is correct.
  3. Is the path of the precompiled SO library correct?
  4. If it’s an NDK-build, check if exception handling, STL, and so on are supported.

### Create Java Native methods

package com.nan.voicechange;

public class VoiceEffectUtils {

    public static final int TYPE_NORMAL = 0;
    public static final int TYPE_LUOLI = 1;
    public static final int TYPE_DASHU = 2;
    public static final int TYPE_JINGSONG = 3;
    public static final int TYPE_GAOGUAI = 4;
    public static final int TYPE_KONGLING = 5;

    static {
        System.loadLibrary("fmodL");
        System.loadLibrary("fmod");
        System.loadLibrary("effect-lib");
    }

    public native static void playFixVoice(String path, int type);

}
Copy the code

### Implement native methods in C/C++ layer

#include "inc/fmod.hpp" #include <stdlib.h> #include <unistd.h> #include <jni.h> #include <android/log.h> // log output macro definition #define LOGI(FORMAT, ...) __android_log_print(ANDROID_LOG_INFO,"jason",FORMAT,##__VA_ARGS__); #define LOGE(FORMAT, ...) __android_log_print(ANDROID_LOG_ERROR,"jason",FORMAT,##__VA_ARGS__); #define TYPE_NORMAL 0 #define TYPE_LUOLI 1 #define TYPE_DASHU 2 #define TYPE_JINGSONG 3 #define TYPE_GAOGUAI 4// #define TYPE_KONGLING 5// void // use namespace fmod; Extern "C" {// Implementation of Java native methods JNIEXPORT void JNICALL Java_com_nan_voicechange_VoiceEffectUtils_playFixVoice(JNIEnv *env, jclass type_, jstring path_, jint type) { const char *path = env->GetStringUTFChars(path_, NULL); System *system = NULL; Sound *sound = NULL; Channel *channel = NULL; DSP *dsp = NULL; bool isPlaying = true; float frequency; //fmod initializes System_Create(&system); // Specify the maximum number of tracks and other parameters system->init(32, FMOD_INIT_NORMAL, NULL); // Create a sound object system->createSound(path, FMOD_DEFAULT, NULL, &sound); Switch (type) {case TYPE_NORMAL: // Update system->playSound(sound, 0, false, &channel); break; case TYPE_LUOLI: System ->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, & DSP); createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, & DSP); DSP ->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 2.5); System ->playSound(sound, 0, false, & Channel); // Add the handler to Channel's track 0. channel->addDSP(0, dsp); LOGE("%s", "luo li"); break; DSP System ->createDSPByType(FMOD_DSP_TYPE_PITCHSHIFT, & DSP); DSP ->setParameterFloat(FMOD_DSP_PITCHSHIFT_PITCH, 0.8); System ->playSound(sound, 0, false, & Channel); channel->addDSP(0, dsp); LOGE("%s", "da shu"); break; Case TYPE_JINGSONG: // system->createDSPByType(FMOD_DSP_TYPE_TREMOLO, & DSP); DSP - > setParameterFloat (FMOD_DSP_TREMOLO_SKEW, 0.5); system->playSound(sound, 0, false, &channel); channel->addDSP(0, dsp); break; System ->playSound(sound, 0, false, &channel); channel->getFrequency(&frequency); Frequency = frequency * 1.6; channel->setFrequency(frequency); LOGI("%s", "fix gaoguai"); break; Case TYPE_KONGLING: // createDSPByType(FMOD_DSP_TYPE_ECHO, & DSP); dsp->setParameterFloat(FMOD_DSP_ECHO_DELAY, 300); dsp->setParameterFloat(FMOD_DSP_ECHO_FEEDBACK, 20); system->playSound(sound, 0, false, &channel); channel->addDSP(0, dsp); LOGI("%s", "fix kongling"); break; default: break; } system->update(); While (isPlaying) {channel->isPlaying(&isPlaying); usleep(1 * 1000 * 1000); //CMake supports exception handling by default. // Try {// //} catch (...) {// //} // Sound ->release(); system->close(); system->release(); env->ReleaseStringUTFChars(path_, path); }}Copy the code

Relevant source: https://github.com/huannan/VoiceChange

If you feel that my words are helpful to you, welcome to pay attention to my public number:

My group welcomes everyone to come in and discuss all kinds of technical and non-technical topics. If you are interested, please add my wechat huannan88 and I will take you into our group.