Skip to main content

Featured

Python programming 8 Music with mouse-drawn lines by PyGame

I revised my previous program "Small interactive music maker" and now melody is made from mouse-drawn lines. Actually, change is not big. Instead of my Fourier series function, two key functions are included as - draw lines with mouse by pygame - from line to fx Drawing lines from below.   https://www.dreamincode.net/forums/topic/401541-buttons-and-sliders-in-pygame/ This must be some pretty fun for kids!   ---------------------------------------------------------------------------------------------- blog 8 Some versions of pygame may have some bug. Need " pip install pygame==2.0.0.dev6 " import pygame, math, sys, time import pygame.midi # use pygame.midi (not Mido) from random import random, choice pygame.init() # initialize Pygame pygame.midi.init() # initialize Pygame MIDI port = pygame.midi.Output(0) # port open port.set_instrument(53, channel = 0) # Voice port.set_instrument(0, channel = 1) # piano port.set_instrument(33, channel = 2) # bass X = 900 ...

Python programming 1 Basics of Mido for MIDI handling

Python library Mido handles MIDI (Musical Instrument Digital Interface).

This is a basic Mido program to play some notes as:
- include libraries
- open MIDI port
- create MIDI file and add 2 tracks
- set tempo
- add some notes to tracks
- send MIDI message to port to play music

 -----------------------------------------------------------------------------------------------------

 
# blog 1 example

# Need “pip install Mido”
# Need “pip install mido python-rtmidi”
import mido
import time
from mido import Message, MidiFile, MidiTrack, MetaMessage

# open MIDI port to play music
ports = mido.get_output_names()
port = mido.open_output(ports[0])

# create new MIDI file
mid = MidiFile()
track0 = MidiTrack() # tempo
track1 = MidiTrack() # instrument 1
mid.tracks.append(track0)
mid.tracks.append(track1)

# set tempo
bpm = 60 # beat per minutes
track0.append(MetaMessage('set_tempo', tempo=int(1000000*60/bpm), time=0))

# convert to beat to MIDI time scale (1 beat to 480 ticks)
def beat_to_tick(dur):
    return int(dur * 480 +0.5)

# add notes to track
track1.append(Message('program_change', channel = 0, program=0,time=0)) # program (instrument) = 0 (Piano)
# 1st note, C4 (60), 1 beat
track1.append(Message('note_on', channel = 0, note=60, velocity=70, time=0))
track1.append(Message('note_off', channel = 0, note=60, velocity=0, time=beat_to_tick(1)))
# 2nd note, D4 (62), 2 beat
track1.append(Message('note_on', channel = 0, note=62, velocity=70, time=0))
track1.append(Message('note_off', channel = 0, note=62, velocity=0, time=beat_to_tick(2)))

# "time" means a waiting time before sending a Message to MIDI instruments.
# So, this is a sequential process.

# If you need to start a new note before the end of previous note, you need to write below.
# a bit complicated.
# Probably, it is easier to divide notes to different tracks.
# Below "play MIDI file" automatically combines two tracks to Messages like below.

# 3rd note, E4 (64), 2 beat
track1.append(Message('note_on', channel = 0, note=64, velocity=70, time=0))
# 4th note, G4 (67), 1 beat start during 3rd note is on
track1.append(Message('note_on', channel = 0, note=67, velocity=70, time=beat_to_tick(1)))
# both 3rd and 4th note off at the same time
track1.append(Message('note_off', channel = 0, note=64, velocity=0, time=beat_to_tick(1)))
track1.append(Message('note_off', channel = 0, note=67, velocity=0, time=beat_to_tick(0)))

# play MIDI file
for msg in mid:
    time.sleep(msg.time)
    if not msg.is_meta:
        port.send(msg)

For more details, see Mido explanations below.

https://mido.readthedocs.io/en/latest/midi_files.html

 -----------------------------------------------------------------------------------------------------

 # blog 1 example

 


Comments