Skip to content

Commit

Permalink
Merge branch 'release-0.2.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
FYLSunghwan committed Sep 12, 2020
2 parents af4e512 + f948170 commit a947d49
Show file tree
Hide file tree
Showing 121 changed files with 51,740 additions and 11 deletions.
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,9 @@ android/keystores/debug.keystore

# generated by bob
lib/

# Android NDK
android/*.iml
android/ndkHelperBin
android/.cxx
android/.externalNativeBuild
7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# react-native-piano-sampler

[![NPM](https://nodei.co/npm/react-native-piano-sampler.png?compact=true)](https://nodei.co/npm/react-native-piano-sampler/)

React Native Piano Sampler : Reads sf2 with FluidSynth(on Android) or sfz with AudioKit(on iOS)

- [x] iOS/iPadOS Implementation
- [ ] Android Implementation
- [x] Android Implementation

## Installation

Expand Down Expand Up @@ -33,7 +35,8 @@ npm install --save react-native-piano-sampler
- Goto the iOS project folder, and do `pod install`

### Prerequisites (Android)
- Preparing
- Download the [soudfont(Full Grand Piano)](https://drive.google.com/file/d/1JHae8NALSvLDuF9nFqtqqipcY9Fo1fuD/view?usp=sharing) and move to `{ProjDirectory}/android/app/src/main/assets`.
- You are good to go :smile:


### Usage in React Native Code
Expand Down
16 changes: 13 additions & 3 deletions android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "com.android.tools.build:gradle:3.5.0"
// noinspection DifferentKotlinGradleVersion
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
Expand All @@ -33,9 +33,13 @@ android {
targetSdkVersion getExtOrIntegerDefault('targetSdkVersion')
versionCode 1
versionName "1.0"

externalNativeBuild {
cmake {
cppFlags ""
}
}
}

buildTypes {
release {
minifyEnabled false
Expand All @@ -48,6 +52,11 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
externalNativeBuild {
cmake {
path "src/main/jni/fluidsynth/android/CMakeLists.txt"
}
}
}

repositories {
Expand Down Expand Up @@ -127,4 +136,5 @@ dependencies {
// noinspection GradleDynamicVersion
api 'com.facebook.react:react-native:+'
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'com.squareup.okio:okio:1.14.0'
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.reactnativepianosampler

class NativeLibJNI {
external fun init(sf2path: String)
external fun noteOn(key: Int, velocity: Int)
external fun noteOff(key: Int)
external fun programChange(channel: Int, programNumber: Int) : Boolean
external fun destroy()
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,76 @@
package com.reactnativepianosampler

import com.facebook.react.bridge.LifecycleEventListener
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import com.facebook.react.bridge.Promise
import okio.Okio
import java.io.File

class PianoSamplerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
class PianoSamplerModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext), LifecycleEventListener {

companion object {

private const val SF2_FILE_NAME = "Full Grand Piano.sf2"

// Used to load the 'fluidsynth' library on application startup.
// Check the CMakeLists.txt that is referenced in app/build.gradle,
// within it there is the statement 'add_library' which specifies
// this identifier.
init {
System.loadLibrary("fluidsynth")
}
}

private var context:ReactApplicationContext = reactContext

private val nativeLibJNI = NativeLibJNI()
private lateinit var sf2file: File

init {
context.addLifecycleEventListener(this);
}

override fun getName(): String {
return "PianoSampler"
}

@ReactMethod
fun playNote(midiNum: Int, velocity: Int) {
print("Kotlin> playNote");
nativeLibJNI.noteOn(midiNum, velocity)
}

@ReactMethod
fun stopNote(midiNum: Int) {
print("Kotlin> stopNote");
nativeLibJNI.noteOff(midiNum);
}

@ReactMethod
fun prepare() {
print("Kotlin> prepare");
sf2file = File(context.filesDir, SF2_FILE_NAME)
copySF2IfNecessary() // sf2 file needs to be in internal directory, not assets
nativeLibJNI.init(sf2file.absolutePath)
}

private fun copySF2IfNecessary() {
if (sf2file.exists() && sf2file.length() > 0) return
Okio.source(context.assets.open(SF2_FILE_NAME)).use { a ->
Okio.buffer(Okio.sink(sf2file)).use { b ->
b.writeAll(a)
}
}
}

override fun onHostResume() {

}

override fun onHostPause() {

}

override fun onHostDestroy() {
nativeLibJNI.destroy()
}

}
86 changes: 86 additions & 0 deletions android/src/main/jni/fluidsynth/android/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
cmake_minimum_required(VERSION 3.4.1)

set(src_DIR ../src)

set(fluidsynth_sources
${src_DIR}/midi/fluid_midi.c
${src_DIR}/midi/fluid_midi_router.c
${src_DIR}/midi/fluid_seq.c
${src_DIR}/midi/fluid_seqbind.c
${src_DIR}/rvoice/fluid_adsr_env.c
${src_DIR}/rvoice/fluid_chorus.c
${src_DIR}/rvoice/fluid_iir_filter.c
${src_DIR}/rvoice/fluid_lfo.c
${src_DIR}/rvoice/fluid_rev.c
${src_DIR}/rvoice/fluid_rvoice.c
${src_DIR}/rvoice/fluid_rvoice_dsp.c
${src_DIR}/rvoice/fluid_rvoice_event.c
${src_DIR}/rvoice/fluid_rvoice_mixer.c
${src_DIR}/sfloader/fluid_defsfont.c
${src_DIR}/sfloader/fluid_ramsfont.c
${src_DIR}/sfloader/fluid_sfont.c
${src_DIR}/synth/fluid_chan.c
${src_DIR}/synth/fluid_event.c
${src_DIR}/synth/fluid_gen.c
${src_DIR}/synth/fluid_mod.c
${src_DIR}/synth/fluid_synth.c
${src_DIR}/synth/fluid_tuning.c
${src_DIR}/synth/fluid_voice.c
${src_DIR}/synth/fluid_synth_monopoly.c
${src_DIR}/utils/fluid_conv.c
${src_DIR}/utils/fluid_hash.c
${src_DIR}/utils/fluid_list.c
${src_DIR}/utils/fluid_ringbuffer.c
${src_DIR}/utils/fluid_settings.c
${src_DIR}/bindings/fluid_filerenderer.c
${src_DIR}/drivers/fluid_adriver.c
${src_DIR}/drivers/fluid_opensles.c
${src_DIR}/utils/fluid_sys.c
src/bindings/fluid_cmd.c
src/drivers/fluid_mdriver.c
../../native-lib.cpp # This line needs to be removed; It's only for testing purposes
)

set ( public_main_HEADER
${CMAKE_BINARY_DIR}/include/fluidsynth.h
)

configure_file ( ../include/fluidsynth.cmake
${public_main_HEADER} )

add_library(fluidsynth SHARED ${fluidsynth_sources})

if(ANDROID_ABI STREQUAL "armeabi-v7a")
target_compile_options(fluidsynth PRIVATE -DWITH_FLOAT)
endif()
if(ANDROID_ABI STREQUAL "x86")
target_compile_options(fluidsynth PRIVATE -DWITH_FLOAT)
endif()

# Specify directories which the compiler should look for headers
target_include_directories(fluidsynth PRIVATE
. include
${src_DIR}/../include
${src_DIR}/synth
${src_DIR}/midi
${src_DIR}/rvoice
${src_DIR}/sfloader
${src_DIR}/utils
${src_DIR}/bindings
${src_DIR}/drivers
${CMAKE_BINARY_DIR}/include
)

target_include_directories(fluidsynth INTERFACE
. include
${src_DIR}/../include
${CMAKE_BINARY_DIR}/include
)

target_compile_options(fluidsynth
PRIVATE -Wall
PRIVATE -DHAVE_CONFIG_H
PRIVATE -Wno-unused-variable
PRIVATE "$<$<CONFIG:DEBUG>:-Werror>") # Only include -Werror when building debug config

target_link_libraries (fluidsynth OpenSLES log)
Loading

0 comments on commit a947d49

Please sign in to comment.