mirror of https://github.com/python/cpython
Initial revision
This commit is contained in:
parent
4a5ab81bc9
commit
715a653152
|
@ -0,0 +1,8 @@
|
|||
Programs that demonstrate the use of the audio device on the SGI 4D/25.
|
||||
These require the built-in module 'audio'.
|
||||
|
||||
XXX This hardware is already obsolete; see ../al for examples of audio
|
||||
XXX on the Indigo and 4D/35.
|
||||
|
||||
play Read a sound sample from a file and play it through the
|
||||
speaker. Options to set volume, sampling rate etc.
|
|
@ -0,0 +1,75 @@
|
|||
#! /usr/local/python
|
||||
|
||||
import sys
|
||||
import audio
|
||||
|
||||
import string
|
||||
import getopt
|
||||
import auds
|
||||
|
||||
debug = []
|
||||
|
||||
DEF_RATE = 3
|
||||
|
||||
def main():
|
||||
#
|
||||
gain = 100
|
||||
rate = 0
|
||||
starter = audio.write
|
||||
stopper = 0
|
||||
#
|
||||
optlist, args = getopt.getopt(sys.argv[1:], 'adg:r:')
|
||||
#
|
||||
for optname, optarg in optlist:
|
||||
if 0:
|
||||
pass
|
||||
elif optname == '-d':
|
||||
debug.append(1)
|
||||
elif optname == '-g':
|
||||
gain = string.atoi(optarg)
|
||||
if not (0 < gain < 256):
|
||||
raise optarg.error, '-g gain out of range'
|
||||
elif optname == '-r':
|
||||
rate = string.atoi(optarg)
|
||||
if not (1 <= rate <= 3):
|
||||
raise optarg.error, '-r rate out of range'
|
||||
elif optname == '-a':
|
||||
starter = audio.start_playing
|
||||
stopper = audio.wait_playing
|
||||
#
|
||||
audio.setoutgain(gain)
|
||||
audio.setrate(rate)
|
||||
#
|
||||
if not args:
|
||||
play(starter, rate, auds.loadfp(sys.stdin))
|
||||
else:
|
||||
real_stopper = 0
|
||||
for file in args:
|
||||
if real_stopper:
|
||||
real_stopper()
|
||||
play(starter, rate, auds.load(file))
|
||||
real_stopper = stopper
|
||||
|
||||
def play(starter, rate, data):
|
||||
magic = data[:4]
|
||||
if magic == '0008':
|
||||
mrate = 3
|
||||
elif magic == '0016':
|
||||
mrate = 2
|
||||
elif magic == '0032':
|
||||
mrate = 1
|
||||
else:
|
||||
mrate = 0
|
||||
if mrate:
|
||||
data = data[4:]
|
||||
else:
|
||||
mrate = DEF_RATE
|
||||
if not rate: rate = mrate
|
||||
audio.setrate(rate)
|
||||
starter(data)
|
||||
|
||||
try:
|
||||
main()
|
||||
finally:
|
||||
audio.setoutgain(0)
|
||||
audio.done()
|
|
@ -0,0 +1,19 @@
|
|||
Three programs that provide a user interface based upon STDWIN to the
|
||||
audio device of the SGI 4D/25. These scripts also demonstrate the power
|
||||
of a set of window interface classes implemented in Python that simplify
|
||||
the construction of all sorts of buttons, etc.
|
||||
|
||||
XXX This hardware is already obsolete; see ../al for examples of audio
|
||||
XXX on the Indigo and 4D/35.
|
||||
|
||||
jukebox Browses a directory full of sound samples and lets you
|
||||
play selected ones. (Probably not fully functional, it
|
||||
requires a conversion program.)
|
||||
|
||||
rec A tape recorder that lets you record a sound sample,
|
||||
play it back, and save it to a file. Various options to
|
||||
set sampling rate, volume etc. When idle it doubles
|
||||
as a VU meter.
|
||||
|
||||
vumeter A VU meter that displays a history of the volume of
|
||||
sound recently sampled from the microphone.
|
|
@ -0,0 +1,321 @@
|
|||
#! /usr/local/python
|
||||
|
||||
# JUKEBOX: browse directories full of sampled sound files.
|
||||
#
|
||||
# One or more "list windows" display the files and subdirectories of
|
||||
# the arguments. Double-clicking on a subdirectory opens a new window
|
||||
# displaying its contents (and so on recursively). Double clicking
|
||||
# on a file plays it as a sound file (assuming it is one).
|
||||
#
|
||||
# Playing is asynchronous: the application keeps listening to events
|
||||
# while the sample is playing, so you can change the volume (gain)
|
||||
# during playing, cancel playing or start a new sample right away.
|
||||
#
|
||||
# The control window displays the current output gain and a primitive
|
||||
# "stop button" to cancel the current play request.
|
||||
#
|
||||
# Sound files must currently be in Dik Winter's compressed Mac format.
|
||||
# Since decompression is costly, decompressed samples are saved in
|
||||
# /usr/tmp/@j* until the application is left. The files are read
|
||||
# afresh each time, though.
|
||||
|
||||
import audio
|
||||
import sunaudio
|
||||
import commands
|
||||
import getopt
|
||||
import path
|
||||
import posix
|
||||
import rand
|
||||
import stdwin
|
||||
from stdwinevents import *
|
||||
import string
|
||||
import sys
|
||||
|
||||
from WindowParent import WindowParent
|
||||
from HVSplit import VSplit
|
||||
from Buttons import PushButton
|
||||
from Sliders import ComplexSlider
|
||||
|
||||
# Pathnames
|
||||
|
||||
HOME_BIN_SGI = '/ufs/guido/bin/sgi/' # Directory where macsound2sgi lives
|
||||
DEF_DB = '/ufs/dik/sounds/Mac/HCOM' # Default directory of sounds
|
||||
|
||||
|
||||
# Global variables
|
||||
|
||||
class struct: pass # Class to define featureless structures
|
||||
|
||||
G = struct() # Holds writable global variables
|
||||
|
||||
|
||||
# Main program
|
||||
|
||||
def main():
|
||||
G.synchronous = 0 # If set, use synchronous audio.write()
|
||||
G.debug = 0 # If set, print debug messages
|
||||
G.gain = 75 # Output gain
|
||||
G.rate = 3 # Sampling rate
|
||||
G.busy = 0 # Set while asynchronous playing is active
|
||||
G.windows = [] # List of open windows (except control)
|
||||
G.mode = 'mac' # Macintosh mode
|
||||
G.tempprefix = '/usr/tmp/@j' + `rand.rand()` + '-'
|
||||
#
|
||||
optlist, args = getopt.getopt(sys.argv[1:], 'dg:r:sSa')
|
||||
for optname, optarg in optlist:
|
||||
if optname == '-d':
|
||||
G.debug = 1
|
||||
elif optname == '-g':
|
||||
G.gain = string.atoi(optarg)
|
||||
if not (0 < G.gain < 256):
|
||||
raise optarg.error, '-g gain out of range'
|
||||
elif optname == '-r':
|
||||
G.rate = string.atoi(optarg)
|
||||
if not (1 <= G.rate <= 3):
|
||||
raise optarg.error, '-r rate out of range'
|
||||
elif optname == '-s':
|
||||
G.synchronous = 1
|
||||
elif optname == '-S':
|
||||
G.mode = 'sgi'
|
||||
elif optname == '-a':
|
||||
G.mode = 'sun'
|
||||
#
|
||||
if not args:
|
||||
args = [DEF_DB]
|
||||
#
|
||||
G.cw = opencontrolwindow()
|
||||
for dirname in args:
|
||||
G.windows.append(openlistwindow(dirname))
|
||||
#
|
||||
#
|
||||
savegain = audio.getoutgain()
|
||||
try:
|
||||
# Initialize stdaudio
|
||||
audio.setoutgain(0)
|
||||
audio.start_playing('')
|
||||
dummy = audio.wait_playing()
|
||||
audio.setoutgain(0)
|
||||
maineventloop()
|
||||
finally:
|
||||
audio.setoutgain(savegain)
|
||||
audio.done()
|
||||
clearcache()
|
||||
|
||||
def maineventloop():
|
||||
mouse_events = WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP
|
||||
while G.windows:
|
||||
type, w, detail = event = stdwin.getevent()
|
||||
if w == G.cw.win:
|
||||
if type == WE_CLOSE:
|
||||
return
|
||||
G.cw.dispatch(event)
|
||||
else:
|
||||
if type == WE_DRAW:
|
||||
w.drawproc(w, detail)
|
||||
elif type in mouse_events:
|
||||
w.mouse(w, type, detail)
|
||||
elif type == WE_CLOSE:
|
||||
w.close(w)
|
||||
del w, event
|
||||
else:
|
||||
if G.debug: print type, w, detail
|
||||
|
||||
# Control window -- to set gain and cancel play operations in progress
|
||||
|
||||
def opencontrolwindow():
|
||||
cw = WindowParent().create('Jukebox', (0, 0))
|
||||
v = VSplit().create(cw)
|
||||
#
|
||||
gain = ComplexSlider().define(v)
|
||||
gain.setminvalmax(0, G.gain, 255)
|
||||
gain.settexts(' ', ' ')
|
||||
gain.sethook(gain_setval_hook)
|
||||
#
|
||||
stop = PushButton().definetext(v, 'Stop')
|
||||
stop.hook = stop_hook
|
||||
#
|
||||
cw.realize()
|
||||
return cw
|
||||
|
||||
def gain_setval_hook(self):
|
||||
G.gain = self.val
|
||||
if G.busy: audio.setoutgain(G.gain)
|
||||
|
||||
def stop_hook(self):
|
||||
if G.busy:
|
||||
audio.setoutgain(0)
|
||||
dummy = audio.stop_playing()
|
||||
G.busy = 0
|
||||
|
||||
|
||||
# List windows -- to display list of files and subdirectories
|
||||
|
||||
def openlistwindow(dirname):
|
||||
list = posix.listdir(dirname)
|
||||
list.sort()
|
||||
i = 0
|
||||
while i < len(list):
|
||||
if list[i] == '.' or list[i] == '..':
|
||||
del list[i]
|
||||
else:
|
||||
i = i+1
|
||||
for i in range(len(list)):
|
||||
name = list[i]
|
||||
if path.isdir(path.join(dirname, name)):
|
||||
list[i] = list[i] + '/'
|
||||
width = maxwidth(list)
|
||||
width = width + stdwin.textwidth(' ') # XXX X11 stdwin bug workaround
|
||||
height = len(list) * stdwin.lineheight()
|
||||
stdwin.setdefwinsize(width, min(height, 500))
|
||||
w = stdwin.open(dirname)
|
||||
stdwin.setdefwinsize(0, 0)
|
||||
w.setdocsize(width, height)
|
||||
w.drawproc = drawlistwindow
|
||||
w.mouse = mouselistwindow
|
||||
w.close = closelistwindow
|
||||
w.dirname = dirname
|
||||
w.list = list
|
||||
w.selected = -1
|
||||
return w
|
||||
|
||||
def maxwidth(list):
|
||||
width = 1
|
||||
for name in list:
|
||||
w = stdwin.textwidth(name)
|
||||
if w > width: width = w
|
||||
return width
|
||||
|
||||
def drawlistwindow(w, area):
|
||||
d = w.begindrawing()
|
||||
d.erase((0, 0), (1000, 10000))
|
||||
lh = d.lineheight()
|
||||
h, v = 0, 0
|
||||
for name in w.list:
|
||||
d.text((h, v), name)
|
||||
v = v + lh
|
||||
showselection(w, d)
|
||||
|
||||
def hideselection(w, d):
|
||||
if w.selected >= 0:
|
||||
invertselection(w, d)
|
||||
|
||||
def showselection(w, d):
|
||||
if w.selected >= 0:
|
||||
invertselection(w, d)
|
||||
|
||||
def invertselection(w, d):
|
||||
lh = d.lineheight()
|
||||
h1, v1 = p1 = 0, w.selected*lh
|
||||
h2, v2 = p2 = 1000, v1 + lh
|
||||
d.invert(p1, p2)
|
||||
|
||||
def mouselistwindow(w, type, detail):
|
||||
(h, v), clicks, button = detail[:3]
|
||||
d = w.begindrawing()
|
||||
lh = d.lineheight()
|
||||
if 0 <= v < lh*len(w.list):
|
||||
i = v / lh
|
||||
else:
|
||||
i = -1
|
||||
if w.selected <> i:
|
||||
hideselection(w, d)
|
||||
w.selected = i
|
||||
showselection(w, d)
|
||||
if type == WE_MOUSE_DOWN and clicks >= 2 and i >= 0:
|
||||
name = path.join(w.dirname, w.list[i])
|
||||
if name[-1:] == '/':
|
||||
if clicks == 2:
|
||||
G.windows.append(openlistwindow(name[:-1]))
|
||||
else:
|
||||
playfile(name)
|
||||
|
||||
def closelistwindow(w):
|
||||
remove(G.windows, w)
|
||||
|
||||
def remove(list, item):
|
||||
for i in range(len(list)):
|
||||
if list[i] == item:
|
||||
del list[i]
|
||||
break
|
||||
|
||||
|
||||
# Playing tools
|
||||
|
||||
cache = {}
|
||||
|
||||
def clearcache():
|
||||
for x in cache.keys():
|
||||
try:
|
||||
sts = posix.system('rm -f ' + cache[x])
|
||||
if sts:
|
||||
print cmd
|
||||
print 'Exit status', sts
|
||||
except:
|
||||
print cmd
|
||||
print 'Exception?!'
|
||||
del cache[x]
|
||||
|
||||
def playfile(name):
|
||||
if G.mode <> 'mac':
|
||||
tempname = name
|
||||
elif cache.has_key(name):
|
||||
tempname = cache[name]
|
||||
else:
|
||||
tempname = G.tempprefix + `rand.rand()`
|
||||
cmd = HOME_BIN_SGI + 'macsound2sgi'
|
||||
cmd = cmd + ' ' + commands.mkarg(name)
|
||||
cmd = cmd + ' >' + tempname
|
||||
if G.debug: print cmd
|
||||
sts = posix.system(cmd)
|
||||
if sts:
|
||||
print cmd
|
||||
print 'Exit status', sts
|
||||
stdwin.fleep()
|
||||
return
|
||||
cache[name] = tempname
|
||||
fp = open(tempname, 'r')
|
||||
try:
|
||||
hdr = sunaudio.gethdr(fp)
|
||||
except sunaudio.error, msg:
|
||||
hdr = ()
|
||||
if hdr:
|
||||
data_size = hdr[0]
|
||||
data = fp.read(data_size)
|
||||
# XXX this doesn't work yet, need to convert from uLAW!!!
|
||||
del fp
|
||||
else:
|
||||
del fp
|
||||
data = readfile(tempname)
|
||||
if G.debug: print len(data), 'bytes read from', tempname
|
||||
if G.busy:
|
||||
G.busy = 0
|
||||
dummy = audio.stop_playing()
|
||||
#
|
||||
# Completely reset the audio device
|
||||
audio.setrate(G.rate)
|
||||
audio.setduration(0)
|
||||
audio.setoutgain(G.gain)
|
||||
#
|
||||
if G.synchronous:
|
||||
audio.write(data)
|
||||
audio.setoutgain(0)
|
||||
else:
|
||||
try:
|
||||
audio.start_playing(data)
|
||||
G.busy = 1
|
||||
except:
|
||||
stdwin.fleep()
|
||||
del data
|
||||
|
||||
def readfile(filename):
|
||||
return readfp(open(filename, 'r'))
|
||||
|
||||
def readfp(fp):
|
||||
data = ''
|
||||
while 1:
|
||||
buf = fp.read(102400) # Reads most samples in one fell swoop
|
||||
if not buf:
|
||||
return data
|
||||
data = data + buf
|
||||
|
||||
main()
|
|
@ -0,0 +1,268 @@
|
|||
#! /ufs/guido/bin/sgi/python
|
||||
|
||||
import sys
|
||||
import audio
|
||||
import stdwin
|
||||
|
||||
import string
|
||||
import getopt
|
||||
|
||||
from stdwinevents import *
|
||||
from Buttons import *
|
||||
from Sliders import *
|
||||
#from Soundogram import Soundogram
|
||||
from VUMeter import VUMeter
|
||||
from WindowParent import WindowParent, MainLoop
|
||||
from HVSplit import HSplit, VSplit
|
||||
|
||||
class TimeOutToggleButton(ToggleButton):
|
||||
def define(self, parent):
|
||||
self = ToggleButton.define(self, parent)
|
||||
self.parent.need_timer(self)
|
||||
self.timer_hook = 0
|
||||
return self
|
||||
def timer(self):
|
||||
if self.timer_hook:
|
||||
self.timer_hook(self)
|
||||
|
||||
K = 1024
|
||||
BUFSIZE = 30*8*K
|
||||
Rates = [0, 32*K, 16*K, 8*K]
|
||||
Magics = ['', '0032', '0016', '0008']
|
||||
|
||||
class Struct: pass
|
||||
G = Struct()
|
||||
|
||||
def main():
|
||||
#
|
||||
# Turn off scroll bars
|
||||
#
|
||||
stdwin.setdefscrollbars(0, 0)
|
||||
#
|
||||
# Set default state
|
||||
#
|
||||
G.gain = 60
|
||||
G.rate = 3
|
||||
G.nomuting = 0
|
||||
G.savefile = '@rec'
|
||||
#
|
||||
# Set default values
|
||||
#
|
||||
G.data = ''
|
||||
G.playing = 0
|
||||
G.recording = 0
|
||||
G.sogram = 0
|
||||
#
|
||||
# Parse options
|
||||
#
|
||||
optlist, args = getopt.getopt(sys.argv[1:], 'mdg:r:')
|
||||
#
|
||||
for optname, optarg in optlist:
|
||||
if 0: # (So all cases start with elif)
|
||||
pass
|
||||
elif optname == '-d':
|
||||
G.debug = 1
|
||||
elif optname == '-g':
|
||||
G.gain = string.atoi(optarg)
|
||||
if not (0 < G.gain < 256):
|
||||
raise optarg.error, '-g gain out of range'
|
||||
elif optname == '-m':
|
||||
G.nomuting = (not G.nomuting)
|
||||
elif optname == '-r':
|
||||
G.rate = string.atoi(optarg)
|
||||
if not (1 <= G.rate <= 3):
|
||||
raise optarg.error, '-r rate out of range'
|
||||
#
|
||||
if args:
|
||||
G.savefile = args[0]
|
||||
#
|
||||
# Initialize the sound package
|
||||
#
|
||||
audio.setoutgain(G.nomuting * G.gain) # Silence the speaker
|
||||
audio.setrate(G.rate)
|
||||
#
|
||||
# Create the WindowParent and VSplit
|
||||
#
|
||||
G.window = WindowParent().create('Recorder', (0, 0))
|
||||
w = G.vsplit = VSplit().create(G.window)
|
||||
#
|
||||
# VU-meter
|
||||
#
|
||||
G.vubtn = VUMeter().define(w)
|
||||
#
|
||||
# Radiobuttons for rates
|
||||
#
|
||||
r1btn = RadioButton().definetext(w, '32 K/sec')
|
||||
r1btn.on_hook = rate_hook
|
||||
r1btn.rate = 1
|
||||
#
|
||||
r2btn = RadioButton().definetext(w, '16 K/sec')
|
||||
r2btn.on_hook = rate_hook
|
||||
r2btn.rate = 2
|
||||
#
|
||||
r3btn = RadioButton().definetext(w, '8 K/sec')
|
||||
r3btn.on_hook = rate_hook
|
||||
r3btn.rate = 3
|
||||
#
|
||||
radios = [r1btn, r2btn, r3btn]
|
||||
r1btn.group = r2btn.group = r3btn.group = radios
|
||||
for r in radios:
|
||||
if r.rate == G.rate: r.select(1)
|
||||
#
|
||||
# Other controls
|
||||
#
|
||||
G.recbtn = TimeOutToggleButton().definetext(w, 'Record')
|
||||
G.recbtn.on_hook = record_on_hook
|
||||
G.recbtn.timer_hook = record_timer_hook
|
||||
G.recbtn.off_hook = record_off_hook
|
||||
#
|
||||
G.mutebtn = CheckButton().definetext(w, 'Mute')
|
||||
G.mutebtn.select(not G.nomuting)
|
||||
G.mutebtn.hook = mute_hook
|
||||
#
|
||||
G.playbtn = TimeOutToggleButton().definetext(w, 'Playback')
|
||||
G.playbtn.on_hook = play_on_hook
|
||||
G.playbtn.timer_hook = play_timer_hook
|
||||
G.playbtn.off_hook = play_off_hook
|
||||
#
|
||||
G.gainbtn = ComplexSlider().define(w)
|
||||
G.gainbtn.settexts(' Volume: ', ' ')
|
||||
G.gainbtn.setminvalmax(0, G.gain, 255)
|
||||
G.gainbtn.sethook(gain_hook)
|
||||
#
|
||||
G.sizebtn = Label().definetext(w, `len(G.data)` + ' bytes')
|
||||
#
|
||||
#G.showbtn = PushButton().definetext(w, 'Sound-o-gram...')
|
||||
#G.showbtn.hook = show_hook
|
||||
#
|
||||
G.savebtn = PushButton().definetext(w, 'Save...')
|
||||
G.savebtn.hook = save_hook
|
||||
#
|
||||
G.quitbtn = PushButton().definetext(w, 'Quit')
|
||||
G.quitbtn.hook = quit_hook
|
||||
G.playbtn.enable(0)
|
||||
G.savebtn.enable(0)
|
||||
#G.showbtn.enable(0)
|
||||
start_vu()
|
||||
G.window.realize()
|
||||
#
|
||||
# Event loop
|
||||
#
|
||||
MainLoop()
|
||||
|
||||
# XXX Disabled...
|
||||
def show_hook(self):
|
||||
savetext = self.text
|
||||
self.settext('Be patient...')
|
||||
close_sogram()
|
||||
stdwin.setdefwinsize(400, 300)
|
||||
win = stdwin.open('Sound-o-gram')
|
||||
G.sogram = Soundogram().define(win, G.data)
|
||||
win.buttons = [G.sogram]
|
||||
self.settext(savetext)
|
||||
|
||||
def close_sogram():
|
||||
if G.sogram:
|
||||
# Break circular references
|
||||
G.sogram.win.buttons[:] = []
|
||||
del G.sogram.win
|
||||
G.sogram = 0
|
||||
|
||||
def mute_hook(self):
|
||||
G.nomuting = (not self.selected)
|
||||
audio.setoutgain(G.nomuting * G.gain)
|
||||
|
||||
def rate_hook(self):
|
||||
G.rate = self.rate
|
||||
audio.setrate(G.rate)
|
||||
|
||||
def record_on_hook(self):
|
||||
stop_vu()
|
||||
close_sogram()
|
||||
audio.setrate(G.rate)
|
||||
audio.setoutgain(G.nomuting * G.gain)
|
||||
audio.start_recording(BUFSIZE)
|
||||
G.recording = 1
|
||||
G.playbtn.enable(0)
|
||||
G.window.settimer(10 * BUFSIZE / Rates[G.rate])
|
||||
|
||||
def record_timer_hook(self):
|
||||
if G.recording:
|
||||
if audio.poll_recording():
|
||||
self.hilite(0)
|
||||
record_off_hook(self)
|
||||
else:
|
||||
self.parent.settimer(5)
|
||||
|
||||
def record_off_hook(self):
|
||||
if not G.recording:
|
||||
return
|
||||
G.data = audio.stop_recording()
|
||||
G.recording = 0
|
||||
G.sizebtn.settext(`len(G.data)` + ' bytes')
|
||||
audio.setoutgain(G.nomuting * G.gain)
|
||||
G.playbtn.enable((len(G.data) > 0))
|
||||
G.savebtn.enable((len(G.data) > 0))
|
||||
#G.showbtn.enable((len(G.data) > 0))
|
||||
G.window.settimer(0)
|
||||
start_vu()
|
||||
|
||||
def play_on_hook(self):
|
||||
stop_vu()
|
||||
audio.setrate(G.rate)
|
||||
audio.setoutgain(G.gain)
|
||||
audio.start_playing(G.data)
|
||||
G.playing = 1
|
||||
G.recbtn.enable(0)
|
||||
G.window.settimer(max(10 * len(G.data) / Rates[G.rate], 1))
|
||||
|
||||
def play_timer_hook(self):
|
||||
if G.playing:
|
||||
if audio.poll_playing():
|
||||
self.hilite(0)
|
||||
play_off_hook(self)
|
||||
else:
|
||||
self.parent.settimer(5)
|
||||
|
||||
def play_off_hook(self):
|
||||
if not G.playing:
|
||||
return
|
||||
x = audio.stop_playing()
|
||||
G.playing = 0
|
||||
audio.setoutgain(G.nomuting * G.gain)
|
||||
G.recbtn.enable(1)
|
||||
G.window.settimer(0)
|
||||
start_vu()
|
||||
|
||||
def gain_hook(self):
|
||||
G.gain = self.val
|
||||
if G.playing or G.nomuting: audio.setoutgain(G.gain)
|
||||
|
||||
def save_hook(self):
|
||||
if not G.data:
|
||||
stdwin.fleep()
|
||||
else:
|
||||
prompt = 'Store sampled data on file: '
|
||||
try:
|
||||
G.savefile = stdwin.askfile(prompt, G.savefile, 1)
|
||||
except KeyboardInterrupt:
|
||||
return
|
||||
try:
|
||||
fp = open(G.savefile, 'w')
|
||||
fp.write(Magics[G.rate] + G.data)
|
||||
except:
|
||||
stdwin.message('Cannot create ' + file)
|
||||
|
||||
def stop_vu():
|
||||
G.vubtn.stop()
|
||||
|
||||
def start_vu():
|
||||
G.vubtn.start()
|
||||
|
||||
def quit_hook(self):
|
||||
G.window.delayed_destroy()
|
||||
|
||||
try:
|
||||
main()
|
||||
finally:
|
||||
audio.setoutgain(0)
|
|
@ -0,0 +1,35 @@
|
|||
#! /usr/local/python
|
||||
|
||||
import audio
|
||||
import stdwin
|
||||
|
||||
from VUMeter import VUMeter
|
||||
from WindowParent import WindowParent
|
||||
import MainLoop
|
||||
|
||||
NBUFS=20
|
||||
BUFSIZE = NBUFS*48
|
||||
SCALE=128
|
||||
|
||||
class MyVUMeter(VUMeter):
|
||||
def init_reactivity(self):
|
||||
self.parent.need_mouse(self)
|
||||
def mouse_down(self, detail):
|
||||
if self.enabled:
|
||||
self.stop()
|
||||
else:
|
||||
self.start()
|
||||
def mouse_move(self, detail): pass
|
||||
def mouse_up(self, detail): pass
|
||||
|
||||
def main():
|
||||
audio.setrate(3)
|
||||
audio.setoutgain(0)
|
||||
w = WindowParent().create('VU Meter', (200, 100))
|
||||
v = MyVUMeter().define(w)
|
||||
v.start()
|
||||
w.realize()
|
||||
while 1:
|
||||
w.dispatch(stdwin.getevent())
|
||||
|
||||
main()
|
|
@ -0,0 +1,75 @@
|
|||
Magic: 12321
|
||||
|
||||
Internal Form Definition File
|
||||
(do not change)
|
||||
|
||||
Number of forms: 1
|
||||
|
||||
=============== FORM ===============
|
||||
Name: main_form
|
||||
Width: 170.000000
|
||||
Height: 190.000000
|
||||
Number of Objects: 4
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 170.000000 190.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 140.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 1
|
||||
name: button1
|
||||
callback: button1CB
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 100.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 2
|
||||
name: button2
|
||||
callback: button2CB
|
||||
argument: 0
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 6
|
||||
box: 10.000000 10.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: EXIT
|
||||
name: exitbutton
|
||||
callback: exitbuttonCB
|
||||
argument: 0
|
||||
|
||||
==============================
|
||||
create_the_forms
|
|
@ -0,0 +1,62 @@
|
|||
#
|
||||
# Example 2 - Using fl in python with callbacks.
|
||||
#
|
||||
# The form is named 'main_form' and resides on file 'test_cb.fd'.
|
||||
# It has three objects named button1, button2 and exitbutton.
|
||||
# All buttons have callbacks with the same names as their corresponding
|
||||
# buttons but with CB appended.
|
||||
#
|
||||
import fl # The forms library
|
||||
import FL # Symbolic constants for the above
|
||||
import flp # The module to parse .fd files
|
||||
import sys
|
||||
|
||||
# The following struct is created to hold the instance variables
|
||||
# main_form, button1, button2 and exitbutton.
|
||||
|
||||
class myform():
|
||||
#
|
||||
# The init function parses and creates the form, but doesn't
|
||||
# display it (yet).
|
||||
def init(self, number):
|
||||
#
|
||||
# First we parse the form
|
||||
parsetree = flp.parse_form('test_cb', 'main_form')
|
||||
#
|
||||
# Next we create it
|
||||
|
||||
flp.create_full_form(self, parsetree)
|
||||
|
||||
# And keep our number
|
||||
self.number = number
|
||||
return self
|
||||
|
||||
#
|
||||
# The show function displays the form. It doesn't do any interaction,
|
||||
# though.
|
||||
def show(self):
|
||||
self.main_form.show_form(FL.PLACE_SIZE, 1, '')
|
||||
|
||||
# The callback functions
|
||||
def button1CB(self, obj, arg):
|
||||
print 'Button 1 pressed on form', self.number
|
||||
|
||||
def button2CB(self, obj, arg):
|
||||
print 'Button 2 pressed on form', self.number
|
||||
|
||||
def exitbuttonCB(self, obj, arg):
|
||||
print 'Ok, bye bye'
|
||||
sys.exit(0)
|
||||
|
||||
#
|
||||
# The main program. Instantiate two variables of the forms class
|
||||
# and interact with them.
|
||||
|
||||
form1 = myform().init(1)
|
||||
form2 = myform().init(2)
|
||||
|
||||
form1.show()
|
||||
form2.show()
|
||||
|
||||
obj = fl.do_forms()
|
||||
print 'do_forms() returned. This should not happen. obj=', obj
|
|
@ -0,0 +1,75 @@
|
|||
Magic: 12321
|
||||
|
||||
Internal Form Definition File
|
||||
(do not change)
|
||||
|
||||
Number of forms: 1
|
||||
|
||||
=============== FORM ===============
|
||||
Name: main_form
|
||||
Width: 170.000000
|
||||
Height: 190.000000
|
||||
Number of Objects: 4
|
||||
|
||||
--------------------
|
||||
class: 1
|
||||
type: 1
|
||||
box: 0.000000 0.000000 170.000000 190.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label:
|
||||
name:
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 140.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 1
|
||||
name: button1
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 0
|
||||
box: 10.000000 100.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: Button 2
|
||||
name: button2
|
||||
callback:
|
||||
argument:
|
||||
|
||||
--------------------
|
||||
class: 11
|
||||
type: 6
|
||||
box: 10.000000 10.000000 150.000000 40.000000
|
||||
boxtype: 1
|
||||
colors: 47 47
|
||||
alignment: 4
|
||||
style: 0
|
||||
size: 11.000000
|
||||
lcol: 0
|
||||
label: EXIT
|
||||
name: exitbutton
|
||||
callback:
|
||||
argument:
|
||||
|
||||
==============================
|
||||
create_the_forms
|
|
@ -0,0 +1,45 @@
|
|||
#
|
||||
# Example 1 - Using fl in python without callbacks.
|
||||
#
|
||||
# The form is named 'main_form' and resides on file 'test_nocb.fd'.
|
||||
# It has three objects named button1, button2 and exitbutton.
|
||||
#
|
||||
import fl # The forms library
|
||||
import FL # Symbolic constants for the above
|
||||
import flp # The module to parse .fd files
|
||||
import sys
|
||||
|
||||
# The following struct is created to hold the instance variables
|
||||
# main_form, button1, button2 and exitbutton.
|
||||
|
||||
class struct(): pass
|
||||
container = struct()
|
||||
|
||||
#
|
||||
# We now first parse the forms file
|
||||
|
||||
parsetree = flp.parse_form('test_nocb', 'main_form')
|
||||
|
||||
#
|
||||
# Next we create it
|
||||
|
||||
flp.create_full_form(container, parsetree)
|
||||
|
||||
#
|
||||
# And display it
|
||||
|
||||
container.main_form.show_form(FL.PLACE_MOUSE, 1, '')
|
||||
|
||||
#
|
||||
# And interact until the exit button is pressed
|
||||
while 1:
|
||||
selected_obj = fl.do_forms()
|
||||
if selected_obj == container.button1:
|
||||
print 'Button 1 selected'
|
||||
elif selected_obj == container.button2:
|
||||
print 'Button 2 selected'
|
||||
elif selected_obj == container.exitbutton:
|
||||
print 'Ok, bye bye'
|
||||
sys.exit(0)
|
||||
else:
|
||||
print 'do_forms() returned unknown object ', selected_obj
|
Loading…
Reference in New Issue