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 package com.plausiblesoftware.drumthumper 17 18 import android.content.res.AssetManager 19 import android.util.Log 20 import java.io.IOException 21 22 class DrumPlayer { 23 companion object { 24 // Sample attributes 25 val NUM_PLAY_CHANNELS: Int = 2 // The number of channels in the player Stream. 26 // Stereo Playback, set to 1 for Mono playback 27 28 // Sample Buffer IDs 29 val BASSDRUM: Int = 0 30 val SNAREDRUM: Int = 1 31 val CRASHCYMBAL: Int = 2 32 val RIDECYMBAL: Int = 3 33 val MIDTOM: Int = 4 34 val LOWTOM: Int = 5 35 val HIHATOPEN: Int = 6 36 val HIHATCLOSED: Int = 7 37 38 // initial pan position for each drum sample 39 val PAN_BASSDRUM: Float = 0f // Dead Center 40 val PAN_SNAREDRUM: Float = -0.75f // Mostly Left 41 val PAN_CRASHCYMBAL: Float = -0.75f // Mostly Left 42 val PAN_RIDECYMBAL: Float = 1.0f // Hard Right 43 val PAN_MIDTOM: Float = 0.25f // A little Right 44 val PAN_LOWTOM: Float = 0.75f // Mostly Right 45 val PAN_HIHATOPEN: Float = -1.0f // Hard Left 46 val PAN_HIHATCLOSED: Float = -1.0f // Hard Left 47 48 // Logging Tag 49 val TAG: String = "DrumPlayer" 50 } 51 setupAudioStreamnull52 fun setupAudioStream() { 53 setupAudioStreamNative(NUM_PLAY_CHANNELS) 54 } 55 startAudioStreamnull56 fun startAudioStream() { 57 startAudioStreamNative() 58 } 59 teardownAudioStreamnull60 fun teardownAudioStream() { 61 teardownAudioStreamNative() 62 } 63 64 // asset-based samples loadWavAssetsnull65 fun loadWavAssets(assetMgr: AssetManager) { 66 loadWavAsset(assetMgr, "KickDrum.wav", BASSDRUM, PAN_BASSDRUM) 67 loadWavAsset(assetMgr, "SnareDrum.wav", SNAREDRUM, PAN_SNAREDRUM) 68 loadWavAsset(assetMgr, "CrashCymbal.wav", CRASHCYMBAL, PAN_CRASHCYMBAL) 69 loadWavAsset(assetMgr, "RideCymbal.wav", RIDECYMBAL, PAN_RIDECYMBAL) 70 loadWavAsset(assetMgr, "MidTom.wav", MIDTOM, PAN_MIDTOM) 71 loadWavAsset(assetMgr, "LowTom.wav", LOWTOM, PAN_LOWTOM) 72 loadWavAsset(assetMgr, "HiHat_Open.wav", HIHATOPEN, PAN_HIHATOPEN) 73 loadWavAsset(assetMgr, "HiHat_Closed.wav", HIHATCLOSED, PAN_HIHATCLOSED) 74 } 75 unloadWavAssetsnull76 fun unloadWavAssets() { 77 unloadWavAssetsNative() 78 } 79 loadWavAssetnull80 private fun loadWavAsset(assetMgr: AssetManager, assetName: String, index: Int, pan: Float) { 81 try { 82 val assetFD = assetMgr.openFd(assetName) 83 val dataStream = assetFD.createInputStream() 84 val dataLen = assetFD.getLength().toInt() 85 val dataBytes = ByteArray(dataLen) 86 dataStream.read(dataBytes, 0, dataLen) 87 loadWavAssetNative(dataBytes, index, pan) 88 assetFD.close() 89 } catch (ex: IOException) { 90 Log.i(TAG, "IOException$ex") 91 } 92 } 93 setupAudioStreamNativenull94 private external fun setupAudioStreamNative(numChannels: Int) 95 private external fun startAudioStreamNative() 96 private external fun teardownAudioStreamNative() 97 98 private external fun loadWavAssetNative(wavBytes: ByteArray, index: Int, pan: Float) 99 private external fun unloadWavAssetsNative() 100 101 external fun trigger(drumIndex: Int) 102 external fun stopTrigger(drumIndex: Int) 103 104 external fun setPan(index: Int, pan: Float) 105 external fun getPan(index: Int): Float 106 107 external fun setGain(index: Int, gain: Float) 108 external fun getGain(index: Int): Float 109 110 external fun getOutputReset() : Boolean 111 external fun clearOutputReset() 112 113 external fun restartStream() 114 } 115