tinkering.py 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. #!/usr/bin/env python
  2. from midiutil import MIDIFile
  3. from mingus.core import chords
  4. NOTES = ['C', 'C#', 'D', 'Eb', 'E', 'F', 'F#', 'G', 'Ab', 'A', 'Bb', 'B']
  5. OCTAVES = list(range(11))
  6. NOTES_IN_OCTAVE = len(NOTES)
  7. errors = {
  8. 'notes': 'Bad input please refer this spec-\n',
  9. }
  10. def swap_accidentals(note):
  11. match note:
  12. case 'Db':
  13. return 'C#'
  14. case 'D#':
  15. return 'Eb'
  16. case 'E#':
  17. return 'F'
  18. case 'Gb':
  19. return 'F#'
  20. case 'G#':
  21. return 'Ab'
  22. case 'A#':
  23. return 'Bb'
  24. case 'B#':
  25. return 'C'
  26. case _:
  27. return note
  28. def note_to_number(note: str, octave: int) -> int:
  29. note = swap_accidentals(note)
  30. assert note in NOTES, errors['notes']
  31. assert octave in OCTAVES, errors['notes']
  32. notenum = NOTES.index(note)
  33. notenum += (NOTES_IN_OCTAVE * octave)
  34. assert 0 <= notenum <= 127, errors['notes']
  35. return notenum
  36. chord_progression = ["Cmaj7", "Cmaj7", "Fmaj7", "Gdom7"]
  37. arpeggio_notes = []
  38. bass_notes = []
  39. for chord in chord_progression:
  40. arpeggio_notes.extend(chords.from_shorthand(chord))
  41. bass_notes.append(chords.from_shorthand(chord)[0])
  42. arpeggio_octave = 4
  43. arpeggio_nums = [note_to_number(x, arpeggio_octave) for x in arpeggio_notes]
  44. bass_octave = 3
  45. bass_nums = [note_to_number(x, bass_octave) for x in bass_notes]
  46. arpeggio_track = 0
  47. bass_track = 1
  48. channel = 0
  49. time = 0 # in beats
  50. arpeggio_duration = 1 # in beats
  51. bass_duration = 4 # in beats
  52. tempo = 120 # in BPM
  53. volume = 100 # 0-127
  54. MyMIDI = MIDIFile(2) # two tracks, defaults to format 1
  55. # tempo track is created automatically
  56. MyMIDI.addTempo(arpeggio_track, time, tempo)
  57. for i, pitch in enumerate(arpeggio_nums):
  58. MyMIDI.addNote(arpeggio_track, channel, pitch, time + i, arpeggio_duration, volume)
  59. for i, pitch in enumerate(bass_nums):
  60. MyMIDI.addNote(bass_track, channel, pitch, time + (i*4), bass_duration, volume)
  61. with open("pure-edm-fire-arpeggio.mid", "wb") as output_file:
  62. MyMIDI.writeFile(output_file)
  63. # print(arpeggio_notes)