1 /*
2 * Copyright 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <jni.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <unistd.h>
22
23 #include <android/log.h>
24
25 // parselib includes
26 #include <stream/MemInputStream.h>
27 #include <wav/WavStreamReader.h>
28
29 #include <player/OneShotSampleSource.h>
30 #include <player/SimpleMultiPlayer.h>
31
32 static const char* TAG = "DrumPlayerJNI";
33
34 // JNI functions are "C" calling convention
35 #ifdef __cplusplus
36 extern "C" {
37 #endif
38
39 using namespace iolib;
40 using namespace parselib;
41
42 static SimpleMultiPlayer sDTPlayer;
43
44 /**
45 * Native (JNI) implementation of DrumPlayer.setupAudioStreamNative()
46 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_setupAudioStreamNative(JNIEnv * env,jobject,jint numChannels)47 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_setupAudioStreamNative(
48 JNIEnv* env, jobject, jint numChannels) {
49 __android_log_print(ANDROID_LOG_INFO, TAG, "%s", "init()");
50
51 // we know in this case that the sample buffers are all 1-channel, 41K
52 sDTPlayer.setupAudioStream(numChannels);
53 }
54
55 JNIEXPORT void JNICALL
Java_com_plausiblesoftware_drumthumper_DrumPlayer_startAudioStreamNative(JNIEnv * env,jobject thiz)56 Java_com_plausiblesoftware_drumthumper_DrumPlayer_startAudioStreamNative(
57 JNIEnv *env, jobject thiz) {
58 sDTPlayer.startStream();
59 }
60
61 /**
62 * Native (JNI) implementation of DrumPlayer.teardownAudioStreamNative()
63 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_teardownAudioStreamNative(JNIEnv *,jobject)64 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_teardownAudioStreamNative(JNIEnv* , jobject) {
65 __android_log_print(ANDROID_LOG_INFO, TAG, "%s", "deinit()");
66
67 // we know in this case that the sample buffers are all 1-channel, 44.1K
68 sDTPlayer.teardownAudioStream();
69 }
70
71 /**
72 * Native (JNI) implementation of DrumPlayer.allocSampleDataNative()
73 */
74 /**
75 * Native (JNI) implementation of DrumPlayer.loadWavAssetNative()
76 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_loadWavAssetNative(JNIEnv * env,jobject,jbyteArray bytearray,jint index,jfloat pan,jint channels)77 JNIEXPORT jboolean JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_loadWavAssetNative(
78 JNIEnv* env, jobject, jbyteArray bytearray, jint index, jfloat pan, jint channels) {
79 int len = env->GetArrayLength (bytearray);
80
81 unsigned char* buf = new unsigned char[len];
82 env->GetByteArrayRegion (bytearray, 0, len, reinterpret_cast<jbyte*>(buf));
83
84 MemInputStream stream(buf, len);
85
86 WavStreamReader reader(&stream);
87 reader.parse();
88
89 jboolean isFormatValid = reader.getNumChannels() == channels;
90
91 SampleBuffer* sampleBuffer = new SampleBuffer();
92 sampleBuffer->loadSampleData(&reader);
93
94 OneShotSampleSource* source = new OneShotSampleSource(sampleBuffer, pan);
95 sDTPlayer.addSampleSource(source, sampleBuffer);
96
97 delete[] buf;
98
99 return isFormatValid;
100 }
101
102 /**
103 * Native (JNI) implementation of DrumPlayer.unloadWavAssetsNative()
104 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_unloadWavAssetsNative(JNIEnv * env,jobject)105 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_unloadWavAssetsNative(JNIEnv* env, jobject) {
106 sDTPlayer.unloadSampleData();
107 }
108
109 /**
110 * Native (JNI) implementation of DrumPlayer.trigger()
111 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_trigger(JNIEnv * env,jobject,jint index)112 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_trigger(JNIEnv* env, jobject, jint index) {
113 sDTPlayer.triggerDown(index);
114 }
115
116 /**
117 * Native (JNI) implementation of DrumPlayer.trigger()
118 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_stopTrigger(JNIEnv * env,jobject,jint index)119 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_stopTrigger(JNIEnv* env, jobject, jint index) {
120 sDTPlayer.triggerUp(index);
121 }
122
123 /**
124 * Native (JNI) implementation of DrumPlayer.getOutputReset()
125 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_getOutputReset(JNIEnv *,jobject)126 JNIEXPORT jboolean JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_getOutputReset(JNIEnv*, jobject) {
127 return sDTPlayer.getOutputReset();
128 }
129
130 /**
131 * Native (JNI) implementation of DrumPlayer.clearOutputReset()
132 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_clearOutputReset(JNIEnv *,jobject)133 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_clearOutputReset(JNIEnv*, jobject) {
134 sDTPlayer.clearOutputReset();
135 }
136
137 /**
138 * Native (JNI) implementation of DrumPlayer.restartStream()
139 */
Java_com_plausiblesoftware_drumthumper_DrumPlayer_restartStream(JNIEnv *,jobject)140 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_restartStream(JNIEnv*, jobject) {
141 sDTPlayer.resetAll();
142 if (sDTPlayer.openStream() && sDTPlayer.startStream()){
143 __android_log_print(ANDROID_LOG_INFO, TAG, "openStream successful");
144 } else {
145 __android_log_print(ANDROID_LOG_ERROR, TAG, "openStream failed");
146 }
147 }
148
Java_com_plausiblesoftware_drumthumper_DrumPlayer_setPan(JNIEnv * env,jobject thiz,jint index,jfloat pan)149 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_setPan(
150 JNIEnv *env, jobject thiz, jint index, jfloat pan) {
151 sDTPlayer.setPan(index, pan);
152 }
153
Java_com_plausiblesoftware_drumthumper_DrumPlayer_getPan(JNIEnv * env,jobject thiz,jint index)154 JNIEXPORT jfloat JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_getPan(
155 JNIEnv *env, jobject thiz, jint index) {
156 return sDTPlayer.getPan(index);
157 }
158
Java_com_plausiblesoftware_drumthumper_DrumPlayer_setGain(JNIEnv * env,jobject thiz,jint index,jfloat gain)159 JNIEXPORT void JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_setGain(
160 JNIEnv *env, jobject thiz, jint index, jfloat gain) {
161 sDTPlayer.setGain(index, gain);
162 }
163
Java_com_plausiblesoftware_drumthumper_DrumPlayer_getGain(JNIEnv * env,jobject thiz,jint index)164 JNIEXPORT jfloat JNICALL Java_com_plausiblesoftware_drumthumper_DrumPlayer_getGain(
165 JNIEnv *env, jobject thiz, jint index) {
166 return sDTPlayer.getGain(index);
167 }
168
169 #ifdef __cplusplus
170 }
171 #endif
172