audiopy revision 2858b43613ca50f21aab629140ffc84278d3b0d8
12a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw#! /usr/bin/env python 22a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3d81d534aef5fe8d6c081121dd545623e7ea2e889Barry Warsaw"""audiopy -- a program to control the Solaris audio device. 42a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 5d81d534aef5fe8d6c081121dd545623e7ea2e889Barry WarsawAuthor: Barry Warsaw 6d81d534aef5fe8d6c081121dd545623e7ea2e889Barry WarsawEmail: bwarsaw@python.org 7d81d534aef5fe8d6c081121dd545623e7ea2e889Barry WarsawVersion: %(__version__)s 8f79b7e274cfd7466115cce88c586d603a430122bBarry Warsaw 92a06084ed51d06cdea9544b5ab02586d300dec83Barry WarsawWhen no arguments are given, this pops up a graphical window which lets you 103febc2443cd3360c4da0dafae26b3530d363368aBarry Warsawchoose the audio input and output devices. 112a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 122a06084ed51d06cdea9544b5ab02586d300dec83Barry WarsawThis program can be driven via the command line, and when done so, no window 132c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsawpops up. Options have the general form: 142a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 152c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw --device[={0,1}] 162c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw -d[={0,1}] 172c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw Set the I/O device. With no value, it toggles the specified device. 182c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw With a value, 0 turns the device off and 1 turns the device on. 192a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 202c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry WarsawThe list of devices and their short options are: 212a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 222c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw (input) 232c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw microphone -- m 242c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw linein -- i 252c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw cd -- c 262c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw 272c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw (output) 282c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw headphones -- p 292c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw speaker -- s 302c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw lineout -- o 312c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw 322c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry WarsawOther options are: 332a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 343febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw --version 353febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw -v 363febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw Print the version number and exit. 373febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw 382a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw --help 392a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw -h 402a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw Print this message and exit. 412a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw""" 422a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 432a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawimport sys 442a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawimport sunaudiodev 452a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawfrom SUNAUDIODEV import * 462a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 472a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw# Milliseconds between interrupt checks 482a06084ed51d06cdea9544b5ab02586d300dec83Barry WarsawKEEPALIVE_TIMER = 500 492a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 50d81d534aef5fe8d6c081121dd545623e7ea2e889Barry Warsaw__version__ = '0.1' 513febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw 522a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 532a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 542a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawclass MainWindow: 552c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw def __init__(self, device): 569ade9ddb147288478748c751ea715a708a7ed2cfBarry Warsaw from Tkinter import * 572c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw self.__devctl = device 582c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw info = device.getinfo() 592c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # 603febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw self.__tkroot = tkroot = Tk(className='Audiopy') 612a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw tkroot.withdraw() 622a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # now create the top level window 632c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw root = self.__root = Toplevel(tkroot, class_='Audiopy') 642a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.protocol('WM_DELETE_WINDOW', self.__quit) 653febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw root.title('audiopy ' + __version__) 663febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw root.iconname('audiopy ' + __version__) 672a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) 682a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 692c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw buttons = [] 702a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # 71b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # where does input come from? 72b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw frame = Frame(root, bd=1, relief=RAISED) 73e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw frame.grid(row=0, column=0, sticky='NSEW') 74b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw label = Label(frame, text='Input From:') 75b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw label.grid(row=0, column=0, sticky=E) 76e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw self.__inputvar = IntVar() 77441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw ## 78441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw btn = Radiobutton(frame, 79441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw text='None', 80441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw variable=self.__inputvar, 81441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw value=0, 82441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw command=self.__pushtodev, 83441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw underline=0) 84441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw btn.grid(row=0, column=1, sticky=W) 85441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw root.bind('<Alt-n>', self.__none) 86441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw root.bind('<Alt-N>', self.__none) 87441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw if not info.i_avail_ports & MICROPHONE: 88441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw btn.configure(state=DISABLED) 89441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw buttons.append(btn) 90441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw ## 91e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw btn = Radiobutton(frame, 92b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw text='Microphone', 93e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw variable=self.__inputvar, 94e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw value=MICROPHONE, 95b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 96b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw underline=0) 97441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw btn.grid(row=1, column=1, sticky=W) 98b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-m>', self.__mic) 99b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-M>', self.__mic) 1002c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw if not info.i_avail_ports & MICROPHONE: 1012c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw btn.configure(state=DISABLED) 1022c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw buttons.append(btn) 1032c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw ## 104e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw btn = Radiobutton(frame, 105b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw text='Line In', 106e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw variable=self.__inputvar, 107e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw value=LINE_IN, 108b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 109b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw underline=5) 110441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw btn.grid(row=2, column=1, sticky=W) 111b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-i>', self.__linein) 112b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw root.bind('<Alt-I>', self.__linein) 1132c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw if not info.i_avail_ports & LINE_IN: 1142c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw btn.configure(state=DISABLED) 1152c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw buttons.append(btn) 116d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw ## if SUNAUDIODEV was built on an older version of Solaris, the CD 117d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw ## input device won't exist 118d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw try: 119d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw btn = Radiobutton(frame, 120d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw text='CD', 121d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw variable=self.__inputvar, 122d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw value=CD, 123d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw command=self.__pushtodev, 124d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw underline=0) 125441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw btn.grid(row=3, column=1, sticky=W) 126d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw root.bind('<Alt-c>', self.__cd) 127d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw root.bind('<Alt-C>', self.__cd) 128d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw if not info.i_avail_ports & CD: 129d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw btn.configure(state=DISABLED) 130d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw buttons.append(btn) 131d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw except NameError: 132d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw pass 133b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # 134b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # where does output go to? 135b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw frame = Frame(root, bd=1, relief=RAISED) 136e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw frame.grid(row=1, column=0, sticky='NSEW') 137b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw label = Label(frame, text='Output To:') 1382a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw label.grid(row=0, column=0, sticky=E) 1392a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__spkvar = IntVar() 140b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 1412a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw text='Speaker', 1422a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw variable=self.__spkvar, 1432a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw onvalue=SPEAKER, 144b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 1452a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 1462a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw btn.grid(row=0, column=1, sticky=W) 1472a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-s>', self.__speaker) 1482a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-S>', self.__speaker) 1492c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw if not info.o_avail_ports & SPEAKER: 1502c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw btn.configure(state=DISABLED) 1512c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw buttons.append(btn) 1522c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw ## 1532a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__headvar = IntVar() 154b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 1552a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw text='Headphones', 1562a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw variable=self.__headvar, 1572a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw onvalue=HEADPHONE, 158b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 1592a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 1602a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw btn.grid(row=1, column=1, sticky=W) 1612a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-h>', self.__headphones) 1622a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-H>', self.__headphones) 1632c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw if not info.o_avail_ports & HEADPHONE: 1642c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw btn.configure(state=DISABLED) 1652c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw buttons.append(btn) 1662c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw ## 1672a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__linevar = IntVar() 168b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw btn = Checkbutton(frame, 1692a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw variable=self.__linevar, 1702a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw onvalue=LINE_OUT, 171b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw text='Line Out', 172b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw command=self.__pushtodev, 1732a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw underline=0) 1742a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw btn.grid(row=2, column=1, sticky=W) 1752a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-l>', self.__lineout) 1762a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw root.bind('<Alt-L>', self.__lineout) 1772c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw if not info.o_avail_ports & LINE_OUT: 1782c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw btn.configure(state=DISABLED) 1792c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw buttons.append(btn) 1802c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # 1812c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # Fix up widths 1822c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw widest = 0 1832c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw for b in buttons: 1842c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw width = b['width'] 1852c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw if width > widest: 1862c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw widest = width 1872c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw for b in buttons: 1882c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw b.configure(width=widest) 1892c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # 1902c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # Add quit button 1912c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw frame = Frame(root) 1922c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw frame.grid(row=2, column=0, sticky='EW', ipady=5) 1932c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw btn = Button(frame, 1942c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw text='Quit', 1952c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw command=self.__quit, 1962c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw underline=0) 1972c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw btn.pack(expand=YES) 1982c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw root.bind('<Alt-q>', self.__quit) 1992c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw root.bind('<Alt-Q>', self.__quit) 200b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # 201b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # do we need to poll for changes? 202b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__needtopoll = 1 203b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw try: 204b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw fd = self.__devctl.fileno() 205b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__needtopoll = 0 206b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw except AttributeError: 207b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw pass 208b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw else: 209b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import fcntl 210b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import signal 211b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw import STROPTS 212b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw # set up the signal handler 213b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw signal.signal(signal.SIGPOLL, self.__update) 214b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw fcntl.ioctl(fd, STROPTS.I_SETSIG, STROPTS.S_MSG) 215b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__update() 216b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 2172a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __quit(self, event=None): 2182a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__devctl.close() 2192a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__root.quit() 2202a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2212a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __keepalive(self): 2222a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # Exercise the Python interpreter regularly so keyboard interrupts get 2232a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # through. 2242a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive) 225b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw if self.__needtopoll: 226b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__update() 227b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 228b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __update(self, num=None, frame=None): 2292a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # We have to poll because the device could have changed state and the 2302a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # underlying module does not support the SIGPOLL notification 2312a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # interface. 2322a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info = self.__devctl.getinfo() 233e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw # input 234e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw self.__inputvar.set(info.i_port) 235e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw # output 2362a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__spkvar.set(info.o_port & SPEAKER) 2372a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__headvar.set(info.o_port & HEADPHONE) 2382a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__linevar.set(info.o_port & LINE_OUT) 2392a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 240b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __pushtodev(self, event=None): 2412a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info = self.__devctl.getinfo() 2422a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw info.o_port = self.__spkvar.get() + \ 2432a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__headvar.get() + \ 2442a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__linevar.get() 245e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw info.i_port = self.__inputvar.get() 2462a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__devctl.setinfo(info) 2472a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2482a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __getset(self, var, onvalue): 249441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw if var.get() == onvalue: 2502a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw var.set(0) 2512a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 2522a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw var.set(onvalue) 253b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw self.__pushtodev() 254441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw 255441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw def __none(self, event=None): 256441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw self.__inputvar.set(0) 257441abb4c8fa5f37c9dd24dd2478c6df57860534cBarry Warsaw self.__pushtodev() 258b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 259b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __mic(self, event=None): 260e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw self.__getset(self.__inputvar, MICROPHONE) 261b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 262b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __linein(self, event=None): 263e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw self.__getset(self.__inputvar, LINE_IN) 264b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw 265b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw def __cd(self, event=None): 266e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw self.__getset(self.__inputvar, CD) 2672a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2682a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __speaker(self, event=None): 2692a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__getset(self.__spkvar, SPEAKER) 2702a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2712a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __headphones(self, event=None): 2722a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__getset(self.__headvar, HEADPHONE) 2732a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2742a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def __lineout(self, event=None): 2752a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__getset(self.__linevar, LINE_OUT) 2762a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2772a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw def start(self): 2782a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__keepalive() 2792a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw self.__tkroot.mainloop() 2802a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2812a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2822a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2832a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawdef usage(msg='', code=1): 284d81d534aef5fe8d6c081121dd545623e7ea2e889Barry Warsaw print __doc__ % globals() 2852858b43613ca50f21aab629140ffc84278d3b0d8Barry Warsaw if msg: 2862858b43613ca50f21aab629140ffc84278d3b0d8Barry Warsaw print msg 2872a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw sys.exit(code) 2882a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2892a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 2902a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawdef main(): 2912c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # 2922c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # Open up the audio control device and query for the current output 2932c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # device 2942c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw device = sunaudiodev.open('control') 2952c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw 2962a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if len(sys.argv) == 1: 2972a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw # GUI 2982c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw w = MainWindow(device) 299b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw try: 300b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw w.start() 301b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw except KeyboardInterrupt: 302b7d1d63f00603acda29741e369c327f048571aedBarry Warsaw pass 3032a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw return 3042a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3052c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # spec: LONG OPT, SHORT OPT, 0=input,1=output, MASK 306d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw options = [('--microphone', '-m', 0, MICROPHONE), 3072c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw ('--linein', '-i', 0, LINE_IN), 3082c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw ('--headphones', '-p', 1, HEADPHONE), 3092c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw ('--speaker', '-s', 1, SPEAKER), 3102c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw ('--lineout', '-o', 1, LINE_OUT), 311d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw ] 312d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw # See the comment above about `CD' 313d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw try: 314d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw options.append(('--cd', '-c', 0, CD)) 315d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw except NameError: 316d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw pass 317d55049aedea656a4509537a11853bd556ccfb013Barry Warsaw 3182c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw info = device.getinfo() 3192c8b35bdd25b0946d4ea35e74a1e20ccd4679325Barry Warsaw # first get the existing values 3202a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw for arg in sys.argv[1:]: 3212a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw if arg in ('-h', '--help'): 3222a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw usage(code=0) 323e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw # does not return 3243febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw elif arg in ('-v', '--version'): 325d81d534aef5fe8d6c081121dd545623e7ea2e889Barry Warsaw print '''\ 326d81d534aef5fe8d6c081121dd545623e7ea2e889Barry Warsawaudiopy -- a program to control the Solaris audio device. 327d81d534aef5fe8d6c081121dd545623e7ea2e889Barry WarsawAuthor: Barry Warsaw 328d81d534aef5fe8d6c081121dd545623e7ea2e889Barry WarsawEmail: bwarsaw@python.org 329d81d534aef5fe8d6c081121dd545623e7ea2e889Barry WarsawVersion: %s''' % __version__ 3303febc2443cd3360c4da0dafae26b3530d363368aBarry Warsaw sys.exit(0) 331e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw for long, short, io, mask in options: 332e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw if arg in (long, short): 333e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw # toggle the option 334e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw if io == 0: 335e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw info.i_port = info.i_port ^ mask 336e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw else: 337e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw info.o_port = info.o_port ^ mask 338e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw break 339e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw val = None 3402a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw try: 341e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw if arg[:len(long)+1] == long+'=': 342e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw val = int(arg[len(long)+1:]) 343e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw elif arg[:len(short)+1] == short+'=': 344e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw val = int(arg[len(short)+1:]) 3452a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw except ValueError: 346e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw usage(msg='Invalid option: ' + arg) 347e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw # does not return 348e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw if val == 0: 349e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw if io == 0: 350e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw info.i_port = info.i_port & ~mask 3512a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 352e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw info.o_port = info.o_port & ~mask 353e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw break 354e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw elif val == 1: 355e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw if io == 0: 356e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw info.i_port = info.i_port | mask 3572a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 358e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw info.o_port = info.o_port | mask 359e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw break 360e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw # else keep trying next option 3612a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw else: 362e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw usage(msg='Invalid option: ' + arg) 363e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw # now set the values 364e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw device.setinfo(info) 365e77ec175d2cf36b4bb5e6a6d9957bf9cd8abf42dBarry Warsaw device.close() 3662a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3672a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3682a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw 3692a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsawif __name__ == '__main__': 3702a06084ed51d06cdea9544b5ab02586d300dec83Barry Warsaw main() 371