Saturday, January 31, 2009

Digital Beethoven

A case: you have to look at a measuring instrument every few seconds for some long minutes but don't want to use stopwatch because you want to concentrate on something else, what then? Also there is a laptop available.

In my case, I made a python script to play a sound file every few seconds to interrupt me from whatever I was reading or discussing, and look at the instrument. The sound file would say something like "take measurement", "take reading", or "look at the meter", just because. I used winsound from python standard library, it's simple. It's a Windows specific thing, but as I'm stuck with windows at work anyway, might as well.

The fun wasn't actually in getting the script work and getting the experiment done more effectively, it was in discovering how easy it is to make a sinusoid beep at (almost) any audible frequency. So, something has to be done during the wait times and it was this: Für Elise in beeps.

import time as t
import winsound as w

#musical scale. Some are off by some hertz, don't protest
middle = {'C': 262,
         'D': 294,
         'd': 312,
         'E': 330,
         'F': 349,
         'G': 392,
         'g': 416,
         'A': 440,
         'B': 494,
         ' ': 37}

#the duration for a quarter note in miliseconds. Arbitrary, don't complain
beat = 498

#the score, believe it
elise = [('E5',0.5),('d5',0.5),
        ('E5',0.5),('d5',0.5), ('E5',0.5), ('A4',0.5), ('D5',0.5), ('C5',0.5),
        ('G4',1.5),('C4',0.5), ('E4',0.5), ('A4',0.5),
        ('B4',1.5),('E4',0.5), ('g4',0.5), ('B4',0.5),
        ('C5',1.5),('E4',0.5), ('D5',0.5), ('C5',0.5),
        ('B4',1.5),('E4',0.5), ('E4',0.5), ('E5',0.5),('E4',0.5),
        ('E5',0.5),('E5',0.5), ('E6',0.5), ('d5',0.5),('E5',0.5),('d5',0.5),
        ('E5',0.5),('d5',0.5), ('E5',0.5), ('d5',0.5),('E5',0.5),('d5',0.5),
        ('E5',0.5),('d5',0.5), ('E5',0.5), ('B4',0.5),('D5',0.5),('C5',0.5),
        ('A4',1.5),('C4',0.5), ('E4',0.5), ('A4',0.5),
        ('B4',1.5),('E4',0.5), ('g4',0.5), ('B4',0.5),
        ('C5',1.5),('E4',0.5), ('E5',0.5), ('d5',0.5),
        ('E5',0.5),('d5',0.5), ('E5',0.5), ('B4',0.5),('D5',0.5),('C5',0.5),
        ('A4',1.5),('C4',0.5), ('E4',0.5), ('A4',0.5),
        ('B4',1.5),('D4',0.5), ('C5',0.5), ('B4',0.5),
        ('A4',2)]

#this code plays the score
for elem in elise:
   freq = int(middle[elem[0][0]]*(2**(int(elem[0][1])-4)))
   dura = int(beat*elem[1])

   #this is what makes the sound
   w.Beep(freq, dura)

   #a blink interval between notes, so the same note played twice would
   #still have a pause in between
   t.sleep(0.002)

Go ahead and dissect it, maybe something interesting would come out. To try it out yourself: save the code into 'something.py', get python interpreter if you haven't, open your 'something.py' in the interpreter, pull your hair out after listening to the robotic piece

Something similar can be done with wave library, which is not windows specific, only I still can't be bothered to read the documentation

1 comments:

  1. This is extremely interesting. I'm going to try to re-read this a bunch of times and use it to create something, then I will send you that thing.

    ReplyDelete