Saturday, October 13, 2012

Tone Generator with Python, PyGame, SciPy and SciKits AudioLab modules


Project: 

Generate sine wave sounds with drums triggers while changing the pitches with a MIDI controller using Python modules some fancy IF statements.

Baby Step:

Read MIDI events and output changing sine wave sounds

Progress:

Working but laggy, see code below and here http://pastebin.com/VTBQxjQm


# f is the frequency of the tone in Hertz,
# fs is the sampling rate, and
# T is the length of the tone in seconds.
import scikits.audiolab
import scipy
import pygame
import pygame.midi
from pygame.locals import *
pygame.mixer.pre_init(44100,-16,2,2048)
pygame.init()
pygame.midi.init()

f = 440
fs = 11025 #22050
T = 0.1
x = scipy.cos((2*scipy.pi*f/fs)*scipy.arange(fs*T))
scikits.audiolab.play(x, fs)


for i in range( pygame.midi.get_count() ):
    r = pygame.midi.get_device_info(i)
    (interf, name, input, output, opened) = r
    in_out = ""
    if input:
        in_out = "(input)"
    if output:
        in_out = "(output)"
    print ("%2i: interface :%s:, name :%s:, opened :%s:  %s" % (i, interf, name, opened, in_out))

mydevicenumber=raw_input('See list above. Please enter the number for your midi input device: ')
print "you chose " + mydevicenumber + ''
reserved_channel_0 = pygame.mixer.Channel(0)
my_font = pygame.font.SysFont("Arial",104)

pygame.fastevent.init()
event_get = pygame.fastevent.get
event_post = pygame.fastevent.post
input_id = int(mydevicenumber)
i = pygame.midi.Input( input_id )
pygame.display.set_caption("midi to sine wave sound generator")
screen = pygame.display.set_mode((800, 600), RESIZABLE, 32)

print "starting"
going = True
while going:
    events = event_get()
    for e in events:
        if e.type in [QUIT]:
            going = False
    if i.poll():
        midi_events = i.read(10)
        #print "full midi_events " + str(midi_events)
        #print "my midi note is " + str(midi_events[0][0][1])
        if str(midi_events[0][0][2]) != "0":
            mymidinote = str(midi_events[0][0][1])
            mymidinumber = int(mymidinote)
            mymidinumber = mymidinumber + 0.0   #types matter here!  
            #freq = 440*(2**((m-69)/12))
            f = 440*(2**((mymidinumber-69)/12))
            x = scipy.cos((2*scipy.pi*f/fs)*scipy.arange(fs*T))
            print "before (fast here)"
            scikits.audiolab.play(x, fs)
            print "after (laggy here)"
            #print "on event"
            #print "freq = " + str(f)
        if str(midi_events[0][0][2]) == "0":
            mymidinote = "0"
            #print "off event"
        #convert them into pygame events.
        midi_evs = pygame.midi.midis2events(midi_events, i.device_id)
        for m_e in midi_evs:
            event_post( m_e )
del i
exit()

bgryderclock micro-blog