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 6 Small interactive drum machine by PyGame

I made a small interactive drum machine by PyGame.

I tried to use matplotlib to make program interactive. But I couldn't.
So I used another library PyGame. PyGame has MIDI functions. But here I used graphic functions only. Library MIDO was used for MIDI functions as before.




 
After you run the program and see four circles. please click them. The rhythm of the circle changes.

At the beginning, all three circles are on the same rhythm of [1,1,0,1,1,1,1,0,0,1,0,1,0,0,0,0]. If you click, this slides by one.

So, click 2nd circle once, 3rd circle twice and 4th circle three times, you can see all 16 patterns of [on/off, on/off, on/off, on/off] with sounds.
Because this is de Bruijn sequence, in which every "4 streight figures" (1st one is 1101, second one is 1011, ...) has different patterns.  One click and the sequence slides by one. Two clicks for two slides and three clicks for three slides, which is the same as "4 straight figures".

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

 
blog 6

from pygame.locals import *
import pygame
import sys
import mido
import time
from mido import Message, MidiFile, MidiTrack, MetaMessage

# port open
ports = mido.get_output_names()
port = mido.open_output(ports[0])

# interactive drum machine
def main(bpm):
    pygame.init()    # initialize Pygame

   # show window
    SCREEN_SIZE = (610, 250)
    pygame.init()
    screen = pygame.display.set_mode(SCREEN_SIZE) # screen
    screen.fill((255,250,250))

    font1 = pygame.font.SysFont(None, 50)
    text1 = font1.render("Click Circles", True, (0,0,0))
    screen.blit(text1, (190,30))
    pygame.display.set_caption("small interactive rhythm machine")    # Caption

    # prepare for drum
    rhythm = [1,1,0,1,1,1,1,0,0,1,0,1,0,0,0,0] # de Bruijn Rhythm
    i = 0
    j = 0
    k = 0
    l = 0
    time.sleep(0.5)
    time1 = time.time()
    while True:
        # 35: BASS, 42: CHH, 45: Low Tom, 47 Low Mid Tom, 48: High Mid Tom, 50: High Tom
       
        # draw circles
        pygame.draw.circle(screen, (250-25*rhythm[i%16],250-55*rhythm[i%16],250-95*rhythm[i%16]), (80,150), 60)
        pygame.draw.circle(screen, (250-35*rhythm[j%16],250-65*rhythm[j%16],250-105*rhythm[j%16]), (230,150), 60)
        pygame.draw.circle(screen, (250-45*rhythm[k%16],250-75*rhythm[k%16],250-115*rhythm[k%16]), (380,150), 60)
        pygame.draw.circle(screen, (250-55*rhythm[l%16],250-85*rhythm[l%16],250-125*rhythm[l%16]), (530,150), 60)
        pygame.display.update()

        # send MIDI message "note_on"
        port.send(Message('note_on', channel=9, note=45, velocity=70*rhythm[i%16]))     # Low Tam
        port.send(Message('note_on', channel=9, note=47, velocity=70*rhythm[j%16]))     # Low Mid Tom
        port.send(Message('note_on', channel=9, note=48, velocity=70*rhythm[k%16]))     # High Mid Tom
        port.send(Message('note_on', channel=9, note=50, velocity=70*rhythm[l%16]))     # High Tom
        # wait for note off
        time.sleep(max(30/bpm-0.02-(time.time()-time1),0))
        time1 = time.time()

        pygame.draw.circle(screen, (255,250,250), (80,150), 60)
        pygame.draw.circle(screen, (255,250,250), (230,150), 60)
        pygame.draw.circle(screen, (255,250,250), (380,150), 60)
        pygame.draw.circle(screen, (255,250,250), (530,150), 60)
        pygame.display.update()
        port.send(Message('note_on', channel=9, note=45, velocity=0))
        port.send(Message('note_on', channel=9, note=47, velocity=0))
        port.send(Message('note_on', channel=9, note=48, velocity=0))
        port.send(Message('note_on', channel=9, note=50, velocity=0))
        time.sleep(0.02)
        i += 1
        j += 1
        k += 1
        l += 1
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

            # Click event
            if event.type == MOUSEBUTTONDOWN:
                x, y = event.pos
                if ((80-x)**2 + (150-y)**2) < 60**2:
                    i += 1
                elif ((230-x)**2 + (150-y)**2) < 60**2:
                    j += 1
                elif ((380-x)**2 + (150-y)**2) < 60**2:
                    k += 1
                elif ((530-x)**2 + (150-y)**2) < 60**2:
                    l += 1
        pygame.display.update()
bpm = 140
main(bpm)



Comments