diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt index 9d8b4f9..e9cfd73 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -24,6 +24,22 @@ } } + override var volume: Float = 1.0f + set(value) { + field = value + for (internalInstrument in internalInstruments) { + internalInstrument.volume = volume + } + } + + override var muted: Boolean = false + set(value) { + field = value + for (instrument in internalInstruments) { + instrument.muted = value + } + } + override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { @@ -35,12 +51,6 @@ throw IllegalStateException("cannot start another note with the current amount of oscillators") } - override fun changeActive(newActive: Boolean) { - for (instrument in internalInstruments) { - instrument.active = newActive - } - } - override fun stop() { for ((i, instrument) in internalInstruments.withIndex()) { instrument.endNote() diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt index 9d8b4f9..e9cfd73 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -24,6 +24,22 @@ } } + override var volume: Float = 1.0f + set(value) { + field = value + for (internalInstrument in internalInstruments) { + internalInstrument.volume = volume + } + } + + override var muted: Boolean = false + set(value) { + field = value + for (instrument in internalInstruments) { + instrument.muted = value + } + } + override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { @@ -35,12 +51,6 @@ throw IllegalStateException("cannot start another note with the current amount of oscillators") } - override fun changeActive(newActive: Boolean) { - for (instrument in internalInstruments) { - instrument.active = newActive - } - } - override fun stop() { for ((i, instrument) in internalInstruments.withIndex()) { instrument.endNote() diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt index bb402f8..50169c9 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt @@ -25,13 +25,12 @@ val context = parent.context val inflater = LayoutInflater.from(context) val binding = FragmentInstrumentBinding.inflate(inflater, parent, false) - return InstrumentViewHolder(binding) + return InstrumentViewHolder(binding, this.parent.childFragmentManager) } override fun onBindViewHolder(holder: InstrumentViewHolder, position: Int) { val instrument = Instrument.instruments[position] holder.instrument = instrument - instrument.applyToView(holder.binding, parent.childFragmentManager) } override fun getItemCount(): Int { diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt index 9d8b4f9..e9cfd73 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -24,6 +24,22 @@ } } + override var volume: Float = 1.0f + set(value) { + field = value + for (internalInstrument in internalInstruments) { + internalInstrument.volume = volume + } + } + + override var muted: Boolean = false + set(value) { + field = value + for (instrument in internalInstruments) { + instrument.muted = value + } + } + override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { @@ -35,12 +51,6 @@ throw IllegalStateException("cannot start another note with the current amount of oscillators") } - override fun changeActive(newActive: Boolean) { - for (instrument in internalInstruments) { - instrument.active = newActive - } - } - override fun stop() { for ((i, instrument) in internalInstruments.withIndex()) { instrument.endNote() diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt index bb402f8..50169c9 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt @@ -25,13 +25,12 @@ val context = parent.context val inflater = LayoutInflater.from(context) val binding = FragmentInstrumentBinding.inflate(inflater, parent, false) - return InstrumentViewHolder(binding) + return InstrumentViewHolder(binding, this.parent.childFragmentManager) } override fun onBindViewHolder(holder: InstrumentViewHolder, position: Int) { val instrument = Instrument.instruments[position] holder.instrument = instrument - instrument.applyToView(holder.binding, parent.childFragmentManager) } override fun getItemCount(): Int { diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt index aeb1078..59e8054 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt @@ -10,11 +10,28 @@ package com.lukas.music.ui.adapters +import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.RecyclerView import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument +import com.lukas.music.ui.fragments.EditInstrumentFragment -class InstrumentViewHolder(val binding: FragmentInstrumentBinding) : +class InstrumentViewHolder( + val binding: FragmentInstrumentBinding, + private val childFragmentManager: FragmentManager +) : RecyclerView.ViewHolder(binding.root) { - lateinit var instrument: Instrument + var instrument: Instrument? = null + set(value) { + field = value + value ?: return + binding.instrumentNameText.text = instrument?.name + binding.editInstrumentButton.setOnClickListener { + EditInstrumentFragment(instrument!!, this).showNow(childFragmentManager, "") + } + binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> + instrument?.muted = !newActive + } + binding.activeSwitch.isChecked = !instrument!!.muted + } } \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt index 9d8b4f9..e9cfd73 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -24,6 +24,22 @@ } } + override var volume: Float = 1.0f + set(value) { + field = value + for (internalInstrument in internalInstruments) { + internalInstrument.volume = volume + } + } + + override var muted: Boolean = false + set(value) { + field = value + for (instrument in internalInstruments) { + instrument.muted = value + } + } + override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { @@ -35,12 +51,6 @@ throw IllegalStateException("cannot start another note with the current amount of oscillators") } - override fun changeActive(newActive: Boolean) { - for (instrument in internalInstruments) { - instrument.active = newActive - } - } - override fun stop() { for ((i, instrument) in internalInstruments.withIndex()) { instrument.endNote() diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt index bb402f8..50169c9 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt @@ -25,13 +25,12 @@ val context = parent.context val inflater = LayoutInflater.from(context) val binding = FragmentInstrumentBinding.inflate(inflater, parent, false) - return InstrumentViewHolder(binding) + return InstrumentViewHolder(binding, this.parent.childFragmentManager) } override fun onBindViewHolder(holder: InstrumentViewHolder, position: Int) { val instrument = Instrument.instruments[position] holder.instrument = instrument - instrument.applyToView(holder.binding, parent.childFragmentManager) } override fun getItemCount(): Int { diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt index aeb1078..59e8054 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt @@ -10,11 +10,28 @@ package com.lukas.music.ui.adapters +import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.RecyclerView import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument +import com.lukas.music.ui.fragments.EditInstrumentFragment -class InstrumentViewHolder(val binding: FragmentInstrumentBinding) : +class InstrumentViewHolder( + val binding: FragmentInstrumentBinding, + private val childFragmentManager: FragmentManager +) : RecyclerView.ViewHolder(binding.root) { - lateinit var instrument: Instrument + var instrument: Instrument? = null + set(value) { + field = value + value ?: return + binding.instrumentNameText.text = instrument?.name + binding.editInstrumentButton.setOnClickListener { + EditInstrumentFragment(instrument!!, this).showNow(childFragmentManager, "") + } + binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> + instrument?.muted = !newActive + } + binding.activeSwitch.isChecked = !instrument!!.muted + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt index 05b471f..67d2ca9 100644 --- a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt +++ b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt @@ -20,16 +20,15 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import androidx.fragment.app.DialogFragment -import androidx.fragment.app.FragmentManager import com.lukas.music.databinding.FragmentEditInstrumentBinding -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument import com.lukas.music.instruments.Waveform +import com.lukas.music.ui.adapters.InstrumentViewHolder +import com.lukas.music.util.setup class EditInstrumentFragment( private val instrument: Instrument, - private val parent: FragmentInstrumentBinding, - private val manager: FragmentManager + private val viewHolder: InstrumentViewHolder ) : DialogFragment() { lateinit var binding: FragmentEditInstrumentBinding @@ -46,7 +45,7 @@ override fun afterTextChanged(s: Editable?) { instrument.name = binding.instrumentNameTextBox.text.toString() - instrument.applyToView(parent, manager) + viewHolder.instrument = viewHolder.instrument } }) val adapter = ArrayAdapter( @@ -67,6 +66,10 @@ override fun onNothingSelected(parent: AdapterView<*>?) {} } + binding.volumeSeek.setup(0, 100, 30) { + binding.volumeText.text = "volume: $it%" + instrument.volume = it.toFloat() / 100f + } binding.closeButton.setOnClickListener { dismiss() } diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt index 9d8b4f9..e9cfd73 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -24,6 +24,22 @@ } } + override var volume: Float = 1.0f + set(value) { + field = value + for (internalInstrument in internalInstruments) { + internalInstrument.volume = volume + } + } + + override var muted: Boolean = false + set(value) { + field = value + for (instrument in internalInstruments) { + instrument.muted = value + } + } + override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { @@ -35,12 +51,6 @@ throw IllegalStateException("cannot start another note with the current amount of oscillators") } - override fun changeActive(newActive: Boolean) { - for (instrument in internalInstruments) { - instrument.active = newActive - } - } - override fun stop() { for ((i, instrument) in internalInstruments.withIndex()) { instrument.endNote() diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt index bb402f8..50169c9 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt @@ -25,13 +25,12 @@ val context = parent.context val inflater = LayoutInflater.from(context) val binding = FragmentInstrumentBinding.inflate(inflater, parent, false) - return InstrumentViewHolder(binding) + return InstrumentViewHolder(binding, this.parent.childFragmentManager) } override fun onBindViewHolder(holder: InstrumentViewHolder, position: Int) { val instrument = Instrument.instruments[position] holder.instrument = instrument - instrument.applyToView(holder.binding, parent.childFragmentManager) } override fun getItemCount(): Int { diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt index aeb1078..59e8054 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt @@ -10,11 +10,28 @@ package com.lukas.music.ui.adapters +import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.RecyclerView import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument +import com.lukas.music.ui.fragments.EditInstrumentFragment -class InstrumentViewHolder(val binding: FragmentInstrumentBinding) : +class InstrumentViewHolder( + val binding: FragmentInstrumentBinding, + private val childFragmentManager: FragmentManager +) : RecyclerView.ViewHolder(binding.root) { - lateinit var instrument: Instrument + var instrument: Instrument? = null + set(value) { + field = value + value ?: return + binding.instrumentNameText.text = instrument?.name + binding.editInstrumentButton.setOnClickListener { + EditInstrumentFragment(instrument!!, this).showNow(childFragmentManager, "") + } + binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> + instrument?.muted = !newActive + } + binding.activeSwitch.isChecked = !instrument!!.muted + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt index 05b471f..67d2ca9 100644 --- a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt +++ b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt @@ -20,16 +20,15 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import androidx.fragment.app.DialogFragment -import androidx.fragment.app.FragmentManager import com.lukas.music.databinding.FragmentEditInstrumentBinding -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument import com.lukas.music.instruments.Waveform +import com.lukas.music.ui.adapters.InstrumentViewHolder +import com.lukas.music.util.setup class EditInstrumentFragment( private val instrument: Instrument, - private val parent: FragmentInstrumentBinding, - private val manager: FragmentManager + private val viewHolder: InstrumentViewHolder ) : DialogFragment() { lateinit var binding: FragmentEditInstrumentBinding @@ -46,7 +45,7 @@ override fun afterTextChanged(s: Editable?) { instrument.name = binding.instrumentNameTextBox.text.toString() - instrument.applyToView(parent, manager) + viewHolder.instrument = viewHolder.instrument } }) val adapter = ArrayAdapter( @@ -67,6 +66,10 @@ override fun onNothingSelected(parent: AdapterView<*>?) {} } + binding.volumeSeek.setup(0, 100, 30) { + binding.volumeText.text = "volume: $it%" + instrument.volume = it.toFloat() / 100f + } binding.closeButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt b/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt index eaf2c61..0c33019 100644 --- a/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt +++ b/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt @@ -16,7 +16,10 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.* +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.Space +import android.widget.TextView import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment @@ -24,6 +27,7 @@ import com.lukas.music.databinding.FragmentPlayBinding import com.lukas.music.instruments.Rhythm import com.lukas.music.song.Song +import com.lukas.music.util.setup class PlayFragment : Fragment() { private lateinit var binding: FragmentPlayBinding @@ -58,11 +62,11 @@ } Song.currentSong.chordProgression.reverse() } - setupSlider(binding.masterVolumeSlider, 0, 100, 100) { + binding.masterVolumeSlider.setup(0, 100, 100) { setMasterVolume(it.toDouble() / 100.0) binding.masterVolumeText.text = "Master volume: $it%" } - setupSlider(binding.tempoSlider, 50, 150, 90) { + binding.tempoSlider.setup(50, 150, 90) { Rhythm.setTempo(it) binding.tempoText.text = "tempo: ${it}bpm" } @@ -116,33 +120,6 @@ ) } - private fun setupSlider( - slider: SeekBar, - min: Int, - max: Int, - initialProgress: Int, - callback: (Int) -> Unit - ) { - slider.min = min - slider.max = max - slider.setOnSeekBarChangeListener(object : - SeekBar.OnSeekBarChangeListener { - override fun onProgressChanged( - seekBar: SeekBar, - progress: Int, fromUser: Boolean - ) { - callback(progress) - } - - override fun onStartTrackingTouch(seekBar: SeekBar) { - } - - override fun onStopTrackingTouch(seekBar: SeekBar) { - } - }) - slider.progress = initialProgress - } - fun updateChords() { binding.phraseDisplay.removeAllViews() chordDisplays.clear() diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt index 9d8b4f9..e9cfd73 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -24,6 +24,22 @@ } } + override var volume: Float = 1.0f + set(value) { + field = value + for (internalInstrument in internalInstruments) { + internalInstrument.volume = volume + } + } + + override var muted: Boolean = false + set(value) { + field = value + for (instrument in internalInstruments) { + instrument.muted = value + } + } + override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { @@ -35,12 +51,6 @@ throw IllegalStateException("cannot start another note with the current amount of oscillators") } - override fun changeActive(newActive: Boolean) { - for (instrument in internalInstruments) { - instrument.active = newActive - } - } - override fun stop() { for ((i, instrument) in internalInstruments.withIndex()) { instrument.endNote() diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt index bb402f8..50169c9 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt @@ -25,13 +25,12 @@ val context = parent.context val inflater = LayoutInflater.from(context) val binding = FragmentInstrumentBinding.inflate(inflater, parent, false) - return InstrumentViewHolder(binding) + return InstrumentViewHolder(binding, this.parent.childFragmentManager) } override fun onBindViewHolder(holder: InstrumentViewHolder, position: Int) { val instrument = Instrument.instruments[position] holder.instrument = instrument - instrument.applyToView(holder.binding, parent.childFragmentManager) } override fun getItemCount(): Int { diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt index aeb1078..59e8054 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt @@ -10,11 +10,28 @@ package com.lukas.music.ui.adapters +import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.RecyclerView import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument +import com.lukas.music.ui.fragments.EditInstrumentFragment -class InstrumentViewHolder(val binding: FragmentInstrumentBinding) : +class InstrumentViewHolder( + val binding: FragmentInstrumentBinding, + private val childFragmentManager: FragmentManager +) : RecyclerView.ViewHolder(binding.root) { - lateinit var instrument: Instrument + var instrument: Instrument? = null + set(value) { + field = value + value ?: return + binding.instrumentNameText.text = instrument?.name + binding.editInstrumentButton.setOnClickListener { + EditInstrumentFragment(instrument!!, this).showNow(childFragmentManager, "") + } + binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> + instrument?.muted = !newActive + } + binding.activeSwitch.isChecked = !instrument!!.muted + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt index 05b471f..67d2ca9 100644 --- a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt +++ b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt @@ -20,16 +20,15 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import androidx.fragment.app.DialogFragment -import androidx.fragment.app.FragmentManager import com.lukas.music.databinding.FragmentEditInstrumentBinding -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument import com.lukas.music.instruments.Waveform +import com.lukas.music.ui.adapters.InstrumentViewHolder +import com.lukas.music.util.setup class EditInstrumentFragment( private val instrument: Instrument, - private val parent: FragmentInstrumentBinding, - private val manager: FragmentManager + private val viewHolder: InstrumentViewHolder ) : DialogFragment() { lateinit var binding: FragmentEditInstrumentBinding @@ -46,7 +45,7 @@ override fun afterTextChanged(s: Editable?) { instrument.name = binding.instrumentNameTextBox.text.toString() - instrument.applyToView(parent, manager) + viewHolder.instrument = viewHolder.instrument } }) val adapter = ArrayAdapter( @@ -67,6 +66,10 @@ override fun onNothingSelected(parent: AdapterView<*>?) {} } + binding.volumeSeek.setup(0, 100, 30) { + binding.volumeText.text = "volume: $it%" + instrument.volume = it.toFloat() / 100f + } binding.closeButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt b/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt index eaf2c61..0c33019 100644 --- a/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt +++ b/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt @@ -16,7 +16,10 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.* +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.Space +import android.widget.TextView import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment @@ -24,6 +27,7 @@ import com.lukas.music.databinding.FragmentPlayBinding import com.lukas.music.instruments.Rhythm import com.lukas.music.song.Song +import com.lukas.music.util.setup class PlayFragment : Fragment() { private lateinit var binding: FragmentPlayBinding @@ -58,11 +62,11 @@ } Song.currentSong.chordProgression.reverse() } - setupSlider(binding.masterVolumeSlider, 0, 100, 100) { + binding.masterVolumeSlider.setup(0, 100, 100) { setMasterVolume(it.toDouble() / 100.0) binding.masterVolumeText.text = "Master volume: $it%" } - setupSlider(binding.tempoSlider, 50, 150, 90) { + binding.tempoSlider.setup(50, 150, 90) { Rhythm.setTempo(it) binding.tempoText.text = "tempo: ${it}bpm" } @@ -116,33 +120,6 @@ ) } - private fun setupSlider( - slider: SeekBar, - min: Int, - max: Int, - initialProgress: Int, - callback: (Int) -> Unit - ) { - slider.min = min - slider.max = max - slider.setOnSeekBarChangeListener(object : - SeekBar.OnSeekBarChangeListener { - override fun onProgressChanged( - seekBar: SeekBar, - progress: Int, fromUser: Boolean - ) { - callback(progress) - } - - override fun onStartTrackingTouch(seekBar: SeekBar) { - } - - override fun onStopTrackingTouch(seekBar: SeekBar) { - } - }) - slider.progress = initialProgress - } - fun updateChords() { binding.phraseDisplay.removeAllViews() chordDisplays.clear() diff --git a/app/src/main/java/com/lukas/music/util/UIUtil.kt b/app/src/main/java/com/lukas/music/util/UIUtil.kt new file mode 100644 index 0000000..b9fa92b --- /dev/null +++ b/app/src/main/java/com/lukas/music/util/UIUtil.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2022 Lukas Eisenhauer + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + */ + +package com.lukas.music.util + +import android.widget.SeekBar + +fun SeekBar.setup( + min: Int, max: Int, initialProgress: Int, callback: (Int) -> Unit +) { + this.min = min + this.max = max + setOnSeekBarChangeListener(object : + SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged( + seekBar: SeekBar, + progress: Int, fromUser: Boolean + ) { + callback(progress) + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + } + }) + this.progress = initialProgress +} diff --git a/.idea/misc.xml b/.idea/misc.xml index 4e369b6..0076403 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 6ebd2b0..61b6e73 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -23,7 +23,6 @@ audioHost = new AudioHost(); } -extern "C" JNIEXPORT jint JNICALL Java_com_lukas_music_instruments_InternalInstrument_createInstrument(JNIEnv *env, jobject thiz) { uint32_t result = audioHost->instruments->size(); @@ -32,16 +31,6 @@ return result; } -extern "C" -JNIEXPORT void JNICALL -Java_com_lukas_music_instruments_InternalInstrument_setInstrumentActive(JNIEnv *env, jobject thiz, - jint id, jboolean active) { - Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), - id)); - instrument->wave->amplitude = active ? 0.3 : 0.0; -} -} -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_startNote(JNIEnv *env, jobject thiz, jint id, jdouble frequency) { @@ -50,7 +39,6 @@ instrument->startNote(frequency); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_endNote(JNIEnv *env, jobject thiz, jint id) { @@ -58,17 +46,24 @@ id)); instrument->endNote(); } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_ui_fragments_PlayFragment_setMasterVolume(JNIEnv *env, jobject thiz, jdouble volume) { audioHost->masterVolume = volume; } -extern "C" JNIEXPORT void JNICALL Java_com_lukas_music_instruments_InternalInstrument_setInstrumentWaveform(JNIEnv *env, jobject thiz, jint id, jint waveform) { Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), id)); instrument->setWaveform(static_cast(waveform)); +} + +JNIEXPORT void JNICALL +Java_com_lukas_music_instruments_InternalInstrument_setVolume(JNIEnv *env, jobject thiz, jint id, + jfloat volume) { + Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), + id)); + instrument->wave->amplitude = volume; +} } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/Instrument.kt b/app/src/main/java/com/lukas/music/instruments/Instrument.kt index 3487ffd..c8c3511 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -10,37 +10,18 @@ package com.lukas.music.instruments -import androidx.fragment.app.FragmentManager -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.song.note.Note import com.lukas.music.song.voice.BassVoice import com.lukas.music.song.voice.ChordVoice import com.lukas.music.song.voice.Voice -import com.lukas.music.ui.fragments.EditInstrumentFragment abstract class Instrument(var name: String) { - private var active = false abstract var waveform: Waveform - - fun applyToView(binding: FragmentInstrumentBinding, childFragmentManager: FragmentManager) { - binding.instrumentNameText.text = name - binding.editInstrumentButton.setOnClickListener { - EditInstrumentFragment( - this, - binding, - childFragmentManager - ).showNow(childFragmentManager, "") - } - binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> - active = newActive - changeActive(newActive) - } - binding.activeSwitch.isChecked = active - } + abstract var volume: Float + abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() - abstract fun changeActive(newActive: Boolean) companion object { val instruments = diff --git a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt index dc64bcc..7c7f54b 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -12,20 +12,40 @@ class InternalInstrument { private val id = createInstrument() - var active: Boolean = false - set(value) { - field = value - setInstrumentActive(id, value) - } var waveform: Waveform = Waveform.SINE set(value) { field = value setInstrumentWaveform(id, value.id) - // this is to resend the setInstrumentActive for the new waveform in the internal c++ code - active = active + refresh() } + var volume: Float = 0.3f + set(value) { + field = value + if (!muted) { + actualVolume = value + } + } + + var muted: Boolean = false + set(value) { + field = value + actualVolume = if (value) 0.0f else volume + } + + private var actualVolume: Float = 1.0f + set(value) { + field = value + setVolume(id, value) + } + + private fun refresh() { + // this is to resend the old information to the internal c++ code (when changing the waveform) + muted = muted + volume = volume + } + fun startNote(frequency: Double) { startNote(id, frequency) } @@ -35,8 +55,8 @@ } private external fun createInstrument(): Int - private external fun setInstrumentActive(id: Int, isActive: Boolean) private external fun setInstrumentWaveform(id: Int, waveform: Int) private external fun startNote(id: Int, frequency: Double) private external fun endNote(id: Int) + private external fun setVolume(id: Int, volume: Float) } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt index e7b7464..55de0af 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -21,14 +21,22 @@ internalInstrument.waveform = value } + override var volume: Float = 1.0f + set(value) { + field = value + internalInstrument.volume = volume + } + + override var muted: Boolean = false + set(value) { + field = value + internalInstrument.muted = value + } + override fun startNote(note: Note) { internalInstrument.startNote(note.frequency) } - override fun changeActive(newActive: Boolean) { - internalInstrument.active = newActive - } - override fun stop() { internalInstrument.endNote() } diff --git a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt index 9d8b4f9..e9cfd73 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -24,6 +24,22 @@ } } + override var volume: Float = 1.0f + set(value) { + field = value + for (internalInstrument in internalInstruments) { + internalInstrument.volume = volume + } + } + + override var muted: Boolean = false + set(value) { + field = value + for (instrument in internalInstruments) { + instrument.muted = value + } + } + override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { @@ -35,12 +51,6 @@ throw IllegalStateException("cannot start another note with the current amount of oscillators") } - override fun changeActive(newActive: Boolean) { - for (instrument in internalInstruments) { - instrument.active = newActive - } - } - override fun stop() { for ((i, instrument) in internalInstruments.withIndex()) { instrument.endNote() diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt index bb402f8..50169c9 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentAdapter.kt @@ -25,13 +25,12 @@ val context = parent.context val inflater = LayoutInflater.from(context) val binding = FragmentInstrumentBinding.inflate(inflater, parent, false) - return InstrumentViewHolder(binding) + return InstrumentViewHolder(binding, this.parent.childFragmentManager) } override fun onBindViewHolder(holder: InstrumentViewHolder, position: Int) { val instrument = Instrument.instruments[position] holder.instrument = instrument - instrument.applyToView(holder.binding, parent.childFragmentManager) } override fun getItemCount(): Int { diff --git a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt index aeb1078..59e8054 100644 --- a/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt +++ b/app/src/main/java/com/lukas/music/ui/adapters/InstrumentViewHolder.kt @@ -10,11 +10,28 @@ package com.lukas.music.ui.adapters +import androidx.fragment.app.FragmentManager import androidx.recyclerview.widget.RecyclerView import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument +import com.lukas.music.ui.fragments.EditInstrumentFragment -class InstrumentViewHolder(val binding: FragmentInstrumentBinding) : +class InstrumentViewHolder( + val binding: FragmentInstrumentBinding, + private val childFragmentManager: FragmentManager +) : RecyclerView.ViewHolder(binding.root) { - lateinit var instrument: Instrument + var instrument: Instrument? = null + set(value) { + field = value + value ?: return + binding.instrumentNameText.text = instrument?.name + binding.editInstrumentButton.setOnClickListener { + EditInstrumentFragment(instrument!!, this).showNow(childFragmentManager, "") + } + binding.activeSwitch.setOnCheckedChangeListener { _, newActive -> + instrument?.muted = !newActive + } + binding.activeSwitch.isChecked = !instrument!!.muted + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt index 05b471f..67d2ca9 100644 --- a/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt +++ b/app/src/main/java/com/lukas/music/ui/fragments/EditInstrumentFragment.kt @@ -20,16 +20,15 @@ import android.widget.AdapterView import android.widget.ArrayAdapter import androidx.fragment.app.DialogFragment -import androidx.fragment.app.FragmentManager import com.lukas.music.databinding.FragmentEditInstrumentBinding -import com.lukas.music.databinding.FragmentInstrumentBinding import com.lukas.music.instruments.Instrument import com.lukas.music.instruments.Waveform +import com.lukas.music.ui.adapters.InstrumentViewHolder +import com.lukas.music.util.setup class EditInstrumentFragment( private val instrument: Instrument, - private val parent: FragmentInstrumentBinding, - private val manager: FragmentManager + private val viewHolder: InstrumentViewHolder ) : DialogFragment() { lateinit var binding: FragmentEditInstrumentBinding @@ -46,7 +45,7 @@ override fun afterTextChanged(s: Editable?) { instrument.name = binding.instrumentNameTextBox.text.toString() - instrument.applyToView(parent, manager) + viewHolder.instrument = viewHolder.instrument } }) val adapter = ArrayAdapter( @@ -67,6 +66,10 @@ override fun onNothingSelected(parent: AdapterView<*>?) {} } + binding.volumeSeek.setup(0, 100, 30) { + binding.volumeText.text = "volume: $it%" + instrument.volume = it.toFloat() / 100f + } binding.closeButton.setOnClickListener { dismiss() } diff --git a/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt b/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt index eaf2c61..0c33019 100644 --- a/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt +++ b/app/src/main/java/com/lukas/music/ui/fragments/PlayFragment.kt @@ -16,7 +16,10 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.widget.* +import android.widget.RadioButton +import android.widget.RadioGroup +import android.widget.Space +import android.widget.TextView import androidx.cardview.widget.CardView import androidx.core.content.ContextCompat import androidx.fragment.app.Fragment @@ -24,6 +27,7 @@ import com.lukas.music.databinding.FragmentPlayBinding import com.lukas.music.instruments.Rhythm import com.lukas.music.song.Song +import com.lukas.music.util.setup class PlayFragment : Fragment() { private lateinit var binding: FragmentPlayBinding @@ -58,11 +62,11 @@ } Song.currentSong.chordProgression.reverse() } - setupSlider(binding.masterVolumeSlider, 0, 100, 100) { + binding.masterVolumeSlider.setup(0, 100, 100) { setMasterVolume(it.toDouble() / 100.0) binding.masterVolumeText.text = "Master volume: $it%" } - setupSlider(binding.tempoSlider, 50, 150, 90) { + binding.tempoSlider.setup(50, 150, 90) { Rhythm.setTempo(it) binding.tempoText.text = "tempo: ${it}bpm" } @@ -116,33 +120,6 @@ ) } - private fun setupSlider( - slider: SeekBar, - min: Int, - max: Int, - initialProgress: Int, - callback: (Int) -> Unit - ) { - slider.min = min - slider.max = max - slider.setOnSeekBarChangeListener(object : - SeekBar.OnSeekBarChangeListener { - override fun onProgressChanged( - seekBar: SeekBar, - progress: Int, fromUser: Boolean - ) { - callback(progress) - } - - override fun onStartTrackingTouch(seekBar: SeekBar) { - } - - override fun onStopTrackingTouch(seekBar: SeekBar) { - } - }) - slider.progress = initialProgress - } - fun updateChords() { binding.phraseDisplay.removeAllViews() chordDisplays.clear() diff --git a/app/src/main/java/com/lukas/music/util/UIUtil.kt b/app/src/main/java/com/lukas/music/util/UIUtil.kt new file mode 100644 index 0000000..b9fa92b --- /dev/null +++ b/app/src/main/java/com/lukas/music/util/UIUtil.kt @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2022 Lukas Eisenhauer + * + * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or(at your option) any later version. + * + * This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along with this program. If not, see . + */ + +package com.lukas.music.util + +import android.widget.SeekBar + +fun SeekBar.setup( + min: Int, max: Int, initialProgress: Int, callback: (Int) -> Unit +) { + this.min = min + this.max = max + setOnSeekBarChangeListener(object : + SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged( + seekBar: SeekBar, + progress: Int, fromUser: Boolean + ) { + callback(progress) + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + } + }) + this.progress = initialProgress +} diff --git a/app/src/main/res/layout/fragment_edit_instrument.xml b/app/src/main/res/layout/fragment_edit_instrument.xml index e984e4b..71d616a 100644 --- a/app/src/main/res/layout/fragment_edit_instrument.xml +++ b/app/src/main/res/layout/fragment_edit_instrument.xml @@ -54,7 +54,8 @@ app:layout_constraintBottom_toBottomOf="@+id/textView2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toEndOf="@+id/textView2" - app:layout_constraintTop_toTopOf="@+id/textView2" /> + app:layout_constraintTop_toTopOf="@+id/textView2" + tools:ignore="DuplicateSpeakableTextCheck" /> + app:layout_constraintTop_toBottomOf="@+id/volumeSeek" /> + app:layout_constraintTop_toBottomOf="@+id/instrumentNameTextBox" + tools:ignore="DuplicateSpeakableTextCheck" /> + + + + \ No newline at end of file