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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 55de0af..8b1ba50 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -34,10 +34,19 @@ } override fun startNote(note: Note) { - internalInstrument.startNote(note.frequency) + if (note == internalInstrument.note) { + return + } + internalInstrument.startNote(note) } override fun stop() { internalInstrument.endNote() } + + override fun stopNote(note: Note) { + if (note == internalInstrument.note) { + stop() + } + } } \ 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 55de0af..8b1ba50 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -34,10 +34,19 @@ } override fun startNote(note: Note) { - internalInstrument.startNote(note.frequency) + if (note == internalInstrument.note) { + return + } + internalInstrument.startNote(note) } override fun stop() { internalInstrument.endNote() } + + override fun stopNote(note: Note) { + if (note == internalInstrument.note) { + stop() + } + } } \ No newline at end of file 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 e9cfd73..c6dae83 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -43,10 +43,13 @@ override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { - internalInstruments[index].startNote(note.frequency) + internalInstruments[index].startNote(note) playing[index] = true return } + if (internalInstruments[index].note == note) { + return + } } throw IllegalStateException("cannot start another note with the current amount of oscillators") } @@ -57,4 +60,13 @@ playing[i] = false } } + + override fun stopNote(note: Note) { + for ((i, instrument) in internalInstruments.withIndex()) { + if (instrument.note == note) { + instrument.endNote() + playing[i] = false + } + } + } } \ 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 55de0af..8b1ba50 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -34,10 +34,19 @@ } override fun startNote(note: Note) { - internalInstrument.startNote(note.frequency) + if (note == internalInstrument.note) { + return + } + internalInstrument.startNote(note) } override fun stop() { internalInstrument.endNote() } + + override fun stopNote(note: Note) { + if (note == internalInstrument.note) { + stop() + } + } } \ No newline at end of file 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 e9cfd73..c6dae83 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -43,10 +43,13 @@ override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { - internalInstruments[index].startNote(note.frequency) + internalInstruments[index].startNote(note) playing[index] = true return } + if (internalInstruments[index].note == note) { + return + } } throw IllegalStateException("cannot start another note with the current amount of oscillators") } @@ -57,4 +60,13 @@ playing[i] = false } } + + override fun stopNote(note: Note) { + for ((i, instrument) in internalInstruments.withIndex()) { + if (instrument.note == note) { + instrument.endNote() + playing[i] = false + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/Song.kt b/app/src/main/java/com/lukas/music/song/Song.kt index 33b8a7d..7f9823f 100644 --- a/app/src/main/java/com/lukas/music/song/Song.kt +++ b/app/src/main/java/com/lukas/music/song/Song.kt @@ -46,10 +46,10 @@ val chord = chordProgression.currentItem?.currentItem ?: return index val chordNotes = chord.getNotes(root) soloInstrument?.let { - it.voice.step(root, chordNotes) + it.voice.step(root, chordNotes, index) } ?: run { - for (voice in Instrument.voice) { - voice.step(root, chordNotes) + for (instrument in Instrument.instruments) { + instrument.voice.step(root, chordNotes, index) } } return index 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 55de0af..8b1ba50 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -34,10 +34,19 @@ } override fun startNote(note: Note) { - internalInstrument.startNote(note.frequency) + if (note == internalInstrument.note) { + return + } + internalInstrument.startNote(note) } override fun stop() { internalInstrument.endNote() } + + override fun stopNote(note: Note) { + if (note == internalInstrument.note) { + stop() + } + } } \ No newline at end of file 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 e9cfd73..c6dae83 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -43,10 +43,13 @@ override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { - internalInstruments[index].startNote(note.frequency) + internalInstruments[index].startNote(note) playing[index] = true return } + if (internalInstruments[index].note == note) { + return + } } throw IllegalStateException("cannot start another note with the current amount of oscillators") } @@ -57,4 +60,13 @@ playing[i] = false } } + + override fun stopNote(note: Note) { + for ((i, instrument) in internalInstruments.withIndex()) { + if (instrument.note == note) { + instrument.endNote() + playing[i] = false + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/Song.kt b/app/src/main/java/com/lukas/music/song/Song.kt index 33b8a7d..7f9823f 100644 --- a/app/src/main/java/com/lukas/music/song/Song.kt +++ b/app/src/main/java/com/lukas/music/song/Song.kt @@ -46,10 +46,10 @@ val chord = chordProgression.currentItem?.currentItem ?: return index val chordNotes = chord.getNotes(root) soloInstrument?.let { - it.voice.step(root, chordNotes) + it.voice.step(root, chordNotes, index) } ?: run { - for (voice in Instrument.voice) { - voice.step(root, chordNotes) + for (instrument in Instrument.instruments) { + instrument.voice.step(root, chordNotes, index) } } return index diff --git a/app/src/main/java/com/lukas/music/song/note/Note.kt b/app/src/main/java/com/lukas/music/song/note/Note.kt index d3a588d..17bfb2b 100644 --- a/app/src/main/java/com/lukas/music/song/note/Note.kt +++ b/app/src/main/java/com/lukas/music/song/note/Note.kt @@ -28,6 +28,22 @@ return this + (-other) } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Note + + if (id != other.id) return false + + return true + } + + override fun hashCode(): Int { + return id + } + + companion object { val NOTES = Array(128) { Note(it) } 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 55de0af..8b1ba50 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -34,10 +34,19 @@ } override fun startNote(note: Note) { - internalInstrument.startNote(note.frequency) + if (note == internalInstrument.note) { + return + } + internalInstrument.startNote(note) } override fun stop() { internalInstrument.endNote() } + + override fun stopNote(note: Note) { + if (note == internalInstrument.note) { + stop() + } + } } \ No newline at end of file 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 e9cfd73..c6dae83 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -43,10 +43,13 @@ override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { - internalInstruments[index].startNote(note.frequency) + internalInstruments[index].startNote(note) playing[index] = true return } + if (internalInstruments[index].note == note) { + return + } } throw IllegalStateException("cannot start another note with the current amount of oscillators") } @@ -57,4 +60,13 @@ playing[i] = false } } + + override fun stopNote(note: Note) { + for ((i, instrument) in internalInstruments.withIndex()) { + if (instrument.note == note) { + instrument.endNote() + playing[i] = false + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/Song.kt b/app/src/main/java/com/lukas/music/song/Song.kt index 33b8a7d..7f9823f 100644 --- a/app/src/main/java/com/lukas/music/song/Song.kt +++ b/app/src/main/java/com/lukas/music/song/Song.kt @@ -46,10 +46,10 @@ val chord = chordProgression.currentItem?.currentItem ?: return index val chordNotes = chord.getNotes(root) soloInstrument?.let { - it.voice.step(root, chordNotes) + it.voice.step(root, chordNotes, index) } ?: run { - for (voice in Instrument.voice) { - voice.step(root, chordNotes) + for (instrument in Instrument.instruments) { + instrument.voice.step(root, chordNotes, index) } } return index diff --git a/app/src/main/java/com/lukas/music/song/note/Note.kt b/app/src/main/java/com/lukas/music/song/note/Note.kt index d3a588d..17bfb2b 100644 --- a/app/src/main/java/com/lukas/music/song/note/Note.kt +++ b/app/src/main/java/com/lukas/music/song/note/Note.kt @@ -28,6 +28,22 @@ return this + (-other) } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Note + + if (id != other.id) return false + + return true + } + + override fun hashCode(): Int { + return id + } + + companion object { val NOTES = Array(128) { Note(it) } diff --git a/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt b/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt index 3990554..a23bbbd 100644 --- a/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt +++ b/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt @@ -14,9 +14,14 @@ import com.lukas.music.song.note.Note class BassVoice(instrument: Instrument) : Voice(instrument) { - override val steps = listOf(1, 3) + override var noteActive: Array> = arrayOf( + arrayOf(true), + arrayOf(false), + arrayOf(true), + arrayOf(false) + ) - override fun step(root: Note, chord: Array) { - instrument.startNote(chord[0] - 24) + override fun getNotes(root: Note, chordNotes: Array): Array { + return arrayOf(chordNotes[0] - 24) } } \ 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 55de0af..8b1ba50 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -34,10 +34,19 @@ } override fun startNote(note: Note) { - internalInstrument.startNote(note.frequency) + if (note == internalInstrument.note) { + return + } + internalInstrument.startNote(note) } override fun stop() { internalInstrument.endNote() } + + override fun stopNote(note: Note) { + if (note == internalInstrument.note) { + stop() + } + } } \ No newline at end of file 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 e9cfd73..c6dae83 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -43,10 +43,13 @@ override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { - internalInstruments[index].startNote(note.frequency) + internalInstruments[index].startNote(note) playing[index] = true return } + if (internalInstruments[index].note == note) { + return + } } throw IllegalStateException("cannot start another note with the current amount of oscillators") } @@ -57,4 +60,13 @@ playing[i] = false } } + + override fun stopNote(note: Note) { + for ((i, instrument) in internalInstruments.withIndex()) { + if (instrument.note == note) { + instrument.endNote() + playing[i] = false + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/Song.kt b/app/src/main/java/com/lukas/music/song/Song.kt index 33b8a7d..7f9823f 100644 --- a/app/src/main/java/com/lukas/music/song/Song.kt +++ b/app/src/main/java/com/lukas/music/song/Song.kt @@ -46,10 +46,10 @@ val chord = chordProgression.currentItem?.currentItem ?: return index val chordNotes = chord.getNotes(root) soloInstrument?.let { - it.voice.step(root, chordNotes) + it.voice.step(root, chordNotes, index) } ?: run { - for (voice in Instrument.voice) { - voice.step(root, chordNotes) + for (instrument in Instrument.instruments) { + instrument.voice.step(root, chordNotes, index) } } return index diff --git a/app/src/main/java/com/lukas/music/song/note/Note.kt b/app/src/main/java/com/lukas/music/song/note/Note.kt index d3a588d..17bfb2b 100644 --- a/app/src/main/java/com/lukas/music/song/note/Note.kt +++ b/app/src/main/java/com/lukas/music/song/note/Note.kt @@ -28,6 +28,22 @@ return this + (-other) } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Note + + if (id != other.id) return false + + return true + } + + override fun hashCode(): Int { + return id + } + + companion object { val NOTES = Array(128) { Note(it) } diff --git a/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt b/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt index 3990554..a23bbbd 100644 --- a/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt +++ b/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt @@ -14,9 +14,14 @@ import com.lukas.music.song.note.Note class BassVoice(instrument: Instrument) : Voice(instrument) { - override val steps = listOf(1, 3) + override var noteActive: Array> = arrayOf( + arrayOf(true), + arrayOf(false), + arrayOf(true), + arrayOf(false) + ) - override fun step(root: Note, chord: Array) { - instrument.startNote(chord[0] - 24) + override fun getNotes(root: Note, chordNotes: Array): Array { + return arrayOf(chordNotes[0] - 24) } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/voice/ChordVoice.kt b/app/src/main/java/com/lukas/music/song/voice/ChordVoice.kt deleted file mode 100644 index fc5362d..0000000 --- a/app/src/main/java/com/lukas/music/song/voice/ChordVoice.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.song.voice - -import com.lukas.music.instruments.Instrument -import com.lukas.music.song.note.Note - -class ChordVoice(instrument: Instrument) : Voice(instrument) { - override val steps: List = listOf(2, 4) - - override fun step(root: Note, chord: Array) { - instrument.stop() - for (note in chord) { - instrument.startNote(note) - } - } -} \ 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 6006bb7..aaa9e02 100644 --- a/app/src/main/java/com/lukas/music/instruments/Instrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/Instrument.kt @@ -12,17 +12,16 @@ 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 abstract class Instrument(var name: String) { - lateinit var voice: Voice + var voice = BassVoice(this) abstract var waveform: Waveform abstract var volume: Float abstract var muted: Boolean abstract fun startNote(note: Note) abstract fun stop() + abstract fun stopNote(note: Note) companion object { val instruments = @@ -30,10 +29,5 @@ MonoInstrument("Bass"), PolyInstrument("Chords"), ) - - val voice = mutableListOf( - BassVoice(instruments[0]), - ChordVoice(instruments[1]), - ) } } \ No newline at end of file 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 bc117e3..0bb7281 100644 --- a/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/InternalInstrument.kt @@ -10,8 +10,11 @@ package com.lukas.music.instruments +import com.lukas.music.song.note.Note + class InternalInstrument { private val id = createInstrument() + var note: Note? = null var waveform: Waveform = Waveform.SINE set(value) { @@ -50,11 +53,13 @@ volume = volume } - fun startNote(frequency: Double) { - startNote(id, frequency) + fun startNote(note: Note) { + this.note = note + startNote(id, note.frequency) } fun endNote() { + note = null endNote(id) } 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 55de0af..8b1ba50 100644 --- a/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/MonoInstrument.kt @@ -34,10 +34,19 @@ } override fun startNote(note: Note) { - internalInstrument.startNote(note.frequency) + if (note == internalInstrument.note) { + return + } + internalInstrument.startNote(note) } override fun stop() { internalInstrument.endNote() } + + override fun stopNote(note: Note) { + if (note == internalInstrument.note) { + stop() + } + } } \ No newline at end of file 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 e9cfd73..c6dae83 100644 --- a/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt +++ b/app/src/main/java/com/lukas/music/instruments/PolyInstrument.kt @@ -43,10 +43,13 @@ override fun startNote(note: Note) { for ((index, instrumentPlaying) in playing.withIndex()) { if (!instrumentPlaying) { - internalInstruments[index].startNote(note.frequency) + internalInstruments[index].startNote(note) playing[index] = true return } + if (internalInstruments[index].note == note) { + return + } } throw IllegalStateException("cannot start another note with the current amount of oscillators") } @@ -57,4 +60,13 @@ playing[i] = false } } + + override fun stopNote(note: Note) { + for ((i, instrument) in internalInstruments.withIndex()) { + if (instrument.note == note) { + instrument.endNote() + playing[i] = false + } + } + } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/Song.kt b/app/src/main/java/com/lukas/music/song/Song.kt index 33b8a7d..7f9823f 100644 --- a/app/src/main/java/com/lukas/music/song/Song.kt +++ b/app/src/main/java/com/lukas/music/song/Song.kt @@ -46,10 +46,10 @@ val chord = chordProgression.currentItem?.currentItem ?: return index val chordNotes = chord.getNotes(root) soloInstrument?.let { - it.voice.step(root, chordNotes) + it.voice.step(root, chordNotes, index) } ?: run { - for (voice in Instrument.voice) { - voice.step(root, chordNotes) + for (instrument in Instrument.instruments) { + instrument.voice.step(root, chordNotes, index) } } return index diff --git a/app/src/main/java/com/lukas/music/song/note/Note.kt b/app/src/main/java/com/lukas/music/song/note/Note.kt index d3a588d..17bfb2b 100644 --- a/app/src/main/java/com/lukas/music/song/note/Note.kt +++ b/app/src/main/java/com/lukas/music/song/note/Note.kt @@ -28,6 +28,22 @@ return this + (-other) } + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as Note + + if (id != other.id) return false + + return true + } + + override fun hashCode(): Int { + return id + } + + companion object { val NOTES = Array(128) { Note(it) } diff --git a/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt b/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt index 3990554..a23bbbd 100644 --- a/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt +++ b/app/src/main/java/com/lukas/music/song/voice/BassVoice.kt @@ -14,9 +14,14 @@ import com.lukas.music.song.note.Note class BassVoice(instrument: Instrument) : Voice(instrument) { - override val steps = listOf(1, 3) + override var noteActive: Array> = arrayOf( + arrayOf(true), + arrayOf(false), + arrayOf(true), + arrayOf(false) + ) - override fun step(root: Note, chord: Array) { - instrument.startNote(chord[0] - 24) + override fun getNotes(root: Note, chordNotes: Array): Array { + return arrayOf(chordNotes[0] - 24) } } \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/voice/ChordVoice.kt b/app/src/main/java/com/lukas/music/song/voice/ChordVoice.kt deleted file mode 100644 index fc5362d..0000000 --- a/app/src/main/java/com/lukas/music/song/voice/ChordVoice.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * 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.song.voice - -import com.lukas.music.instruments.Instrument -import com.lukas.music.song.note.Note - -class ChordVoice(instrument: Instrument) : Voice(instrument) { - override val steps: List = listOf(2, 4) - - override fun step(root: Note, chord: Array) { - instrument.stop() - for (note in chord) { - instrument.startNote(note) - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/lukas/music/song/voice/Voice.kt b/app/src/main/java/com/lukas/music/song/voice/Voice.kt index 9a58ec0..1b3ead1 100644 --- a/app/src/main/java/com/lukas/music/song/voice/Voice.kt +++ b/app/src/main/java/com/lukas/music/song/voice/Voice.kt @@ -14,13 +14,23 @@ import com.lukas.music.song.note.Note abstract class Voice(val instrument: Instrument) { - abstract val steps: List + abstract var noteActive: Array> - abstract fun step(root: Note, chord: Array) + abstract fun getNotes(root: Note, chordNotes: Array): Array - init { - // TODO: fix this (have voice be an attribute of Instrument)! - // TODO: introduce DefaultVoices and CustomVoice - instrument.voice = this + fun step(root: Note, chordNotes: Array, beat: Int) { + if (instrument.muted) { + return + } + val activeNotes = noteActive[beat] + val notes = getNotes(root, chordNotes) + for ((index, active) in activeNotes.withIndex()) { + val note = notes[index] + if (!active) { + instrument.stopNote(note) + continue + } + instrument.startNote(note) + } } } \ No newline at end of file