diff --git a/.idea/misc.xml b/.idea/misc.xml index a5fe0f9..cb4089b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/.idea/misc.xml b/.idea/misc.xml index a5fe0f9..cb4089b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/AudioHost.cpp b/app/src/main/cpp/AudioHost.cpp index 359bb2d..dc80bd1 100644 --- a/app/src/main/cpp/AudioHost.cpp +++ b/app/src/main/cpp/AudioHost.cpp @@ -17,6 +17,9 @@ for (auto const &instrument: *thiz->instruments) { instrument->render(buffer, sampleCount); } + for (uint32_t i = 0; i < sampleCount; i++) { + buffer[i] *= thiz->masterVolume; + } return AAUDIO_CALLBACK_RESULT_CONTINUE; } diff --git a/.idea/misc.xml b/.idea/misc.xml index a5fe0f9..cb4089b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/AudioHost.cpp b/app/src/main/cpp/AudioHost.cpp index 359bb2d..dc80bd1 100644 --- a/app/src/main/cpp/AudioHost.cpp +++ b/app/src/main/cpp/AudioHost.cpp @@ -17,6 +17,9 @@ for (auto const &instrument: *thiz->instruments) { instrument->render(buffer, sampleCount); } + for (uint32_t i = 0; i < sampleCount; i++) { + buffer[i] *= thiz->masterVolume; + } return AAUDIO_CALLBACK_RESULT_CONTINUE; } diff --git a/app/src/main/cpp/AudioHost.h b/app/src/main/cpp/AudioHost.h index e8976a8..d5309c4 100644 --- a/app/src/main/cpp/AudioHost.h +++ b/app/src/main/cpp/AudioHost.h @@ -13,7 +13,8 @@ AAudioStream *stream; public: uint32_t sampleRate = 0; - std::list *instruments = new std::list(); + double masterVolume = 1.0f; + std::list *instruments = new std::list(); AudioHost(); }; diff --git a/.idea/misc.xml b/.idea/misc.xml index a5fe0f9..cb4089b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/AudioHost.cpp b/app/src/main/cpp/AudioHost.cpp index 359bb2d..dc80bd1 100644 --- a/app/src/main/cpp/AudioHost.cpp +++ b/app/src/main/cpp/AudioHost.cpp @@ -17,6 +17,9 @@ for (auto const &instrument: *thiz->instruments) { instrument->render(buffer, sampleCount); } + for (uint32_t i = 0; i < sampleCount; i++) { + buffer[i] *= thiz->masterVolume; + } return AAUDIO_CALLBACK_RESULT_CONTINUE; } diff --git a/app/src/main/cpp/AudioHost.h b/app/src/main/cpp/AudioHost.h index e8976a8..d5309c4 100644 --- a/app/src/main/cpp/AudioHost.h +++ b/app/src/main/cpp/AudioHost.h @@ -13,7 +13,8 @@ AAudioStream *stream; public: uint32_t sampleRate = 0; - std::list *instruments = new std::list(); + double masterVolume = 1.0f; + std::list *instruments = new std::list(); AudioHost(); }; diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 94cd9ab..04e4757 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -57,4 +57,10 @@ Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), 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; } \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index a5fe0f9..cb4089b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/AudioHost.cpp b/app/src/main/cpp/AudioHost.cpp index 359bb2d..dc80bd1 100644 --- a/app/src/main/cpp/AudioHost.cpp +++ b/app/src/main/cpp/AudioHost.cpp @@ -17,6 +17,9 @@ for (auto const &instrument: *thiz->instruments) { instrument->render(buffer, sampleCount); } + for (uint32_t i = 0; i < sampleCount; i++) { + buffer[i] *= thiz->masterVolume; + } return AAUDIO_CALLBACK_RESULT_CONTINUE; } diff --git a/app/src/main/cpp/AudioHost.h b/app/src/main/cpp/AudioHost.h index e8976a8..d5309c4 100644 --- a/app/src/main/cpp/AudioHost.h +++ b/app/src/main/cpp/AudioHost.h @@ -13,7 +13,8 @@ AAudioStream *stream; public: uint32_t sampleRate = 0; - std::list *instruments = new std::list(); + double masterVolume = 1.0f; + std::list *instruments = new std::list(); AudioHost(); }; diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 94cd9ab..04e4757 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -57,4 +57,10 @@ Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), 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; } \ No newline at end of file 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 eadc36b..0493d29 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 @@ -4,6 +4,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.SeekBar import androidx.fragment.app.Fragment import com.lukas.music.databinding.FragmentPlayBinding import com.lukas.music.instruments.Rhythm @@ -22,6 +23,27 @@ if (Rhythm.on) android.R.drawable.ic_media_pause else android.R.drawable.ic_media_play ) } + binding.masterVolumeSlider.min = 0 + binding.masterVolumeSlider.max = 100 + binding.masterVolumeSlider.setOnSeekBarChangeListener(object : + SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged( + seekBar: SeekBar, + progress: Int, fromUser: Boolean + ) { + setMasterVolume(progress.toDouble() / 100.0) + binding.masterVolumeText.text = "Master volume: $progress%" + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + } + }) + binding.masterVolumeSlider.progress = 100 return binding.root } + + external fun setMasterVolume(volume: Double) } \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index a5fe0f9..cb4089b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/AudioHost.cpp b/app/src/main/cpp/AudioHost.cpp index 359bb2d..dc80bd1 100644 --- a/app/src/main/cpp/AudioHost.cpp +++ b/app/src/main/cpp/AudioHost.cpp @@ -17,6 +17,9 @@ for (auto const &instrument: *thiz->instruments) { instrument->render(buffer, sampleCount); } + for (uint32_t i = 0; i < sampleCount; i++) { + buffer[i] *= thiz->masterVolume; + } return AAUDIO_CALLBACK_RESULT_CONTINUE; } diff --git a/app/src/main/cpp/AudioHost.h b/app/src/main/cpp/AudioHost.h index e8976a8..d5309c4 100644 --- a/app/src/main/cpp/AudioHost.h +++ b/app/src/main/cpp/AudioHost.h @@ -13,7 +13,8 @@ AAudioStream *stream; public: uint32_t sampleRate = 0; - std::list *instruments = new std::list(); + double masterVolume = 1.0f; + std::list *instruments = new std::list(); AudioHost(); }; diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 94cd9ab..04e4757 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -57,4 +57,10 @@ Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), 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; } \ No newline at end of file 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 eadc36b..0493d29 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 @@ -4,6 +4,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.SeekBar import androidx.fragment.app.Fragment import com.lukas.music.databinding.FragmentPlayBinding import com.lukas.music.instruments.Rhythm @@ -22,6 +23,27 @@ if (Rhythm.on) android.R.drawable.ic_media_pause else android.R.drawable.ic_media_play ) } + binding.masterVolumeSlider.min = 0 + binding.masterVolumeSlider.max = 100 + binding.masterVolumeSlider.setOnSeekBarChangeListener(object : + SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged( + seekBar: SeekBar, + progress: Int, fromUser: Boolean + ) { + setMasterVolume(progress.toDouble() / 100.0) + binding.masterVolumeText.text = "Master volume: $progress%" + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + } + }) + binding.masterVolumeSlider.progress = 100 return binding.root } + + external fun setMasterVolume(volume: Double) } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_play.xml b/app/src/main/res/layout/fragment_play.xml index e66caea..9f2ab99 100644 --- a/app/src/main/res/layout/fragment_play.xml +++ b/app/src/main/res/layout/fragment_play.xml @@ -16,11 +16,34 @@ android:layout_height="wrap_content" android:layout_marginTop="16dp" android:clickable="true" - android:contentDescription="start or stop the song" + android:contentDescription="@string/play_button_description" android:src="@android:drawable/ic_media_play" app:fabSize="normal" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index a5fe0f9..cb4089b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,7 +11,7 @@ - + diff --git a/app/src/main/cpp/AudioHost.cpp b/app/src/main/cpp/AudioHost.cpp index 359bb2d..dc80bd1 100644 --- a/app/src/main/cpp/AudioHost.cpp +++ b/app/src/main/cpp/AudioHost.cpp @@ -17,6 +17,9 @@ for (auto const &instrument: *thiz->instruments) { instrument->render(buffer, sampleCount); } + for (uint32_t i = 0; i < sampleCount; i++) { + buffer[i] *= thiz->masterVolume; + } return AAUDIO_CALLBACK_RESULT_CONTINUE; } diff --git a/app/src/main/cpp/AudioHost.h b/app/src/main/cpp/AudioHost.h index e8976a8..d5309c4 100644 --- a/app/src/main/cpp/AudioHost.h +++ b/app/src/main/cpp/AudioHost.h @@ -13,7 +13,8 @@ AAudioStream *stream; public: uint32_t sampleRate = 0; - std::list *instruments = new std::list(); + double masterVolume = 1.0f; + std::list *instruments = new std::list(); AudioHost(); }; diff --git a/app/src/main/cpp/JavaFunctions.cpp b/app/src/main/cpp/JavaFunctions.cpp index 94cd9ab..04e4757 100644 --- a/app/src/main/cpp/JavaFunctions.cpp +++ b/app/src/main/cpp/JavaFunctions.cpp @@ -57,4 +57,10 @@ Instrument *instrument = static_cast(listGet(audioHost->instruments->begin(), 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; } \ No newline at end of file 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 eadc36b..0493d29 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 @@ -4,6 +4,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.widget.SeekBar import androidx.fragment.app.Fragment import com.lukas.music.databinding.FragmentPlayBinding import com.lukas.music.instruments.Rhythm @@ -22,6 +23,27 @@ if (Rhythm.on) android.R.drawable.ic_media_pause else android.R.drawable.ic_media_play ) } + binding.masterVolumeSlider.min = 0 + binding.masterVolumeSlider.max = 100 + binding.masterVolumeSlider.setOnSeekBarChangeListener(object : + SeekBar.OnSeekBarChangeListener { + override fun onProgressChanged( + seekBar: SeekBar, + progress: Int, fromUser: Boolean + ) { + setMasterVolume(progress.toDouble() / 100.0) + binding.masterVolumeText.text = "Master volume: $progress%" + } + + override fun onStartTrackingTouch(seekBar: SeekBar) { + } + + override fun onStopTrackingTouch(seekBar: SeekBar) { + } + }) + binding.masterVolumeSlider.progress = 100 return binding.root } + + external fun setMasterVolume(volume: Double) } \ No newline at end of file diff --git a/app/src/main/res/layout/fragment_play.xml b/app/src/main/res/layout/fragment_play.xml index e66caea..9f2ab99 100644 --- a/app/src/main/res/layout/fragment_play.xml +++ b/app/src/main/res/layout/fragment_play.xml @@ -16,11 +16,34 @@ android:layout_height="wrap_content" android:layout_marginTop="16dp" android:clickable="true" - android:contentDescription="start or stop the song" + android:contentDescription="@string/play_button_description" android:src="@android:drawable/ic_media_play" app:fabSize="normal" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> + + + + + \ No newline at end of file diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 32c8b81..3e338a9 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,5 +2,5 @@ Music Credits this app was created by Lukas Eisenhauer - Hello blank fragment + start or stop the song \ No newline at end of file