diff --git a/src/midi_kasittelija.py b/src/midi_kasittelija.py index 74c7461..0c1b7eb 100644 --- a/src/midi_kasittelija.py +++ b/src/midi_kasittelija.py @@ -45,19 +45,40 @@ def lue_midi(tiedostopolku): return tulos -def kirjoita_midi(tiedostopolku, nuotit, tempo=120): +def kirjoita_midi(tiedostopolku, nuotit, tempo=120, rytmi="1/4"): """Kirjoittaa halutut nuotit valittuun MIDI-tiedostoon annetulla tempolla""" midi = mido.MidiFile() raita = mido.MidiTrack() + rytmi = rytmi_taulukoksi(rytmi) + iskun_kesto = midi.ticks_per_beat + rytmi = [round(x*4*iskun_kesto) for x in rytmi] + raita.append(mido.MetaMessage("set_tempo", tempo=mido.bpm2tempo(tempo), time=0)) raita.append(mido.MetaMessage("time_signature")) raita.append(mido.Message("program_change", program=0, time=0)) + rytmi_i = 0 + for nuotti in nuotit: if nuotti: raita.append(mido.Message("note_on", note=nuotti, velocity=64, time=0)) - raita.append(mido.Message("note_on", note=nuotti, velocity=0, time=480)) + raita.append(mido.Message("note_on", note=nuotti, velocity=0, time=rytmi[rytmi_i])) + rytmi_i = (rytmi_i + 1) % len(rytmi) midi.tracks.append(raita) midi.save(tiedostopolku) + +def rytmi_taulukoksi(rytmi): + rytmi = rytmi.split("|") + tulos = [] + for alkio in rytmi: + alkio = alkio.split("/") + if len(alkio) == 2: + tulos.append(int(alkio[0]) / int(alkio[1])) + elif len(alkio) == 1: + tulos.append(int(alkio[0])) + else: + continue + + return tulos diff --git a/src/musiikki_generaattori.py b/src/musiikki_generaattori.py index 9aeab3b..6358a45 100644 --- a/src/musiikki_generaattori.py +++ b/src/musiikki_generaattori.py @@ -95,9 +95,9 @@ class MusiikkiGeneraattori: return len(self._nuotit) - def kirjoita_midi(self, tiedostopolku, tempo=120): - """Kirjoittaa nuotit MIDI-tiedostoon halutulla tempolla""" - kirjoita_midi(tiedostopolku, self._nuotit, tempo) + def kirjoita_midi(self, tiedostopolku, tempo=120, rytmi="1/4"): + """Kirjoittaa nuotit MIDI-tiedostoon halutulla tempolla ja rytmillä""" + kirjoita_midi(tiedostopolku, self._nuotit, tempo, rytmi) def _nuotit_midiksi(self, nuotit: str): """Muuttaa perinteiset nuottimerkinnät kuten C#4 MIDI-arvoiksi""" diff --git a/src/ui.py b/src/ui.py index 0c10808..37dceb1 100644 --- a/src/ui.py +++ b/src/ui.py @@ -12,8 +12,9 @@ class UI: # pylint: disable=too-few-public-methods, too-many-instance-attributes self._tulos_polku = "savelma.mid" self._aste = 1 self._alku = "C4" - self._nuottien_maara = 100 + self._nuottien_maara = 120 self._tempo = 120 + self._rytmi = "1/4" self._toiminnot = { "A": ("(A)pu", self._tulosta_apu, 0, @@ -24,12 +25,14 @@ class UI: # pylint: disable=too-few-public-methods, too-many-instance-attributes "Valitse valmiin sävelmän polku"), "K": ("(K)etjun aste", self._aseta_aste, 1, "Aseta Markovin ketjun aste valittuun kokonaislukuun"), - "L": ("a(L)kuosa [merkkijono]", self._aseta_alkuosa, 1, - "Aseta alkuosa. Esim. 'C4|D#5|Gb3'"), "N": ("(N)uotteja [luku]", self._aseta_nuottien_maara, 1, "Aseta sävelmän nuottien määrä valittuun kokonaislukuun"), "T": ("(T)empo [luku]", self._aseta_tempo, 1, "Aseta tempo valittuun kokonaislukuun"), + "R": ("(R)ytmi [merkkijono]", self._aseta_rytmi, 1, + "Aseta rytmi. Esim. '1/4|1/4|1/2'"), + "L": ("a(L)kuosa [merkkijono]", self._aseta_alkuosa, 1, + "Aseta alkuosa. Esim. 'C4|D#5|Gb3'"), "G": ("(G)eneroi sävelmä", self._generoi_savelma, 0, "Generoi sävelmä valituilla asetuksilla"), "S": ("(S)ulje", self._sulje, 0, @@ -93,6 +96,7 @@ class UI: # pylint: disable=too-few-public-methods, too-many-instance-attributes print(f"Markovin ketjun aste: {self._aste}") print(f"Sävelmän pituus nuotteina: {self._nuottien_maara}") print(f"Tempo: {self._tempo}") + print(f"Rytmi: '{self._rytmi}'") print(f"Alkuosa: '{self._alku}'") def _tulosta_apu(self, _): @@ -118,13 +122,6 @@ class UI: # pylint: disable=too-few-public-methods, too-many-instance-attributes except ValueError: self._virheet.append("ANNETTU ASTE EI MUUTETTAVISSA KOKONAISLUVUKSI!") - def _aseta_alkuosa(self, alkuosa): - alkuosa = alkuosa[0] - if search(r"^([CcDdEeFfGgAaBb][#b]?[0-8]\|)*[CcDdEeFfGgAaBb][#b]?[0-8]$", alkuosa): - self._alku = alkuosa - else: - self._virheet.append("ANNETTU ALKUOSA EI KELPAA!") - def _aseta_nuottien_maara(self, nuotteja): try: nuottien_maara = int(nuotteja[0]) @@ -143,13 +140,27 @@ class UI: # pylint: disable=too-few-public-methods, too-many-instance-attributes except ValueError: self._virheet.append("ANNETTU TEMPO EI KELPAA!") + def _aseta_rytmi(self, rytmi): + rytmi = rytmi[0] + if search(r"^\|?((([1-9]\/[1-9])|[1-9])\|)*(([1-9]/[1-9])|[1-9])\|?$", rytmi): + self._rytmi = rytmi + else: + self._virheet.append("ANNETTU RYTMI EI KELPAA!") + + def _aseta_alkuosa(self, alkuosa): + alkuosa = alkuosa[0] + if search(r"^\|?([CcDdEeFfGgAaBb][#b]?[0-8]\|)*[CcDdEeFfGgAaBb][#b]?[0-8]\|?$", alkuosa): + self._alku = alkuosa + else: + self._virheet.append("ANNETTU ALKUOSA EI KELPAA!") + def _generoi_savelma(self, _): musiikki_generaattori.lue_opetusdata(self._opetusdata_polku) musiikki_generaattori.valmistele_ketju(self._alku, self._aste) generoitu_maara = musiikki_generaattori.generoi_nuotteja(self._nuottien_maara) print(f"Generoitiin {generoitu_maara} nuottia!\n") - musiikki_generaattori.kirjoita_midi(self._tulos_polku, self._tempo) + musiikki_generaattori.kirjoita_midi(self._tulos_polku, self._tempo, self._rytmi) def _sulje(self): sys_exit(0)