]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Initial revision
authorGuido van Rossum <guido@python.org>
Fri, 15 May 1992 15:39:56 +0000 (15:39 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 15 May 1992 15:39:56 +0000 (15:39 +0000)
Demo/stdwin/jukebox.py [new file with mode: 0755]

diff --git a/Demo/stdwin/jukebox.py b/Demo/stdwin/jukebox.py
new file mode 100755 (executable)
index 0000000..fba5d71
--- /dev/null
@@ -0,0 +1,314 @@
+#! /ufs/guido/bin/sgi/python
+
+# XXX This file is being hacked -- some functionality has been taken out!
+
+# 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 commands
+import getopt
+import os
+import rand
+import stdwin
+from stdwinevents import *
+import string
+import sys
+import tempfile
+
+from WindowParent import WindowParent
+from HVSplit import VSplit
+from Buttons import PushButton
+from Sliders import ComplexSlider
+
+# Pathnames
+
+DEF_DB = '/usr/local/sounds/aiff'      # Default directory of sounds
+SOX = '/usr/local/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'
+               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 = 1
+               elif optname == '-r':
+                       G.rate = int(eval(optarg))
+               elif optname == '-s':
+                       G.synchronous = 1
+               elif optname == '-t':
+                       G.mode = optarg
+       #
+       if not args:
+               args = [DEF_DB]
+       #
+       G.cw = opencontrolwindow()
+       for dirname in args:
+               G.windows.append(openlistwindow(dirname))
+       #
+       #
+       try:
+               maineventloop()
+       finally:
+               clearcache()
+               killchild()
+
+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
+                       if type == WE_TIMER:
+                               checkchild()
+                               if G.busy:
+                                       G.cw.win.settimer(1)
+                       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: 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.wait(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))
+       v = VSplit().create(cw)
+       #
+       stop = PushButton().definetext(v, 'Stop')
+       stop.hook = stop_hook
+       stop.enable(0)
+       G.stop = stop
+       #
+       cw.realize()
+       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] == '.' or list[i] == '..':
+                       del list[i]
+               else:
+                       i = i+1
+       for i in range(len(list)):
+               name = list[i]
+               if os.path.isdir(os.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))
+       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 in list:
+               w = stdwin.textwidth(name)
+               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 in w.list:
+               d.text((h, v), name)
+               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 = os.path.join(w.dirname, w.list[i])
+               if name[-1:] == '/':
+                       if clicks == 2:
+                               G.windows.append(openlistwindow(name[:-1]))
+               else:
+                       playfile(name)
+               setcursors('cross')
+
+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
+
+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():
+               try:
+                       sts = os.system('rm -f ' + cache[x])
+                       if sts:
+                               print cmd
+                               print 'Exit status', sts
+               except:
+                       print cmd
+                       print 'Exception?!'
+               del cache[x]
+
+def playfile(name):
+       killchild()
+       if G.mode in ('', 'au', 'aiff'):
+               tempname = name
+       elif cache.has_key(name):
+               tempname = cache[name]
+       else:
+               tempname = G.tempprefix + `rand.rand()` + '.aiff'
+               cmd = SOX
+               if G.mode <> '' and G.mode <> 'sox':
+                       cmd = cmd + ' -t ' + G.mode
+               cmd = cmd + ' ' + commands.mkarg(name)
+               cmd = cmd + ' -t aiff'
+               if G.rate:
+                       cmd = cmd + ' -r ' + `G.rate`
+               cmd = cmd + ' ' + tempname
+               if G.debug: print cmd
+               sts = os.system(cmd)
+               if sts:
+                       print cmd
+                       print 'Exit status', sts
+                       stdwin.fleep()
+                       return
+               cache[name] = tempname
+       pid = os.fork()
+       if pid == 0:
+               # Child
+               os.exec(SFPLAY, [SFPLAY, '-r', tempname])
+               # NOTREACHED
+       # Parent
+       if G.synchronous:
+               sts = os.wait(pid, 0)
+       else:
+               G.busy = pid
+               G.stop.enable(1)
+               G.cw.win.settimer(1)
+
+main()