diff options
Diffstat (limited to 'Demo/stdwin/jukebox.py')
-rwxr-xr-x | Demo/stdwin/jukebox.py | 413 |
1 files changed, 0 insertions, 413 deletions
diff --git a/Demo/stdwin/jukebox.py b/Demo/stdwin/jukebox.py deleted file mode 100755 index e3c9db8..0000000 --- a/Demo/stdwin/jukebox.py +++ /dev/null @@ -1,413 +0,0 @@ -#! /usr/bin/env python - -# XXX This only works on SGIs running IRIX 4.0 or higher - -# 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 for events -# while the sample is playing, so you can cancel playing or start a -# new sample right away. Synchronous playing is available through the -# -s option. -# -# The control window displays a "stop button" that cancel the current -# play request. -# -# Most sound file formats recognized by SOX or SFPLAY are recognized. -# Since conversion is costly, converted files are cached in -# /usr/tmp/@j* until the user quits or changes the sampling rate via -# the Rate menu. - -import commands -import getopt -import os -from stat import * -import rand -import stdwin -from stdwinevents import * -import sys -import tempfile -import sndhdr - -from WindowParent import WindowParent -from Buttons import PushButton - -# Pathnames - -DEF_DB = '/usr/local/sounds' # Default directory of sounds -SOX = '/usr/local/bin/sox' # Sound format conversion program -SFPLAY = '/usr/sbin/sfplay' # Sound playing program - - -# 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.busy = 0 # Set while asynchronous playing is active - G.windows = [] # List of open windows, except control - G.mode = '' # File type (default any that sfplay knows) - G.rate = 0 # Sampling rate (default " " " ") - G.tempprefix = tempfile.mktemp() - # - try: - optlist, args = getopt.getopt(sys.argv[1:], 'dr:st:') - except getopt.error, msg: - sys.stdout = sys.stderr - print msg - print 'usage: jukebox [-d] [-s] [-t type] [-r rate]' - print ' -d debugging (-dd event debugging)' - print ' -s synchronous playing' - print ' -t type file type' - print ' -r rate sampling rate' - sys.exit(2) - # - for optname, optarg in optlist: - if optname == '-d': - G.debug = G.debug + 1 - elif optname == '-r': - G.rate = int(eval(optarg)) - elif optname == '-s': - G.synchronous = 1 - elif optname == '-t': - G.mode = optarg - # - if G.debug: - for name in G.__dict__.keys(): - print 'G.' + name, '=', `G.__dict__[name]` - # - if not args: - args = [DEF_DB] - # - G.cw = opencontrolwindow() - for dirname in args: - G.windows.append(openlistwindow(dirname)) - # - # - try: - maineventloop() - finally: - clearcache() - killchild() - -# Entries in Rate menu: -rates = ['default', '7350', \ - '8000', '11025', '16000', '22050', '32000', '41000', '48000'] - -def maineventloop(): - mouse_events = WE_MOUSE_DOWN, WE_MOUSE_MOVE, WE_MOUSE_UP - while G.windows: - try: - type, w, detail = event = stdwin.getevent() - except KeyboardInterrupt: - killchild() - continue - if w == G.cw.win: - if type == WE_CLOSE: - return - if type == WE_TIMER: - checkchild() - if G.busy: - G.cw.win.settimer(1) - elif type == WE_MENU: - menu, item = detail - if menu is G.ratemenu: - clearcache() - if item == 0: - G.rate = 0 - else: - G.rate = eval(rates[item]) - for i in range(len(rates)): - menu.check(i, (i == item)) - else: - 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 > 1: print type, w, detail - -def checkchild(): - if G.busy: - waitchild(1) - -def killchild(): - if G.busy: - os.kill(G.busy, 9) - waitchild(0) - -def waitchild(options): - pid, sts = os.waitpid(G.busy, options) - if pid == G.busy: - G.busy = 0 - G.stop.enable(0) - - -# Control window -- to set gain and cancel play operations in progress - -def opencontrolwindow(): - stdwin.setdefscrollbars(0, 0) - cw = WindowParent().create('Jukebox', (0, 0)) - # - stop = PushButton().definetext(cw, ' Stop ') - stop.hook = stop_hook - stop.enable(0) - G.stop = stop - # - cw.realize() - # - G.ratemenu = cw.win.menucreate('Rate') - for r in rates: - G.ratemenu.additem(r) - if G.rate == 0: - G.ratemenu.check(0, 1) - else: - for i in len(range(rates)): - if rates[i] == `G.rate`: - G.ratemenu.check(i, 1) - # - return cw - -def stop_hook(self): - killchild() - - -# List windows -- to display list of files and subdirectories - -def openlistwindow(dirname): - list = os.listdir(dirname) - list.sort() - i = 0 - while i < len(list): - if list[i][0] == '.': - del list[i] - else: - i = i+1 - for i in range(len(list)): - fullname = os.path.join(dirname, list[i]) - if os.path.isdir(fullname): - info = '/' - else: - try: - size = os.stat(fullname)[ST_SIZE] - info = `(size + 1023)/1024` + 'k' - except IOError: - info = '???' - info = '(' + info + ')' - list[i] = list[i], info - width = maxwidth(list) - # width = width + stdwin.textwidth(' ') # XXX X11 stdwin bug workaround - height = len(list) * stdwin.lineheight() - stdwin.setdefwinsize(width, min(height, 500)) - stdwin.setdefscrollbars(0, 1) - 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, info in list: - w = stdwin.textwidth(name + ' ' + info) - if w > width: width = w - return width - -def drawlistwindow(w, area): -## (left, top), (right, bottom) = area - d = w.begindrawing() - d.erase((0, 0), (1000, 10000)) - lh = d.lineheight() - h, v = 0, 0 - for name, info in w.list: - if info == '/': - text = name + '/' - else: - text = name + ' ' + info - d.text((h, v), text) - v = v + lh - showselection(w, d) - d.close() - -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) - d.close() - if type == WE_MOUSE_DOWN and clicks >= 2 and i >= 0: - setcursors('watch') - name, info = w.list[i] - fullname = os.path.join(w.dirname, name) - if info == '/': - if clicks == 2: - G.windows.append(openlistwindow(fullname)) - else: - playfile(fullname) - setcursors('cross') - -def closelistwindow(w): - G.windows.remove(w) - -def setcursors(cursor): - for w in G.windows: - w.setwincursor(cursor) - G.cw.win.setwincursor(cursor) - - -# Playing tools - -cache = {} - -def clearcache(): - for x in cache.keys(): - cmd = 'rm -f ' + cache[x] - if G.debug: print cmd - sts = os.system(cmd) - if sts: - print cmd - print 'Exit status', sts - del cache[x] - -validrates = (8000, 11025, 16000, 22050, 32000, 44100, 48000) - -def playfile(filename): - killchild() - try: - tuple = sndhdr.what(filename) - except IOError, msg: - print 'Can\'t open', filename, msg - stdwin.fleep() - return - raw = 0 - if tuple: - mode, rate = tuple[:2] - if rate == 0: - rate = G.rate - if rate == 0: - rate = 8000 - else: - mode = G.mode - rate = G.rate - if G.debug: print 'mode =', mode, 'rate =', rate - if mode in ('au', 'aiff', 'wav', 'aifc', 'ul', 'ub', 'sb') and \ - rate in validrates: - tempname = filename - if mode in ('ul', 'ub', 'sb'): - raw = 1 - elif cache.has_key(filename): - tempname = cache[filename] - else: - tempname = G.tempprefix + `rand.rand()` + '.aiff' - cmd = SOX - if G.debug: - cmd = cmd + ' -V' - if mode <> '': - cmd = cmd + ' -t ' + mode - cmd = cmd + ' ' + commands.mkarg(filename) - cmd = cmd + ' -t aiff' - if rate not in validrates: - rate = 32000 - if rate: - cmd = cmd + ' -r ' + `rate` - cmd = cmd + ' ' + tempname - if G.debug: print cmd - sts = os.system(cmd) - if sts: - print cmd - print 'Exit status', sts - stdwin.fleep() - try: - os.unlink(tempname) - except: - pass - return - cache[filename] = tempname - if raw: - pid = sfplayraw(tempname, tuple) - else: - pid = sfplay(tempname, []) - if G.synchronous: - sts = os.wait(pid, 0) - else: - G.busy = pid - G.stop.enable(1) - G.cw.win.settimer(1) - -def sfplayraw(filename, tuple): - args = ['-i'] - type, rate, channels, frames, bits = tuple - if type == 'ul': - args.append('mulaw') - elif type == 'ub': - args = args + ['integer', '8', 'unsigned'] - elif type == 'sb': - args = args + ['integer', '8', '2scomp'] - else: - print 'sfplayraw: warning: unknown type in', tuple - if channels > 1: - args = args + ['channels', `channels`] - if not rate: - rate = G.rate - if rate: - args = args + ['rate', `rate`] - args.append('end') - return sfplay(filename, args) - -def sfplay(filename, args): - if G.debug: - args = ['-p'] + args - args = [SFPLAY, '-r'] + args + [filename] - if G.debug: print 'sfplay:', args - pid = os.fork() - if pid == 0: - # Child - os.execv(SFPLAY, args) - # NOTREACHED - else: - # Parent - return pid - -main() |