⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jukebox.py

📁 reduced python source for embedded apps
💻 PY
字号:
#! /usr/bin/env 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 audioimport sunaudioimport commandsimport getoptimport pathimport posiximport randimport stdwinfrom stdwinevents import *import stringimport sysfrom WindowParent import WindowParentfrom HVSplit import VSplitfrom Buttons import PushButtonfrom Sliders import ComplexSlider# PathnamesHOME_BIN_SGI = '/ufs/guido/bin/sgi/'	# Directory where macsound2sgi livesDEF_DB = '/ufs/dik/sounds/Mac/HCOM'	# Default directory of sounds# Global variablesclass struct: pass		# Class to define featureless structuresG = struct()			# Holds writable global variables# Main programdef 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 progressdef 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 cwdef 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 subdirectoriesdef 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 wdef maxwidth(list):	width = 1	for name in list:		w = stdwin.textwidth(name)		if w > width: width = w	return widthdef 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 toolscache = {}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 datadef 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 + bufmain()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -