Syllabus 20091201

From XPUB & Lens-Based wiki


Today we are coding a version of the DIMI-O from Erkki Kurenniemi.

Generating tones

Generate a range of tones (not a half-tone scale)

for ((i=-24; i<0;i++))
do
echo $i
freq=$((2*i+18))
sox -c1 -r441000 -n bleep$i.wav synth 0.25 sine %$freq vol 0.7 fade h 0.05 0.15 0.05
done


Running BASH commands from within Python

Simplest way is with os.system:

import os
os.system("ls")


These functions use the subprocess module which gives more options for controlling how a BASH command gets run.

DEVNULL = open(os.devnull)

def shell (cmd, ignoreSTDERR = True):
    """ always synchronous (python waits for command to finish), adding "&" to command has no effect """
    if ignoreSTDERR:
        return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=DEVNULL).communicate()[0].strip()
    else:
        return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()[0].strip()

def shellbg (cmd, ignoreSTDERR = True):
    """ asynchronous, command runs in the background letting python continue immediately """
    parts = cmd.split()    
    if ignoreSTDERR:
        return subprocess.Popen(parts, stdout=subprocess.PIPE, stderr=DEVNULL)
    else:
        return subprocess.Popen(parts, stdout=subprocess.PIPE)


Connecting back to the camera

#!/usr/bin/python

import sys
import pygame
from pygame.locals import *
from pygame.time import Clock
from time import sleep
import thread

def reader ():
    while True:
        line = sys.stdin.readline()
        if (not line): break
        line = line.strip()
        if line.startswith("image"):
                # print "read motion data:", line
                parts = line.strip().split()
                x = int(parts[1])                
                y = int(parts[2])                
                w = int(parts[3])                
                h = int(parts[4])                
                numpixels = int(parts[5])
                imgfilename = parts[6]
                print x, y, w, h, imgfilename                
                # (x, y, w, h, numpixels) = [int(x) for x in line.split()[1:]]
                evt = pygame.event.Event(USEREVENT, {"x" : x, "y": y, "w":w, "h":h, "f": imgfilename})
                pygame.event.post(evt)

(mx, my, mw, mh) = (10, 10, 50, 50)
pygame.init()
# screen = pygame.display.set_mode((640, 480), FULLSCREEN, 32)
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption("motionbox")
clock = Clock()

thread.start_new_thread(reader, ())
image = None

while True:
    for event in pygame.event.get():
        if event.type==QUIT or \
            (event.type == KEYDOWN and event.key == K_ESCAPE):
            sys.exit()
        elif event.type == USEREVENT:
            # print event
            mx = event.x
            my = event.y
            mw = event.w
            mh = event.h
            mx -= mw/2
            my -= mh/2
            image = pygame.image.load(event.f).convert()
            print image

    screen.fill((0, 0, 0))
    pygame.draw.rect(screen, (255, 255, 255), (mx, my, mw, mh), 1)
    if image:
        screen.blit(image, (0, 0))
    pygame.display.update()
    clock.tick(30)


import sys, pygame, os,subprocess
pygame.init()

width, height = (640, 480)
screen = pygame.display.set_mode((width, height))
clock = pygame.time.Clock()

def slide(start, end, slider):
    x = ((end-start)*slider)+start
    return x

DEVNULL = open(os.devnull)

def shell (cmd, ignoreSTDERR = True):
    """ always synchronous, adding "&" to command has no effect """
    if ignoreSTDERR:
        return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=DEVNULL).communicate()[0].strip()
    else:
        return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()[0].strip()

def shellbg (cmd, ignoreSTDERR = True):
    """ always synchronous, adding "&" to command has no effect """
    parts = cmd.split()    
    if ignoreSTDERR:
        return subprocess.Popen(parts, stdout=subprocess.PIPE, stderr=DEVNULL)
    else:
        return subprocess.Popen(parts, stdout=subprocess.PIPE)

prev_tone=0

while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT or \
          (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE):
            sys.exit()


    mx, my = pygame.mouse.get_pos()
    x_slider = (mx/float(width))
    y_slider = (my/float(height))
    
    tone = slide(0,-24,y_slider)
    tone=int(round(tone))
    # print tone
    
    
    if prev_tone!=tone:
        command = "play bleep"+str(tone)+".wav"
        # print command
        shellbg(command)
        prev_tone=tone
    
    
    c = min(my, 255)
    screen.fill((0, 0, 0))
    
    pygame.draw.rect(screen, (c, 255, 255), ((width/2)-5, (-(height/24)*tone)-5, 10, 10), 0)
    pygame.display.flip()
    
    clock.tick(30)



#!/usr/bin/python

import sys, os, subprocess
import pygame
from pygame.locals import *
from pygame.time import Clock
from time import sleep
import thread

def reader ():
    while True:
        line = sys.stdin.readline()
        if (not line): break
        line = line.strip()
        if line.startswith("image"):
                # print "read motion data:", line
                parts = line.strip().split()
                x = int(parts[1])                
                y = int(parts[2])                
                w = int(parts[3])                
                h = int(parts[4])                
                numpixels = int(parts[5])
                imgfilename = parts[6]
                # print x, y, w, h, imgfilename                
                # (x, y, w, h, numpixels) = [int(x) for x in line.split()[1:]]
                evt = pygame.event.Event(USEREVENT, {"x" : x, "y": y, "w":w, "h":h, "f": imgfilename})
                pygame.event.post(evt)

def slide(start, end, slider):
    x = ((end-start)*slider)+start
    return x

DEVNULL = open(os.devnull)

def shell (cmd, ignoreSTDERR = True):
    """ always synchronous, adding "&" to command has no effect """
    if ignoreSTDERR:
        return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=DEVNULL).communicate()[0].strip()
    else:
        return subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()[0].strip()

def shellbg (cmd, ignoreSTDERR = True):
    """ always synchronous, adding "&" to command has no effect """
    parts = cmd.split()    
    if ignoreSTDERR:
        return subprocess.Popen(parts, stdout=subprocess.PIPE, stderr=DEVNULL)
    else:
        return subprocess.Popen(parts, stdout=subprocess.PIPE)




prev_tone=0
(mx, my, mw, mh) = (10, 10, 50, 50)
pygame.init()
# screen = pygame.display.set_mode((640, 480), FULLSCREEN, 32)
w = 640
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption("motionbox")
clock = Clock()

thread.start_new_thread(reader, ())
image = None
rx,ry,rw,rh = (0,0,0,0)

while True:
    for event in pygame.event.get():
        if event.type==QUIT or \
            (event.type == KEYDOWN and event.key == K_ESCAPE):
            sys.exit()
        elif event.type == USEREVENT:
            # print event
            mx = event.x
            my = event.y
            mw = event.w
            mh = event.h
            mx -= mw/2
            my -= mh/2
            image = pygame.image.load(event.f).convert()
            #print image

    screen.fill((0, 0, 0))
    if image:
        screen.blit(image, (0, 0))
    
    # dampened feedback
    rx += 0.25 * (mx - rx)
    ry += 0.25 * (my - ry)
    rw += 0.25 * (mw - rw)
    rh += 0.25 * (mh - rh)
    
    
    
    slider = ((rx+(rw/2))/float(w))
    tone = slide(0,-24,slider)
    tone=int(round(tone))
    # print tone
    
    
    if prev_tone!=tone:
        command = "play bleep"+str(tone)+".wav"
        # print command
        shellbg(command)
        prev_tone=tone
    
    pygame.draw.rect(screen, (255, 255, 255), (rx, ry, rw, rh), 20)
    pygame.display.update()
    clock.tick(30)


Attachments