Added control of gain for each drum and a mix UI for gain and pan.
diff --git a/samples/build.gradle b/samples/build.gradle
index d522839..d51e478 100644
--- a/samples/build.gradle
+++ b/samples/build.gradle
@@ -27,7 +27,7 @@
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath 'com.android.tools.build:gradle:3.6.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
diff --git a/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp b/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp
index 1517a78..274036f 100644
--- a/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp
+++ b/samples/drumthumper/src/main/cpp/DrumPlayerJNI.cpp
@@ -128,6 +128,27 @@
}
}
+JNIEXPORT void JNICALL Java_com_google_oboe_sample_drumthumper_DrumPlayer_setPan(
+ JNIEnv *env, jobject thiz, jint index, jfloat pan) {
+ sDTPlayer.setPan(index, pan);
+}
+
+JNIEXPORT jfloat JNICALL Java_com_google_oboe_sample_drumthumper_DrumPlayer_getPan(
+ JNIEnv *env, jobject thiz, jint index) {
+ // TODO: implement getPan()
+ return sDTPlayer.getPan(index);
+}
+
+JNIEXPORT void JNICALL Java_com_google_oboe_sample_drumthumper_DrumPlayer_setGain(
+ JNIEnv *env, jobject thiz, jint index, jfloat gain) {
+ sDTPlayer.setGain(index, gain);
+}
+
+JNIEXPORT jfloat JNICALL Java_com_google_oboe_sample_drumthumper_DrumPlayer_getGain(
+ JNIEnv *env, jobject thiz, jint index) {
+ return sDTPlayer.getGain(index);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumPlayer.kt b/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumPlayer.kt
index 2937600..598766c 100644
--- a/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumPlayer.kt
+++ b/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumPlayer.kt
@@ -95,6 +95,12 @@
external fun trigger(drumIndex: Int)
+ external fun setPan(index: Int, pan: Float)
+ external fun getPan(index: Int): Float
+
+ external fun setGain(index: Int, gain: Float)
+ external fun getGain(index: Int): Float
+
external fun getOutputReset() : Boolean
external fun clearOutputReset()
diff --git a/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumThumperActivity.kt b/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumThumperActivity.kt
index b8f9811..cebc5cc 100644
--- a/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumThumperActivity.kt
+++ b/samples/drumthumper/src/main/java/com/google/oboe/sample/drumthumper/DrumThumperActivity.kt
@@ -21,6 +21,7 @@
import android.media.AudioManager
import android.os.Bundle
import android.util.Log
+import android.widget.SeekBar
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
@@ -30,8 +31,11 @@
import java.time.LocalDateTime;
import kotlin.concurrent.schedule
+import kotlin.math.roundToInt
-class DrumThumperActivity : AppCompatActivity(), TriggerPad.DrumPadTriggerListener {
+class DrumThumperActivity : AppCompatActivity(),
+ TriggerPad.DrumPadTriggerListener,
+ SeekBar.OnSeekBarChangeListener {
private val TAG = "DrumThumperActivity"
private var mAudioMgr: AudioManager? = null
@@ -99,6 +103,26 @@
}
}
+ // UI Helpers
+ fun gainPosToGainVal(pos: Int) : Float {
+ // map 0 -> 200 to 0.0f -> 2.0f
+ return pos.toFloat() / 100.0f
+ }
+
+ fun gainValToGainPos(value: Float) : Int {
+ return (value * 100.0f).toInt()
+ }
+
+ fun panPosToPanVal(pos: Int) : Float {
+ // map 0 -> 200 to -1.0f -> 1..0f
+ return (pos.toFloat() - 100.0f) / 100.0f
+ }
+
+ fun panValToPanPos(value: Float) : Int {
+ // map -1.0f -> 1.0f to 0 -> 200
+ return ((value * 200.0f) + 100.0f).toInt()
+ }
+
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -125,46 +149,79 @@
setContentView(R.layout.drumthumper_activity)
// hookup the UI
- run {
- var pad: TriggerPad = findViewById(R.id.kickPad)
- pad.addListener(this)
- }
+ var sb : SeekBar;
- run {
- var pad: TriggerPad = findViewById(R.id.snarePad)
- pad.addListener(this)
- }
+ // "Kick" drum
+ (findViewById(R.id.kickPad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.kickPan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.BASSDRUM)))
+ sb = (findViewById(R.id.kickGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain(DrumPlayer.BASSDRUM)))
- run {
- var pad: TriggerPad = findViewById(R.id.midTomPad)
- pad.addListener(this)
- }
+ // Snare drum
+ (findViewById(R.id.snarePad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.snarePan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.SNAREDRUM)))
+ sb = (findViewById(R.id.snareGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain(DrumPlayer.SNAREDRUM)))
- run {
- var pad: TriggerPad = findViewById(R.id.lowTomPad)
- pad.addListener(this)
- }
+ // Mid tom
+ (findViewById(R.id.midTomPad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.midTomPan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.MIDTOM)))
+ sb = (findViewById(R.id.midTomGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain((DrumPlayer.MIDTOM))))
- run {
- var pad: TriggerPad = findViewById(R.id.hihatOpenPad)
- pad.addListener(this)
- }
+ // Low tom
+ (findViewById(R.id.lowTomPad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.lowTomPan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.LOWTOM)))
+ sb = (findViewById(R.id.lowTomGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain(DrumPlayer.LOWTOM)))
- run {
- var pad: TriggerPad = findViewById(R.id.hihatClosedPad)
- pad.addListener(this)
- }
+ // Open hihat
+ (findViewById(R.id.hihatOpenPad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.hihatOpenPan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.HIHATOPEN)))
+ sb = (findViewById(R.id.hihatOpenGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain(DrumPlayer.HIHATOPEN)))
- run {
- var pad: TriggerPad = findViewById(R.id.ridePad)
- pad.addListener(this)
- }
+ // Closed hihat
+ (findViewById(R.id.hihatClosedPad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.hihatClosedPan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.HIHATCLOSED)))
+ sb = (findViewById(R.id.hihatClosedGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain(DrumPlayer.HIHATCLOSED)))
- run {
- var pad: TriggerPad = findViewById(R.id.crashPad)
- pad.addListener(this)
- }
+ // Ride cymbal
+ (findViewById(R.id.ridePad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.ridePan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.RIDECYMBAL)))
+ sb = (findViewById(R.id.rideGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain(DrumPlayer.RIDECYMBAL)))
+ // Crash cymbal
+ (findViewById(R.id.crashPad) as TriggerPad).addListener(this)
+ sb = (findViewById(R.id.crashPan) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(panValToPanPos(mDrumPlayer.getPan(DrumPlayer.CRASHCYMBAL)))
+ sb = (findViewById(R.id.crashGain) as SeekBar)
+ sb.setOnSeekBarChangeListener(this)
+ sb.setProgress(gainValToGainPos(mDrumPlayer.getGain(DrumPlayer.CRASHCYMBAL)))
}
override fun onPause() {
@@ -206,4 +263,52 @@
override fun triggerUp(pad: TriggerPad) {
// NOP
}
+
+ //
+ // SeekBar.OnSeekBarChangeListener
+ //
+ override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
+ when (seekBar!!.id) {
+ // BASSDRUM
+ R.id.kickGain -> mDrumPlayer.setGain(DrumPlayer.BASSDRUM, gainPosToGainVal(progress))
+ R.id.kickPan -> mDrumPlayer.setPan(DrumPlayer.BASSDRUM, panPosToPanVal(progress))
+
+ // SNAREDRUM
+ R.id.snareGain -> mDrumPlayer.setGain(DrumPlayer.SNAREDRUM, gainPosToGainVal(progress))
+ R.id.snarePan -> mDrumPlayer.setPan(DrumPlayer.SNAREDRUM, panPosToPanVal(progress))
+
+ // MIDTOM
+ R.id.midTomGain -> mDrumPlayer.setGain(DrumPlayer.MIDTOM, gainPosToGainVal(progress))
+ R.id.midTomPan -> mDrumPlayer.setPan(DrumPlayer.MIDTOM, panPosToPanVal(progress))
+
+ // LOWTOM
+ R.id.lowTomGain -> mDrumPlayer.setGain(DrumPlayer.LOWTOM, gainPosToGainVal(progress))
+ R.id.lowTomPan -> mDrumPlayer.setPan(DrumPlayer.LOWTOM, panPosToPanVal(progress))
+
+ // HIHATOPEN
+ R.id.hihatOpenGain -> mDrumPlayer.setGain(DrumPlayer.HIHATOPEN, gainPosToGainVal(progress))
+ R.id.hihatOpenPan -> mDrumPlayer.setPan(DrumPlayer.HIHATOPEN, panPosToPanVal(progress))
+
+ // HIHATCLOSED
+ R.id.hihatClosedGain -> mDrumPlayer.setGain(DrumPlayer.HIHATCLOSED, gainPosToGainVal(progress))
+ R.id.hihatClosedPan -> mDrumPlayer.setPan(DrumPlayer.HIHATCLOSED, panPosToPanVal(progress))
+
+ // RIDECYMBAL
+ R.id.rideGain -> mDrumPlayer.setGain(DrumPlayer.RIDECYMBAL, gainPosToGainVal(progress))
+ R.id.ridePan -> mDrumPlayer.setPan(DrumPlayer.RIDECYMBAL, panPosToPanVal(progress))
+
+ // CRASHCYMBAL
+ R.id.crashGain -> mDrumPlayer.setGain(DrumPlayer.CRASHCYMBAL, gainPosToGainVal(progress))
+ R.id.crashPan -> mDrumPlayer.setPan(DrumPlayer.CRASHCYMBAL, panPosToPanVal(progress))
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) {
+ // NOP
+ }
+
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ // NOP
+ }
+
}
diff --git a/samples/drumthumper/src/main/res/layout/drumthumper_activity.xml b/samples/drumthumper/src/main/res/layout/drumthumper_activity.xml
index 2ff2392..764aa16 100644
--- a/samples/drumthumper/src/main/res/layout/drumthumper_activity.xml
+++ b/samples/drumthumper/src/main/res/layout/drumthumper_activity.xml
@@ -20,21 +20,112 @@
android:layout_height="128dp"
android:orientation="horizontal">
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/kickPad"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Kick" />
-
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/snarePad"
+ <LinearLayout
android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Snare" />
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
+
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/kickPad"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Kick" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/kickPan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/kickGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
+
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/snarePad"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Snare" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/snarePan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/snareGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+
+ </LinearLayout>
+ </LinearLayout>
</LinearLayout>
<LinearLayout
@@ -42,21 +133,112 @@
android:layout_height="128dp"
android:orientation="horizontal">
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/hihatOpenPad"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Open Hat" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/hihatClosedPad"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Closed Hat" />
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/hihatOpenPad"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Open Hat" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/hihatOpenPan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/hihatOpenGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
+
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/hihatClosedPad"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Closed Hat" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/hihatClosedPan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/hihatClosedGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+ </LinearLayout>
</LinearLayout>
<LinearLayout
@@ -64,21 +246,111 @@
android:layout_height="128dp"
android:orientation="horizontal">
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/midTomPad"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Mid Tom" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/lowTomPad"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Low Tom" />
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/midTomPad"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Mid Tom" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/midTomPan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/midTomGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
+
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/lowTomPad"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Low Tom" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/lowTomPan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/lowTomGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+ </LinearLayout>
</LinearLayout>
<LinearLayout
@@ -86,22 +358,111 @@
android:layout_height="128dp"
android:orientation="horizontal">
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/ridePad"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Ride" />
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
- <com.google.oboe.sample.drumthumper.TriggerPad
- android:id="@+id/crashPad"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:padding="5dp"
- android:text="Crash" />
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/ridePad"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Ride" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/ridePan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/rideGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="wrap_content"
+ android:layout_height="128dp"
+ android:layout_weight=".5"
+ android:orientation="vertical">
+
+ <com.google.oboe.sample.drumthumper.TriggerPad
+ android:id="@+id/crashPad"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="5dp"
+ android:text="Crash" />
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="P:"/>
+
+ <SeekBar
+ android:id="@+id/crashPan"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="G:"/>
+
+ <SeekBar
+ android:id="@+id/crashGain"
+ style="@android:style/Widget.DeviceDefault.SeekBar"
+ android:layout_width="match_parent"
+ android:layout_height="20dp"
+ android:layout_marginTop="5dp"
+ android:max="200" />
+ </LinearLayout>
+ </LinearLayout>
</LinearLayout>
-
</LinearLayout>
diff --git a/samples/iolib/src/main/cpp/player/OneShotSampleSource.cpp b/samples/iolib/src/main/cpp/player/OneShotSampleSource.cpp
index 3828cff..ec1bf11 100644
--- a/samples/iolib/src/main/cpp/player/OneShotSampleSource.cpp
+++ b/samples/iolib/src/main/cpp/player/OneShotSampleSource.cpp
@@ -31,12 +31,12 @@
if (numWriteFrames != 0) {
// Mix in the samples
- // investigate unrolling this loop...
+ // investigate unrolling these loops...
const float* data = mSampleBuffer->getSampleData();
if (numChannels == 1) {
// MONO output
for (int32_t frameIndex = 0; frameIndex < numWriteFrames; frameIndex++) {
- outBuff[frameIndex] += data[mCurFrameIndex++];
+ outBuff[frameIndex] += data[mCurFrameIndex++] * mGain;
}
} else if (numChannels == 2) {
// STEREO output
diff --git a/samples/iolib/src/main/cpp/player/SampleSource.h b/samples/iolib/src/main/cpp/player/SampleSource.h
index bdfa692..3f18a7a 100644
--- a/samples/iolib/src/main/cpp/player/SampleSource.h
+++ b/samples/iolib/src/main/cpp/player/SampleSource.h
@@ -39,7 +39,7 @@
static constexpr float PAN_CENTER = 0.0f;
SampleSource(SampleBuffer *sampleBuffer, float pan)
- : mSampleBuffer(sampleBuffer), mCurFrameIndex(0), mIsPlaying(false) {
+ : mSampleBuffer(sampleBuffer), mCurFrameIndex(0), mIsPlaying(false), mGain(1.0f) {
setPan(pan);
}
virtual ~SampleSource() {}
@@ -57,10 +57,20 @@
} else {
mPan = pan;
}
+ calcGainFactors();
+ }
- // useful information: http://www.cs.cmu.edu/~music/icm-online/readings/panlaws/
- mLeftGain = (mPan * 0.5) + 0.5;
- mRightGain = 1.0 - mLeftGain;
+ float getPan() {
+ return mPan;
+ }
+
+ void setGain(float gain) {
+ mGain = gain;
+ calcGainFactors();
+ }
+
+ float getGain() {
+ return mGain;
}
protected:
@@ -73,9 +83,19 @@
// Logical pan value
float mPan;
- // precomputed channel gains
+ // precomputed channel gains for pan
float mLeftGain;
float mRightGain;
+
+ // Overall gain
+ float mGain;
+
+private:
+ void calcGainFactors() {
+ // useful panning information: http://www.cs.cmu.edu/~music/icm-online/readings/panlaws/
+ mRightGain = ((mPan * 0.5) + 0.5) * mGain;
+ mLeftGain = (1.0 - mRightGain) * mGain;
+ }
};
} // namespace wavlib
diff --git a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp
index 767ecf5..4313668 100644
--- a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp
+++ b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.cpp
@@ -134,7 +134,7 @@
}
}
-void SimpleMultiPlayer::addSampleSource(OneShotSampleSource* source, SampleBuffer* buffer) {
+void SimpleMultiPlayer::addSampleSource(SampleSource* source, SampleBuffer* buffer) {
mSampleBuffers.push_back(buffer);
mSampleSources.push_back(source);
mNumSampleBuffers++;
@@ -172,4 +172,20 @@
}
}
+void SimpleMultiPlayer::setPan(int index, float pan) {
+ mSampleSources[index]->setPan(pan);
+}
+
+float SimpleMultiPlayer::getPan(int index) {
+ return mSampleSources[index]->getPan();
+}
+
+void SimpleMultiPlayer::setGain(int index, float gain) {
+ mSampleSources[index]->setGain(gain);
+}
+
+float SimpleMultiPlayer::getGain(int index) {
+ return mSampleSources[index]->getGain();
+}
+
}
diff --git a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h
index b0be62b..455bc57 100644
--- a/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h
+++ b/samples/iolib/src/main/cpp/player/SimpleMultiPlayer.h
@@ -53,7 +53,7 @@
* The indexes associated with each source channel is the order in which they
* are added.
*/
- void addSampleSource(OneShotSampleSource* source, SampleBuffer* buffer);
+ void addSampleSource(SampleSource* source, SampleBuffer* buffer);
/**
* Deallocates and deletes all added source/buffer (see addSampleSource()).
*/
@@ -67,6 +67,12 @@
bool getOutputReset() { return mOutputReset; }
void clearOutputReset() { mOutputReset = false; }
+ void setPan(int index, float pan);
+ float getPan(int index);
+
+ void setGain(int index, float gain);
+ float getGain(int index);
+
private:
// Oboe Audio Stream
oboe::ManagedStream mAudioStream;
@@ -77,8 +83,8 @@
// Sample Data
int32_t mNumSampleBuffers;
- std::vector<SampleBuffer*> mSampleBuffers;
- std::vector<OneShotSampleSource*> mSampleSources;
+ std::vector<SampleBuffer*> mSampleBuffers;
+ std::vector<SampleSource*> mSampleSources;
bool mOutputReset;
};