audiopy revision b7d1d63f00603acda29741e369c327f048571aed
12a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw#! /usr/bin/env python 22a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 32a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw"""Program to control the Solaris audio device. 42a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 52a06084ed51d06cdea9544b5ab02586d300dec83Barry WarsawWhen no arguments are given, this pops up a graphical window which lets you 62a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawchoose which audio output device you want sound to go to. 72a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 82a06084ed51d06cdea9544b5ab02586d300dec83Barry WarsawThis program can be driven via the command line, and when done so, no window 92a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawpops up. Here are the options: 102a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 112a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw --headphones[={0,1}] 122a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw -p[={0,1}] 132a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw Set the headphones output device. With no value, it toggles the 142a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw headphone device. With a value, 0 turns the headphones off and 1 152a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw turns the headphones on. 162a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 172a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw --speaker[={0,1}] 182a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw -s[={0,1}] 192a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw Set the speaker output device. Value semantics are the same as 202a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw above. 212a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 222a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw --lineout[={0,1}] 232a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw -l[={0,1}] 242a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw Set the line out output device. Value semantics are the same as 252a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw above. 262a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 272a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw --help 282a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw -h 292a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw Print this message and exit. 302a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 312a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw""" 322a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 332a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawimport sys 342a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawfrom Tkinter import * 352a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawimport sunaudiodev 362a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawfrom SUNAUDIODEV import * 372a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 382a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw# Milliseconds between interrupt checks 392a06084ed51d06cdea9544b5ab02586d300dec83Barry WarsawKEEPALIVE_TIMER = 500 402a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 412a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 422a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 432a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawclass MainWindow: 442a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __init__(self): 452a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__tkroot = tkroot = Tk(className='Pynche') 462a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw tkroot.withdraw() 472a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # create the menubar 482a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw menubar = Menu(tkroot) 492a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 502a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # File menu 512a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 522a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw filemenu = Menu(menubar, tearoff=0) 532a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw filemenu.add_command(label='Quit', 542a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw command=self.__quit, 552a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw accelerator='Alt-Q', 562a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 572a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 582a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # Tie them together 592a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 602a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw menubar.add_cascade(label='File', 612a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw menu=filemenu, 622a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 632a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # now create the top level window 642a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root = self.__root = Toplevel(tkroot, class_='Audiopy', menu=menubar) 652a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.protocol('WM_DELETE_WINDOW', self.__quit) 662a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.title('Audiopy') 672a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.iconname('Audiopy') 682a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) 692a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-q>', self.__quit) 702a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-Q>', self.__quit) 712a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 722a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # Open up the audio control device and query for the current output 732a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # device 742a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__devctl = sunaudiodev.open('control') 752a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info = self.__devctl.getinfo() 762a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 77b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # where does input come from? 78b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw frame = Frame(root, bd=1, relief=RAISED) 79b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw frame.grid(row=0, column=0) 80b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw label = Label(frame, text='Input From:') 81b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw label.grid(row=0, column=0, sticky=E) 82b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__micvar = IntVar() 83b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 84b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw text='Microphone', 85b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw variable=self.__micvar, 86b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw onvalue=MICROPHONE, 87b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 88b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw underline=0) 89b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn.grid(row=0, column=1, sticky=W) 90b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-m>', self.__mic) 91b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-M>', self.__mic) 92b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__lineinvar = IntVar() 93b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 94b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw text='Line In', 95b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw variable=self.__lineinvar, 96b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw onvalue=LINE_IN, 97b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 98b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw underline=5) 99b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn.grid(row=1, column=1, sticky=W) 100b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-i>', self.__linein) 101b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-I>', self.__linein) 102b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__cdvar = IntVar() 103b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 104b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw text='CD', 105b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw variable=self.__cdvar, 106b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw onvalue=CD, 107b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 108b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw underline=0) 109b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn.grid(row=2, column=1, sticky=W) 110b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-c>', self.__cd) 111b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-C>', self.__cd) 112b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # 113b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # where does output go to? 114b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw frame = Frame(root, bd=1, relief=RAISED) 115b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw frame.grid(row=1, column=0) 116b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw label = Label(frame, text='Output To:') 1172a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw label.grid(row=0, column=0, sticky=E) 1182a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__spkvar = IntVar() 119b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 1202a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw text='Speaker', 1212a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw variable=self.__spkvar, 1222a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw onvalue=SPEAKER, 123b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 1242a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 1252a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw btn.grid(row=0, column=1, sticky=W) 1262a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-s>', self.__speaker) 1272a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-S>', self.__speaker) 1282a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__headvar = IntVar() 129b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 1302a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw text='Headphones', 1312a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw variable=self.__headvar, 1322a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw onvalue=HEADPHONE, 133b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 1342a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 1352a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw btn.grid(row=1, column=1, sticky=W) 1362a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-h>', self.__headphones) 1372a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-H>', self.__headphones) 1382a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__linevar = IntVar() 139b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 1402a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw variable=self.__linevar, 1412a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw onvalue=LINE_OUT, 142b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw text='Line Out', 143b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 1442a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 1452a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw btn.grid(row=2, column=1, sticky=W) 1462a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-l>', self.__lineout) 1472a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-L>', self.__lineout) 148b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # 149b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # do we need to poll for changes? 150b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__needtopoll = 1 151b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw try: 152b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw fd = self.__devctl.fileno() 153b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__needtopoll = 0 154b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw except AttributeError: 155b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw pass 156b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw else: 157b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import struct 158b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import fcntl 159b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import signal 160b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import FCNTL 161b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import STROPTS 162b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # set up the signal handler 163b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw signal.signal(signal.SIGPOLL, self.__update) 164b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw fcntl.ioctl(fd, STROPTS.I_SETSIG, STROPTS.S_MSG) 165b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__update() 166b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 1672a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __quit(self, event=None): 1682a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__devctl.close() 1692a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__root.quit() 1702a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 1712a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __keepalive(self): 1722a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # Exercise the Python interpreter regularly so keyboard interrupts get 1732a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # through. 1742a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) 175b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw if self.__needtopoll: 176b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__update() 177b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 178b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __update(self, num=None, frame=None): 1792a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # We have to poll because the device could have changed state and the 1802a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # underlying module does not support the SIGPOLL notification 1812a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # interface. 1822a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info = self.__devctl.getinfo() 1832a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__spkvar.set(info.o_port & SPEAKER) 1842a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__headvar.set(info.o_port & HEADPHONE) 1852a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__linevar.set(info.o_port & LINE_OUT) 186b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__micvar.set(info.i_port & MICROPHONE) 187b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__lineinvar.set(info.i_port & LINE_IN) 188b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__cdvar.set(info.i_port & CD) 1892a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 190b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __pushtodev(self, event=None): 1912a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info = self.__devctl.getinfo() 1922a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info.o_port = self.__spkvar.get() + \ 1932a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__headvar.get() + \ 1942a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__linevar.get() 195b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw info.i_port = self.__micvar.get() + \ 196b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__lineinvar.get() + \ 197b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__cdvar.get() 1982a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__devctl.setinfo(info) 1992a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2002a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __getset(self, var, onvalue): 2012a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if var.get(): 2022a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw var.set(0) 2032a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 2042a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw var.set(onvalue) 205b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__pushtodev() 206b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 207b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __mic(self, event=None): 208b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__getset(self.__micvar, MICROPHONE) 209b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 210b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __linein(self, event=None): 211b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__getset(self.__lineinvar, LINE_IN) 212b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 213b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __cd(self, event=None): 214b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__getset(self.__cdvar, CD) 2152a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2162a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __speaker(self, event=None): 2172a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__getset(self.__spkvar, SPEAKER) 2182a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2192a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __headphones(self, event=None): 2202a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__getset(self.__headvar, HEADPHONE) 2212a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2222a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __lineout(self, event=None): 2232a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__getset(self.__linevar, LINE_OUT) 2242a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2252a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def start(self): 2262a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__keepalive() 2272a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__tkroot.mainloop() 2282a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2292a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2302a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2312a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawdef usage(msg='', code=1): 2322a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw print __doc__ 2332a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw print msg 2342a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sys.exit(code) 2352a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2362a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2372a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawdef main(): 2382a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if len(sys.argv) == 1: 2392a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # GUI 2402a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw w = MainWindow() 241b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw try: 242b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw w.start() 243b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw except KeyboardInterrupt: 244b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw pass 2452a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw return 2462a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2472a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # command line 2482a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = None 2492a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = None 2502a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = None 2512a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw for arg in sys.argv[1:]: 2522a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if arg in ('-h', '--help'): 2532a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage(code=0) 2542a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # SPEAKER 2552a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg in ('-s', '--speaker'): 2562a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = -1 2572a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg[:3] == '-s=': 2582a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 2592a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = int(arg[3:]) 2602a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw except ValueError: 2612a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw pass 2622a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if sval <> 0 and sval <> 1: 2632a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage('Invalid option: ' + arg) 2642a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg[:10] == '--speaker=': 2652a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 2662a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = int(arg[10:]) 2672a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw except ValueError: 2682a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw pass 2692a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if sval <> 0 and sval <> 1: 2702a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage('Invalid option: ' + arg) 2712a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # HEADPHONES 2722a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg in ('-p', '--headphones'): 2732a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = -1 2742a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg[:3] == '-p=': 2752a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 2762a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = int(arg[3:]) 2772a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw except ValueError: 2782a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw pass 2792a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if hval <> 0 and hval <> 1: 2802a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage('Invalid option: ' + arg) 2812a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg[:13] == '--headphones=': 2822a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 2832a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = int(arg[130:]) 2842a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw except ValueError: 2852a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw pass 2862a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if hval <> 0 and hval <> 1: 2872a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage('Invalid option: ' + arg) 2882a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # LINEOUT 2892a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg in ('-l', '--lineout'): 2902a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = -1 2912a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg[:3] == '-l=': 2922a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 2932a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = int(arg[3:]) 2942a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw except ValueError: 2952a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw pass 2962a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if lval <> 0 and lval <> 1: 2972a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage('Invalid option: ' + arg) 2982a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw elif arg[:10] == '--lineout=': 2992a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 3002a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = int(arg[10:]) 3012a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw except ValueError: 3022a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw pass 3032a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if lval <> 0 and lval <> 1: 3042a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage('Invalid option: ' + arg) 3052a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3062a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage('Invalid option: ' + arg) 3072a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # now set the values 3082a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 3092a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw devctl = sunaudiodev.open('control') 3102a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info = devctl.getinfo() 3112a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if sval is not None: 3122a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if sval == -1: 3132a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if info.o_port & SPEAKER: 3142a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = 0 3152a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3162a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = SPEAKER 3172a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3182a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = sval * SPEAKER 3192a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3202a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sval = info.o_port & SPEAKER 3212a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if hval is not None: 3222a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if hval == -1: 3232a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if info.o_port & HEADPHONE: 3242a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = 0 3252a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3262a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = HEADPHONE 3272a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3282a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = hval * HEADPHONE 3292a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3302a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw hval = info.o_port & HEADPHONE 3312a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if lval is not None: 3322a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if lval == -1: 3332a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if info.o_port & LINE_OUT: 3342a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = 0 3352a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3362a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = LINE_OUT 3372a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3382a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = lval * LINE_OUT 3392a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 3402a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw lval = info.o_port & LINE_OUT 3412a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info.o_port = sval + hval + lval 3422a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw devctl.setinfo(info) 3432a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw finally: 3442a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw devctl.close() 3452a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3462a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3472a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3482a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawif __name__ == '__main__': 3492a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw main() 350