mirror of
https://github.com/python/cpython
synced 2024-09-04 15:56:13 +00:00
Merged revisions 56492-56752 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/p3yk ........ r56497 | kurt.kaiser | 2007-07-22 14:55:16 -0700 (Sun, 22 Jul 2007) | 4 lines In the case of syntax errors, in py3k format_exception_only() was including line number and position in the final line of the exception notification, duplicating info in previous lines. ........ r56501 | kurt.kaiser | 2007-07-22 19:35:50 -0700 (Sun, 22 Jul 2007) | 2 lines Hum, needed a newline in the last change. ........ r56536 | kurt.kaiser | 2007-07-24 19:06:48 -0700 (Tue, 24 Jul 2007) | 5 lines Not all instantiations of SyntaxError set the args attribute. e.g. symtable.c Modify format_exception_only() to get SyntaxError attributes directly instead of unpacking 'args'. ........ r56537 | kurt.kaiser | 2007-07-24 19:13:03 -0700 (Tue, 24 Jul 2007) | 3 lines Update doctest strings: traceback.py no longer prints redundant location information in the last line of the exception display. ........ r56627 | kurt.kaiser | 2007-07-29 21:06:57 -0700 (Sun, 29 Jul 2007) | 2 lines Interactive interpreter emulator (code.py) failing to print exceptions. ........ r56628 | kurt.kaiser | 2007-07-29 21:41:02 -0700 (Sun, 29 Jul 2007) | 2 lines Eliminate extra lines before and after tracebacks. ........ r56638 | kurt.kaiser | 2007-07-31 19:36:45 -0700 (Tue, 31 Jul 2007) | 3 lines Refactor syntax error display in shell and edit windows; move colorize_syntax_error() to EditorWindow; update to py3k. ........ r56685 | neal.norwitz | 2007-08-02 22:20:23 -0700 (Thu, 02 Aug 2007) | 10 lines Remove several h/w and o/s specific modules that are undocumented, obsolete, and/or not widely used: linuxaudiodev.c, sunaudiodev.c Lib/plat-sunos5/SUNAUDIODEV.py Lib/audiodev.py Tools/audiopy/audiopy Move Lib/toaiff.py to Demo. See PEP 3108 for most of the details. ........ r56686 | neal.norwitz | 2007-08-02 22:21:48 -0700 (Thu, 02 Aug 2007) | 4 lines Missed one module that should have been removed since it relied on audiodev which was removed. ........ r56748 | neal.norwitz | 2007-08-04 19:19:04 -0700 (Sat, 04 Aug 2007) | 1 line Make from X import * outside module scope an error. ........ r56750 | neal.norwitz | 2007-08-04 19:35:01 -0700 (Sat, 04 Aug 2007) | 1 line Use READONLY consistently instead of RO ........
This commit is contained in:
parent
77553ab531
commit
33d2689fc9
|
@ -1,149 +0,0 @@
|
|||
# DAH should be three DOTs.
|
||||
# Space between DOTs and DAHs should be one DOT.
|
||||
# Space between two letters should be one DAH.
|
||||
# Space between two words should be DOT DAH DAH.
|
||||
|
||||
import sys, math, audiodev
|
||||
|
||||
DOT = 30
|
||||
DAH = 3 * DOT
|
||||
OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
|
||||
|
||||
morsetab = {
|
||||
'A': '.-', 'a': '.-',
|
||||
'B': '-...', 'b': '-...',
|
||||
'C': '-.-.', 'c': '-.-.',
|
||||
'D': '-..', 'd': '-..',
|
||||
'E': '.', 'e': '.',
|
||||
'F': '..-.', 'f': '..-.',
|
||||
'G': '--.', 'g': '--.',
|
||||
'H': '....', 'h': '....',
|
||||
'I': '..', 'i': '..',
|
||||
'J': '.---', 'j': '.---',
|
||||
'K': '-.-', 'k': '-.-',
|
||||
'L': '.-..', 'l': '.-..',
|
||||
'M': '--', 'm': '--',
|
||||
'N': '-.', 'n': '-.',
|
||||
'O': '---', 'o': '---',
|
||||
'P': '.--.', 'p': '.--.',
|
||||
'Q': '--.-', 'q': '--.-',
|
||||
'R': '.-.', 'r': '.-.',
|
||||
'S': '...', 's': '...',
|
||||
'T': '-', 't': '-',
|
||||
'U': '..-', 'u': '..-',
|
||||
'V': '...-', 'v': '...-',
|
||||
'W': '.--', 'w': '.--',
|
||||
'X': '-..-', 'x': '-..-',
|
||||
'Y': '-.--', 'y': '-.--',
|
||||
'Z': '--..', 'z': '--..',
|
||||
'0': '-----',
|
||||
'1': '.----',
|
||||
'2': '..---',
|
||||
'3': '...--',
|
||||
'4': '....-',
|
||||
'5': '.....',
|
||||
'6': '-....',
|
||||
'7': '--...',
|
||||
'8': '---..',
|
||||
'9': '----.',
|
||||
',': '--..--',
|
||||
'.': '.-.-.-',
|
||||
'?': '..--..',
|
||||
';': '-.-.-.',
|
||||
':': '---...',
|
||||
"'": '.----.',
|
||||
'-': '-....-',
|
||||
'/': '-..-.',
|
||||
'(': '-.--.-',
|
||||
')': '-.--.-',
|
||||
'_': '..--.-',
|
||||
' ': ' '
|
||||
}
|
||||
|
||||
# If we play at 44.1 kHz (which we do), then if we produce one sine
|
||||
# wave in 100 samples, we get a tone of 441 Hz. If we produce two
|
||||
# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
|
||||
# appears to be a nice one for playing morse code.
|
||||
def mkwave(octave):
|
||||
global sinewave, nowave
|
||||
sinewave = ''
|
||||
for i in range(100):
|
||||
val = int(math.sin(math.pi * float(i) * octave / 50.0) * 30000)
|
||||
sinewave = sinewave + chr((val >> 8) & 255) + chr(val & 255)
|
||||
nowave = '\0' * 200
|
||||
|
||||
mkwave(OCTAVE)
|
||||
|
||||
def main():
|
||||
import getopt, string
|
||||
try:
|
||||
opts, args = getopt.getopt(sys.argv[1:], 'o:p:')
|
||||
except getopt.error:
|
||||
sys.stderr.write('Usage ' + sys.argv[0] +
|
||||
' [ -o outfile ] [ args ] ...\n')
|
||||
sys.exit(1)
|
||||
dev = None
|
||||
for o, a in opts:
|
||||
if o == '-o':
|
||||
import aifc
|
||||
dev = aifc.open(a, 'w')
|
||||
dev.setframerate(44100)
|
||||
dev.setsampwidth(2)
|
||||
dev.setnchannels(1)
|
||||
if o == '-p':
|
||||
mkwave(string.atoi(a))
|
||||
if not dev:
|
||||
import audiodev
|
||||
dev = audiodev.AudioDev()
|
||||
dev.setoutrate(44100)
|
||||
dev.setsampwidth(2)
|
||||
dev.setnchannels(1)
|
||||
dev.close = dev.stop
|
||||
dev.writeframesraw = dev.writeframes
|
||||
if args:
|
||||
line = string.join(args)
|
||||
else:
|
||||
line = sys.stdin.readline()
|
||||
while line:
|
||||
mline = morse(line)
|
||||
play(mline, dev)
|
||||
if hasattr(dev, 'wait'):
|
||||
dev.wait()
|
||||
if not args:
|
||||
line = sys.stdin.readline()
|
||||
else:
|
||||
line = ''
|
||||
dev.close()
|
||||
|
||||
# Convert a string to morse code with \001 between the characters in
|
||||
# the string.
|
||||
def morse(line):
|
||||
res = ''
|
||||
for c in line:
|
||||
try:
|
||||
res = res + morsetab[c] + '\001'
|
||||
except KeyError:
|
||||
pass
|
||||
return res
|
||||
|
||||
# Play a line of morse code.
|
||||
def play(line, dev):
|
||||
for c in line:
|
||||
if c == '.':
|
||||
sine(dev, DOT)
|
||||
elif c == '-':
|
||||
sine(dev, DAH)
|
||||
else: # space
|
||||
pause(dev, DAH + DOT)
|
||||
pause(dev, DOT)
|
||||
|
||||
def sine(dev, length):
|
||||
for i in range(length):
|
||||
dev.writeframesraw(sinewave)
|
||||
|
||||
def pause(dev, length):
|
||||
for i in range(length):
|
||||
dev.writeframesraw(nowave)
|
||||
|
||||
if __name__ == '__main__' or sys.argv[0] == __name__:
|
||||
main()
|
|
@ -199,7 +199,6 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
|
|||
lib/libcrypto.tex \
|
||||
lib/libhashlib.tex \
|
||||
lib/libhmac.tex \
|
||||
lib/libsun.tex \
|
||||
lib/libxdrlib.tex \
|
||||
lib/libimghdr.tex \
|
||||
lib/libformatter.tex \
|
||||
|
@ -259,7 +258,6 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
|
|||
lib/libsymbol.tex \
|
||||
lib/libbinhex.tex \
|
||||
lib/libuu.tex \
|
||||
lib/libsunaudio.tex \
|
||||
lib/libfileinput.tex \
|
||||
lib/libimaplib.tex \
|
||||
lib/libpoplib.tex \
|
||||
|
|
|
@ -416,10 +416,6 @@ and how to embed it in other applications.
|
|||
% OTHER PLATFORM-SPECIFIC STUFF
|
||||
% =============
|
||||
|
||||
\input{libsun} % SUNOS ONLY
|
||||
\input{libsunaudio}
|
||||
% XXX(nnorwitz): the modules below this comment should be kept.
|
||||
|
||||
\input{windows} % MS Windows ONLY
|
||||
\input{libmsilib}
|
||||
\input{libmsvcrt}
|
||||
|
@ -430,9 +426,6 @@ and how to embed it in other applications.
|
|||
\input{libundoc}
|
||||
|
||||
%\chapter{Obsolete Modules}
|
||||
%\input{libcmpcache}
|
||||
%\input{libcmp}
|
||||
%\input{libni}
|
||||
|
||||
\chapter{Reporting Bugs}
|
||||
\input{reportingbugs}
|
||||
|
|
|
@ -7,9 +7,8 @@
|
|||
|
||||
The \module{audioop} module contains some useful operations on sound
|
||||
fragments. It operates on sound fragments consisting of signed
|
||||
integer samples 8, 16 or 32 bits wide, stored in Python strings. This
|
||||
is the same format as used by the \refmodule{al} and \refmodule{sunaudiodev}
|
||||
modules. All scalar items are integers, unless specified otherwise.
|
||||
integer samples 8, 16 or 32 bits wide, stored in Python strings.
|
||||
All scalar items are integers, unless specified otherwise.
|
||||
|
||||
% This para is mostly here to provide an excuse for the index entries...
|
||||
This module provides support for a-LAW, u-LAW and Intel/DVI ADPCM encodings.
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
\chapter{SunOS Specific Services}
|
||||
\label{sunos}
|
||||
|
||||
The modules described in this chapter provide interfaces to features
|
||||
that are unique to SunOS 5 (also known as Solaris version 2).
|
||||
|
||||
\localmoduletable
|
|
@ -1,146 +0,0 @@
|
|||
\section{\module{sunaudiodev} ---
|
||||
Access to Sun audio hardware}
|
||||
|
||||
\declaremodule{builtin}{sunaudiodev}
|
||||
\platform{SunOS}
|
||||
\modulesynopsis{Access to Sun audio hardware.}
|
||||
|
||||
|
||||
This module allows you to access the Sun audio interface. The Sun
|
||||
audio hardware is capable of recording and playing back audio data
|
||||
in u-LAW\index{u-LAW} format with a sample rate of 8K per second. A
|
||||
full description can be found in the \manpage{audio}{7I} manual page.
|
||||
|
||||
The module
|
||||
\refmodule[sunaudiodev-constants]{SUNAUDIODEV}\refstmodindex{SUNAUDIODEV}
|
||||
defines constants which may be used with this module.
|
||||
|
||||
This module defines the following variables and functions:
|
||||
|
||||
\begin{excdesc}{error}
|
||||
This exception is raised on all errors. The argument is a string
|
||||
describing what went wrong.
|
||||
\end{excdesc}
|
||||
|
||||
\begin{funcdesc}{open}{mode}
|
||||
This function opens the audio device and returns a Sun audio device
|
||||
object. This object can then be used to do I/O on. The \var{mode} parameter
|
||||
is one of \code{'r'} for record-only access, \code{'w'} for play-only
|
||||
access, \code{'rw'} for both and \code{'control'} for access to the
|
||||
control device. Since only one process is allowed to have the recorder
|
||||
or player open at the same time it is a good idea to open the device
|
||||
only for the activity needed. See \manpage{audio}{7I} for details.
|
||||
|
||||
As per the manpage, this module first looks in the environment
|
||||
variable \code{AUDIODEV} for the base audio device filename. If not
|
||||
found, it falls back to \file{/dev/audio}. The control device is
|
||||
calculated by appending ``ctl'' to the base audio device.
|
||||
\end{funcdesc}
|
||||
|
||||
|
||||
\subsection{Audio Device Objects \label{audio-device-objects}}
|
||||
|
||||
The audio device objects are returned by \function{open()} define the
|
||||
following methods (except \code{control} objects which only provide
|
||||
\method{getinfo()}, \method{setinfo()}, \method{fileno()}, and
|
||||
\method{drain()}):
|
||||
|
||||
\begin{methoddesc}[audio device]{close}{}
|
||||
This method explicitly closes the device. It is useful in situations
|
||||
where deleting the object does not immediately close it since there
|
||||
are other references to it. A closed device should not be used again.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{fileno}{}
|
||||
Returns the file descriptor associated with the device. This can be
|
||||
used to set up \code{SIGPOLL} notification, as described below.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{drain}{}
|
||||
This method waits until all pending output is processed and then returns.
|
||||
Calling this method is often not necessary: destroying the object will
|
||||
automatically close the audio device and this will do an implicit drain.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{flush}{}
|
||||
This method discards all pending output. It can be used avoid the
|
||||
slow response to a user's stop request (due to buffering of up to one
|
||||
second of sound).
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{getinfo}{}
|
||||
This method retrieves status information like input and output volume,
|
||||
etc. and returns it in the form of
|
||||
an audio status object. This object has no methods but it contains a
|
||||
number of attributes describing the current device status. The names
|
||||
and meanings of the attributes are described in
|
||||
\code{<sun/audioio.h>} and in the \manpage{audio}{7I}
|
||||
manual page. Member names
|
||||
are slightly different from their C counterparts: a status object is
|
||||
only a single structure. Members of the \cdata{play} substructure have
|
||||
\samp{o_} prepended to their name and members of the \cdata{record}
|
||||
structure have \samp{i_}. So, the C member \cdata{play.sample_rate} is
|
||||
accessed as \member{o_sample_rate}, \cdata{record.gain} as \member{i_gain}
|
||||
and \cdata{monitor_gain} plainly as \member{monitor_gain}.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{ibufcount}{}
|
||||
This method returns the number of samples that are buffered on the
|
||||
recording side, i.e.\ the program will not block on a
|
||||
\function{read()} call of so many samples.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{obufcount}{}
|
||||
This method returns the number of samples buffered on the playback
|
||||
side. Unfortunately, this number cannot be used to determine a number
|
||||
of samples that can be written without blocking since the kernel
|
||||
output queue length seems to be variable.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{read}{size}
|
||||
This method reads \var{size} samples from the audio input and returns
|
||||
them as a Python string. The function blocks until enough data is available.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{setinfo}{status}
|
||||
This method sets the audio device status parameters. The \var{status}
|
||||
parameter is an device status object as returned by \function{getinfo()} and
|
||||
possibly modified by the program.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}[audio device]{write}{samples}
|
||||
Write is passed a Python string containing audio samples to be played.
|
||||
If there is enough buffer space free it will immediately return,
|
||||
otherwise it will block.
|
||||
\end{methoddesc}
|
||||
|
||||
The audio device supports asynchronous notification of various events,
|
||||
through the SIGPOLL signal. Here's an example of how you might enable
|
||||
this in Python:
|
||||
|
||||
\begin{verbatim}
|
||||
def handle_sigpoll(signum, frame):
|
||||
print 'I got a SIGPOLL update'
|
||||
|
||||
import fcntl, signal, STROPTS
|
||||
|
||||
signal.signal(signal.SIGPOLL, handle_sigpoll)
|
||||
fcntl.ioctl(audio_obj.fileno(), STROPTS.I_SETSIG, STROPTS.S_MSG)
|
||||
\end{verbatim}
|
||||
|
||||
|
||||
\section{\module{SUNAUDIODEV} ---
|
||||
Constants used with \module{sunaudiodev}}
|
||||
|
||||
\declaremodule[sunaudiodev-constants]{standard}{SUNAUDIODEV}
|
||||
\platform{SunOS}
|
||||
\modulesynopsis{Constants for use with \refmodule{sunaudiodev}.}
|
||||
|
||||
|
||||
This is a companion module to
|
||||
\refmodule{sunaudiodev}\refbimodindex{sunaudiodev} which defines
|
||||
useful symbolic constants like \constant{MIN_GAIN},
|
||||
\constant{MAX_GAIN}, \constant{SPEAKER}, etc. The names of the
|
||||
constants are the same names as used in the C include file
|
||||
\code{<sun/audioio.h>}, with the leading string \samp{AUDIO_}
|
||||
stripped.
|
|
@ -52,19 +52,8 @@ document these.
|
|||
\section{Multimedia}
|
||||
|
||||
\begin{description}
|
||||
\item[\module{audiodev}]
|
||||
--- Platform-independent API for playing audio data.
|
||||
|
||||
\item[\module{linuxaudiodev}]
|
||||
--- Play audio data on the Linux audio device. Replaced in Python 2.3
|
||||
by the \module{ossaudiodev} module.
|
||||
|
||||
\item[\module{sunaudio}]
|
||||
--- Interpret Sun audio headers (may become obsolete or a tool/demo).
|
||||
|
||||
\item[\module{toaiff}]
|
||||
--- Convert "arbitrary" sound files to AIFF files; should probably
|
||||
become a tool or demo. Requires the external program \program{sox}.
|
||||
\end{description}
|
||||
|
||||
|
||||
|
|
257
Lib/audiodev.py
257
Lib/audiodev.py
|
@ -1,257 +0,0 @@
|
|||
"""Classes for manipulating audio devices (currently only for Sun and SGI)"""
|
||||
|
||||
__all__ = ["error","AudioDev"]
|
||||
|
||||
class error(Exception):
|
||||
pass
|
||||
|
||||
class Play_Audio_sgi:
|
||||
# Private instance variables
|
||||
## if 0: access frameratelist, nchannelslist, sampwidthlist, oldparams, \
|
||||
## params, config, inited_outrate, inited_width, \
|
||||
## inited_nchannels, port, converter, classinited: private
|
||||
|
||||
classinited = 0
|
||||
frameratelist = nchannelslist = sampwidthlist = None
|
||||
|
||||
def initclass(self):
|
||||
import AL
|
||||
self.frameratelist = [
|
||||
(48000, AL.RATE_48000),
|
||||
(44100, AL.RATE_44100),
|
||||
(32000, AL.RATE_32000),
|
||||
(22050, AL.RATE_22050),
|
||||
(16000, AL.RATE_16000),
|
||||
(11025, AL.RATE_11025),
|
||||
( 8000, AL.RATE_8000),
|
||||
]
|
||||
self.nchannelslist = [
|
||||
(1, AL.MONO),
|
||||
(2, AL.STEREO),
|
||||
(4, AL.QUADRO),
|
||||
]
|
||||
self.sampwidthlist = [
|
||||
(1, AL.SAMPLE_8),
|
||||
(2, AL.SAMPLE_16),
|
||||
(3, AL.SAMPLE_24),
|
||||
]
|
||||
self.classinited = 1
|
||||
|
||||
def __init__(self):
|
||||
import al, AL
|
||||
if not self.classinited:
|
||||
self.initclass()
|
||||
self.oldparams = []
|
||||
self.params = [AL.OUTPUT_RATE, 0]
|
||||
self.config = al.newconfig()
|
||||
self.inited_outrate = 0
|
||||
self.inited_width = 0
|
||||
self.inited_nchannels = 0
|
||||
self.converter = None
|
||||
self.port = None
|
||||
return
|
||||
|
||||
def __del__(self):
|
||||
if self.port:
|
||||
self.stop()
|
||||
if self.oldparams:
|
||||
import al, AL
|
||||
al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
|
||||
self.oldparams = []
|
||||
|
||||
def wait(self):
|
||||
if not self.port:
|
||||
return
|
||||
import time
|
||||
while self.port.getfilled() > 0:
|
||||
time.sleep(0.1)
|
||||
self.stop()
|
||||
|
||||
def stop(self):
|
||||
if self.port:
|
||||
self.port.closeport()
|
||||
self.port = None
|
||||
if self.oldparams:
|
||||
import al, AL
|
||||
al.setparams(AL.DEFAULT_DEVICE, self.oldparams)
|
||||
self.oldparams = []
|
||||
|
||||
def setoutrate(self, rate):
|
||||
for (raw, cooked) in self.frameratelist:
|
||||
if rate == raw:
|
||||
self.params[1] = cooked
|
||||
self.inited_outrate = 1
|
||||
break
|
||||
else:
|
||||
raise error, 'bad output rate'
|
||||
|
||||
def setsampwidth(self, width):
|
||||
for (raw, cooked) in self.sampwidthlist:
|
||||
if width == raw:
|
||||
self.config.setwidth(cooked)
|
||||
self.inited_width = 1
|
||||
break
|
||||
else:
|
||||
if width == 0:
|
||||
import AL
|
||||
self.inited_width = 0
|
||||
self.config.setwidth(AL.SAMPLE_16)
|
||||
self.converter = self.ulaw2lin
|
||||
else:
|
||||
raise error, 'bad sample width'
|
||||
|
||||
def setnchannels(self, nchannels):
|
||||
for (raw, cooked) in self.nchannelslist:
|
||||
if nchannels == raw:
|
||||
self.config.setchannels(cooked)
|
||||
self.inited_nchannels = 1
|
||||
break
|
||||
else:
|
||||
raise error, 'bad # of channels'
|
||||
|
||||
def writeframes(self, data):
|
||||
if not (self.inited_outrate and self.inited_nchannels):
|
||||
raise error, 'params not specified'
|
||||
if not self.port:
|
||||
import al, AL
|
||||
self.port = al.openport('Python', 'w', self.config)
|
||||
self.oldparams = self.params[:]
|
||||
al.getparams(AL.DEFAULT_DEVICE, self.oldparams)
|
||||
al.setparams(AL.DEFAULT_DEVICE, self.params)
|
||||
if self.converter:
|
||||
data = self.converter(data)
|
||||
self.port.writesamps(data)
|
||||
|
||||
def getfilled(self):
|
||||
if self.port:
|
||||
return self.port.getfilled()
|
||||
else:
|
||||
return 0
|
||||
|
||||
def getfillable(self):
|
||||
if self.port:
|
||||
return self.port.getfillable()
|
||||
else:
|
||||
return self.config.getqueuesize()
|
||||
|
||||
# private methods
|
||||
## if 0: access *: private
|
||||
|
||||
def ulaw2lin(self, data):
|
||||
import audioop
|
||||
return audioop.ulaw2lin(data, 2)
|
||||
|
||||
class Play_Audio_sun:
|
||||
## if 0: access outrate, sampwidth, nchannels, inited_outrate, inited_width, \
|
||||
## inited_nchannels, converter: private
|
||||
|
||||
def __init__(self):
|
||||
self.outrate = 0
|
||||
self.sampwidth = 0
|
||||
self.nchannels = 0
|
||||
self.inited_outrate = 0
|
||||
self.inited_width = 0
|
||||
self.inited_nchannels = 0
|
||||
self.converter = None
|
||||
self.port = None
|
||||
return
|
||||
|
||||
def __del__(self):
|
||||
self.stop()
|
||||
|
||||
def setoutrate(self, rate):
|
||||
self.outrate = rate
|
||||
self.inited_outrate = 1
|
||||
|
||||
def setsampwidth(self, width):
|
||||
self.sampwidth = width
|
||||
self.inited_width = 1
|
||||
|
||||
def setnchannels(self, nchannels):
|
||||
self.nchannels = nchannels
|
||||
self.inited_nchannels = 1
|
||||
|
||||
def writeframes(self, data):
|
||||
if not (self.inited_outrate and self.inited_width and self.inited_nchannels):
|
||||
raise error, 'params not specified'
|
||||
if not self.port:
|
||||
import sunaudiodev, SUNAUDIODEV
|
||||
self.port = sunaudiodev.open('w')
|
||||
info = self.port.getinfo()
|
||||
info.o_sample_rate = self.outrate
|
||||
info.o_channels = self.nchannels
|
||||
if self.sampwidth == 0:
|
||||
info.o_precision = 8
|
||||
self.o_encoding = SUNAUDIODEV.ENCODING_ULAW
|
||||
# XXX Hack, hack -- leave defaults
|
||||
else:
|
||||
info.o_precision = 8 * self.sampwidth
|
||||
info.o_encoding = SUNAUDIODEV.ENCODING_LINEAR
|
||||
self.port.setinfo(info)
|
||||
if self.converter:
|
||||
data = self.converter(data)
|
||||
self.port.write(data)
|
||||
|
||||
def wait(self):
|
||||
if not self.port:
|
||||
return
|
||||
self.port.drain()
|
||||
self.stop()
|
||||
|
||||
def stop(self):
|
||||
if self.port:
|
||||
self.port.flush()
|
||||
self.port.close()
|
||||
self.port = None
|
||||
|
||||
def getfilled(self):
|
||||
if self.port:
|
||||
return self.port.obufcount()
|
||||
else:
|
||||
return 0
|
||||
|
||||
## # Nobody remembers what this method does, and it's broken. :-(
|
||||
## def getfillable(self):
|
||||
## return BUFFERSIZE - self.getfilled()
|
||||
|
||||
def AudioDev():
|
||||
# Dynamically try to import and use a platform specific module.
|
||||
try:
|
||||
import al
|
||||
except ImportError:
|
||||
try:
|
||||
import sunaudiodev
|
||||
return Play_Audio_sun()
|
||||
except ImportError:
|
||||
try:
|
||||
import Audio_mac
|
||||
except ImportError:
|
||||
raise error, 'no audio device'
|
||||
else:
|
||||
return Audio_mac.Play_Audio_mac()
|
||||
else:
|
||||
return Play_Audio_sgi()
|
||||
|
||||
def test(fn = None):
|
||||
import sys
|
||||
if sys.argv[1:]:
|
||||
fn = sys.argv[1]
|
||||
else:
|
||||
fn = 'f:just samples:just.aif'
|
||||
import aifc
|
||||
af = aifc.open(fn, 'r')
|
||||
print(fn, af.getparams())
|
||||
p = AudioDev()
|
||||
p.setoutrate(af.getframerate())
|
||||
p.setsampwidth(af.getsampwidth())
|
||||
p.setnchannels(af.getnchannels())
|
||||
BUFSIZ = af.getframerate()/af.getsampwidth()/af.getnchannels()
|
||||
while 1:
|
||||
data = af.readframes(BUFSIZ)
|
||||
if not data: break
|
||||
print(len(data))
|
||||
p.writeframes(data)
|
||||
p.wait()
|
||||
|
||||
if __name__ == '__main__':
|
||||
test()
|
20
Lib/code.py
20
Lib/code.py
|
@ -111,16 +111,16 @@ def showsyntaxerror(self, filename=None):
|
|||
if filename and type is SyntaxError:
|
||||
# Work hard to stuff the correct filename in the exception
|
||||
try:
|
||||
msg, (dummy_filename, lineno, offset, line) = value
|
||||
except:
|
||||
msg, (dummy_filename, lineno, offset, line) = value.args
|
||||
except ValueError:
|
||||
# Not the format we expect; leave it alone
|
||||
pass
|
||||
else:
|
||||
# Stuff in the right filename
|
||||
value = SyntaxError(msg, (filename, lineno, offset, line))
|
||||
sys.last_value = value
|
||||
list = traceback.format_exception_only(type, value)
|
||||
map(self.write, list)
|
||||
lines = traceback.format_exception_only(type, value)
|
||||
self.write(''.join(lines))
|
||||
|
||||
def showtraceback(self):
|
||||
"""Display the exception that just occurred.
|
||||
|
@ -137,13 +137,13 @@ def showtraceback(self):
|
|||
sys.last_traceback = tb
|
||||
tblist = traceback.extract_tb(tb)
|
||||
del tblist[:1]
|
||||
list = traceback.format_list(tblist)
|
||||
if list:
|
||||
list.insert(0, "Traceback (most recent call last):\n")
|
||||
list[len(list):] = traceback.format_exception_only(type, value)
|
||||
lines = traceback.format_list(tblist)
|
||||
if lines:
|
||||
lines.insert(0, "Traceback (most recent call last):\n")
|
||||
lines.extend(traceback.format_exception_only(type, value))
|
||||
finally:
|
||||
tblist = tb = None
|
||||
map(self.write, list)
|
||||
self.write(''.join(lines))
|
||||
|
||||
def write(self, data):
|
||||
"""Write a string.
|
||||
|
@ -184,7 +184,7 @@ def resetbuffer(self):
|
|||
def interact(self, banner=None):
|
||||
"""Closely emulate the interactive Python console.
|
||||
|
||||
The optional banner argument specify the banner to print
|
||||
The optional banner argument specifies the banner to print
|
||||
before the first interaction; by default it prints a banner
|
||||
similar to the one printed by the real Python interpreter,
|
||||
followed by the current class name in parentheses (so as not
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import sys
|
||||
import os
|
||||
import re
|
||||
import string
|
||||
import imp
|
||||
from itertools import count
|
||||
from Tkinter import *
|
||||
|
@ -602,6 +603,19 @@ def ResetColorizer(self):
|
|||
theme = idleConf.GetOption('main','Theme','name')
|
||||
self.text.config(idleConf.GetHighlight(theme, "normal"))
|
||||
|
||||
IDENTCHARS = string.ascii_letters + string.digits + "_"
|
||||
|
||||
def colorize_syntax_error(self, text, pos):
|
||||
text.tag_add("ERROR", pos)
|
||||
char = text.get(pos)
|
||||
if char and char in self.IDENTCHARS:
|
||||
text.tag_add("ERROR", pos + " wordstart", pos)
|
||||
if '\n' == text.get(pos): # error at line end
|
||||
text.mark_set("insert", pos)
|
||||
else:
|
||||
text.mark_set("insert", pos + "+1c")
|
||||
text.see(pos)
|
||||
|
||||
def ResetFont(self):
|
||||
"Update the text widgets' font if it is changed"
|
||||
# Called from configDialog.py
|
||||
|
@ -1004,6 +1018,8 @@ def set_tabwidth(self, newtabwidth):
|
|||
"n" * newtabwidth)
|
||||
text.configure(tabs=pixels)
|
||||
|
||||
### begin autoindent code ### (configuration was moved to beginning of class)
|
||||
|
||||
# If ispythonsource and guess are true, guess a good value for
|
||||
# indentwidth based on file content (if possible), and if
|
||||
# indentwidth != tabwidth set usetabs false.
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
import os
|
||||
import os.path
|
||||
import sys
|
||||
import string
|
||||
import getopt
|
||||
import re
|
||||
import socket
|
||||
|
@ -35,7 +34,6 @@
|
|||
from . import RemoteDebugger
|
||||
from . import macosxSupport
|
||||
|
||||
IDENTCHARS = string.ascii_letters + string.digits + "_"
|
||||
LOCALHOST = '127.0.0.1'
|
||||
|
||||
try:
|
||||
|
@ -624,47 +622,30 @@ def prepend_syspath(self, filename):
|
|||
\n""" % (filename,))
|
||||
|
||||
def showsyntaxerror(self, filename=None):
|
||||
"""Extend base class method: Add Colorizing
|
||||
"""Override Interactive Interpreter method: Use Colorizing
|
||||
|
||||
Color the offending position instead of printing it and pointing at it
|
||||
with a caret.
|
||||
|
||||
"""
|
||||
text = self.tkconsole.text
|
||||
stuff = self.unpackerror()
|
||||
if stuff:
|
||||
msg, lineno, offset, line = stuff
|
||||
if lineno == 1:
|
||||
pos = "iomark + %d chars" % (offset-1)
|
||||
else:
|
||||
pos = "iomark linestart + %d lines + %d chars" % \
|
||||
(lineno-1, offset-1)
|
||||
text.tag_add("ERROR", pos)
|
||||
text.see(pos)
|
||||
char = text.get(pos)
|
||||
if char and char in IDENTCHARS:
|
||||
text.tag_add("ERROR", pos + " wordstart", pos)
|
||||
self.tkconsole.resetoutput()
|
||||
self.write("SyntaxError: %s\n" % str(msg))
|
||||
else:
|
||||
self.tkconsole.resetoutput()
|
||||
InteractiveInterpreter.showsyntaxerror(self, filename)
|
||||
self.tkconsole.showprompt()
|
||||
|
||||
def unpackerror(self):
|
||||
tkconsole = self.tkconsole
|
||||
text = tkconsole.text
|
||||
text.tag_remove("ERROR", "1.0", "end")
|
||||
type, value, tb = sys.exc_info()
|
||||
ok = type is SyntaxError
|
||||
if ok:
|
||||
try:
|
||||
msg, (dummy_filename, lineno, offset, line) = value
|
||||
if not offset:
|
||||
offset = 0
|
||||
except:
|
||||
ok = 0
|
||||
if ok:
|
||||
return msg, lineno, offset, line
|
||||
msg = value.msg or "<no detail available>"
|
||||
lineno = value.lineno or 1
|
||||
offset = value.offset or 0
|
||||
if offset == 0:
|
||||
lineno += 1 #mark end of offending line
|
||||
if lineno == 1:
|
||||
pos = "iomark + %d chars" % (offset-1)
|
||||
else:
|
||||
return None
|
||||
pos = "iomark linestart + %d lines + %d chars" % \
|
||||
(lineno-1, offset-1)
|
||||
tkconsole.colorize_syntax_error(text, pos)
|
||||
tkconsole.resetoutput()
|
||||
self.write("SyntaxError: %s\n" % msg)
|
||||
tkconsole.showprompt()
|
||||
|
||||
def showtraceback(self):
|
||||
"Extend base class method to reset output properly"
|
||||
|
|
|
@ -23,12 +23,11 @@
|
|||
import tabnanny
|
||||
import tokenize
|
||||
import tkMessageBox
|
||||
from .EditorWindow import EditorWindow
|
||||
from . import PyShell
|
||||
|
||||
from .configHandler import idleConf
|
||||
|
||||
IDENTCHARS = string.ascii_letters + string.digits + "_"
|
||||
|
||||
indent_message = """Error: Inconsistent indentation detected!
|
||||
|
||||
1) Your indentation is outright incorrect (easy to fix), OR
|
||||
|
@ -83,7 +82,7 @@ def checksyntax(self, filename):
|
|||
self.shell = shell = self.flist.open_shell()
|
||||
saved_stream = shell.get_warning_stream()
|
||||
shell.set_warning_stream(shell.stderr)
|
||||
f = open(filename, 'r')
|
||||
f = file(filename, 'r')
|
||||
source = f.read()
|
||||
f.close()
|
||||
if '\r' in source:
|
||||
|
@ -91,40 +90,25 @@ def checksyntax(self, filename):
|
|||
source = re.sub(r"\r", "\n", source)
|
||||
if source and source[-1] != '\n':
|
||||
source = source + '\n'
|
||||
text = self.editwin.text
|
||||
editwin = self.editwin
|
||||
text = editwin.text
|
||||
text.tag_remove("ERROR", "1.0", "end")
|
||||
try:
|
||||
try:
|
||||
# If successful, return the compiled code
|
||||
return compile(source, filename, "exec")
|
||||
except (SyntaxError, OverflowError) as err:
|
||||
try:
|
||||
msg, (errorfilename, lineno, offset, line) = err.args
|
||||
if not errorfilename:
|
||||
err.args = msg, (filename, lineno, offset, line)
|
||||
err.filename = filename
|
||||
self.colorize_syntax_error(msg, lineno, offset)
|
||||
except:
|
||||
msg = str(err)
|
||||
self.errorbox("Syntax error",
|
||||
"There's an error in your program:\n" + msg)
|
||||
return False
|
||||
# If successful, return the compiled code
|
||||
return compile(source, filename, "exec")
|
||||
except (SyntaxError, OverflowError) as value:
|
||||
msg = value.msg or "<no detail available>"
|
||||
lineno = value.lineno or 1
|
||||
offset = value.offset or 0
|
||||
if offset == 0:
|
||||
lineno += 1 #mark end of offending line
|
||||
pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1)
|
||||
editwin.colorize_syntax_error(text, pos)
|
||||
self.errorbox("SyntaxError", "%-20s" % msg)
|
||||
return False
|
||||
finally:
|
||||
shell.set_warning_stream(saved_stream)
|
||||
|
||||
def colorize_syntax_error(self, msg, lineno, offset):
|
||||
text = self.editwin.text
|
||||
pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1)
|
||||
text.tag_add("ERROR", pos)
|
||||
char = text.get(pos)
|
||||
if char and char in IDENTCHARS:
|
||||
text.tag_add("ERROR", pos + " wordstart", pos)
|
||||
if '\n' == text.get(pos): # error at line end
|
||||
text.mark_set("insert", pos)
|
||||
else:
|
||||
text.mark_set("insert", pos + "+1c")
|
||||
text.see(pos)
|
||||
|
||||
def run_module_event(self, event):
|
||||
"""Run the module after setting up the environment.
|
||||
|
||||
|
@ -199,10 +183,10 @@ def ask_save_dialog(self):
|
|||
icon=tkMessageBox.QUESTION,
|
||||
type=tkMessageBox.OKCANCEL,
|
||||
default=tkMessageBox.OK,
|
||||
master=self.editwin.text)
|
||||
parent=self.editwin.text)
|
||||
return mb.show()
|
||||
|
||||
def errorbox(self, title, message):
|
||||
# XXX This should really be a function of EditorWindow...
|
||||
tkMessageBox.showerror(title, message, master=self.editwin.text)
|
||||
tkMessageBox.showerror(title, message, parent=self.editwin.text)
|
||||
self.editwin.text.focus_set()
|
||||
|
|
|
@ -149,14 +149,14 @@ def print_exception():
|
|||
typ, val, tb = excinfo = sys.exc_info()
|
||||
sys.last_type, sys.last_value, sys.last_traceback = excinfo
|
||||
tbe = traceback.extract_tb(tb)
|
||||
print('\nTraceback (most recent call last):', file=efile)
|
||||
print('Traceback (most recent call last):', file=efile)
|
||||
exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
|
||||
"RemoteDebugger.py", "bdb.py")
|
||||
cleanup_traceback(tbe, exclude)
|
||||
traceback.print_list(tbe, file=efile)
|
||||
lines = traceback.format_exception_only(typ, val)
|
||||
for line in lines:
|
||||
print(line, end=' ', file=efile)
|
||||
print(line, end='', file=efile)
|
||||
|
||||
def cleanup_traceback(tb, exclude):
|
||||
"Remove excluded traces from beginning/end of tb; get cached lines"
|
||||
|
|
|
@ -1,40 +0,0 @@
|
|||
# Symbolic constants for use with sunaudiodev module
|
||||
# The names are the same as in audioio.h with the leading AUDIO_
|
||||
# removed.
|
||||
|
||||
# Not all values are supported on all releases of SunOS.
|
||||
|
||||
# Encoding types, for fields i_encoding and o_encoding
|
||||
|
||||
ENCODING_NONE = 0 # no encoding assigned
|
||||
ENCODING_ULAW = 1 # u-law encoding
|
||||
ENCODING_ALAW = 2 # A-law encoding
|
||||
ENCODING_LINEAR = 3 # Linear PCM encoding
|
||||
|
||||
# Gain ranges for i_gain, o_gain and monitor_gain
|
||||
|
||||
MIN_GAIN = 0 # minimum gain value
|
||||
MAX_GAIN = 255 # maximum gain value
|
||||
|
||||
# Balance values for i_balance and o_balance
|
||||
|
||||
LEFT_BALANCE = 0 # left channel only
|
||||
MID_BALANCE = 32 # equal left/right channel
|
||||
RIGHT_BALANCE = 64 # right channel only
|
||||
BALANCE_SHIFT = 3
|
||||
|
||||
# Port names for i_port and o_port
|
||||
|
||||
PORT_A = 1
|
||||
PORT_B = 2
|
||||
PORT_C = 3
|
||||
PORT_D = 4
|
||||
|
||||
SPEAKER = 0x01 # output to built-in speaker
|
||||
HEADPHONE = 0x02 # output to headphone jack
|
||||
LINE_OUT = 0x04 # output to line out
|
||||
|
||||
MICROPHONE = 0x01 # input from microphone
|
||||
LINE_IN = 0x02 # input from line in
|
||||
CD = 0x04 # input from on-board CD inputs
|
||||
INTERNAL_CD_IN = CD # input from internal CDROM
|
|
@ -372,7 +372,7 @@ test_support provides the following useful objects:
|
|||
|
||||
* ``findfile(file)`` - you can call this function to locate a file
|
||||
somewhere along sys.path or in the Lib/test tree - see
|
||||
test_linuxaudiodev.py for an example of its use.
|
||||
test_ossaudiodev.py for an example of its use.
|
||||
|
||||
* ``fcmp(x,y)`` - you can call this function to compare two floating
|
||||
point numbers when you expect them to only be approximately equal
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
test_linuxaudiodev
|
||||
expected rate >= 0, not -1
|
||||
expected sample size >= 0, not -2
|
||||
nchannels must be 1 or 2, not 3
|
||||
unknown audio encoding: 177
|
||||
for linear unsigned 16-bit little-endian audio, expected sample size 16, not 8
|
||||
for linear unsigned 8-bit audio, expected sample size 8, not 16
|
|
@ -1106,8 +1106,6 @@ def __init__(self):
|
|||
self.expected = set(s.split())
|
||||
|
||||
# expected to be skipped on every platform, even Linux
|
||||
self.expected.add('test_linuxaudiodev')
|
||||
|
||||
if not os.path.supports_unicode_filenames:
|
||||
self.expected.add('test_pep277')
|
||||
|
||||
|
@ -1134,7 +1132,6 @@ def __init__(self):
|
|||
self.expected.add(skip)
|
||||
|
||||
if sys.platform != 'sunos5':
|
||||
self.expected.add('test_sunaudiodev')
|
||||
self.expected.add('test_nis')
|
||||
|
||||
self.valid = True
|
||||
|
|
|
@ -39,7 +39,6 @@ def test_all(self):
|
|||
self.check_all("StringIO")
|
||||
self.check_all("UserString")
|
||||
self.check_all("aifc")
|
||||
self.check_all("audiodev")
|
||||
self.check_all("base64")
|
||||
self.check_all("bdb")
|
||||
self.check_all("binhex")
|
||||
|
@ -135,7 +134,6 @@ def test_all(self):
|
|||
self.check_all("textwrap")
|
||||
self.check_all("threading")
|
||||
self.check_all("timeit")
|
||||
self.check_all("toaiff")
|
||||
self.check_all("tokenize")
|
||||
self.check_all("traceback")
|
||||
self.check_all("tty")
|
||||
|
|
|
@ -733,14 +733,14 @@
|
|||
... yield 1
|
||||
Traceback (most recent call last):
|
||||
..
|
||||
SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[0]>, line 3)
|
||||
SyntaxError: 'return' with argument inside generator
|
||||
|
||||
>>> def f():
|
||||
... yield 1
|
||||
... return 22
|
||||
Traceback (most recent call last):
|
||||
..
|
||||
SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[1]>, line 3)
|
||||
SyntaxError: 'return' with argument inside generator
|
||||
|
||||
"return None" is not the same as "return" in a generator:
|
||||
|
||||
|
@ -749,7 +749,7 @@
|
|||
... return None
|
||||
Traceback (most recent call last):
|
||||
..
|
||||
SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[2]>, line 3)
|
||||
SyntaxError: 'return' with argument inside generator
|
||||
|
||||
These are fine:
|
||||
|
||||
|
@ -878,7 +878,7 @@
|
|||
... if 0:
|
||||
... yield 2 # because it's a generator (line 10)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.syntax[24]>, line 10)
|
||||
SyntaxError: 'return' with argument inside generator
|
||||
|
||||
This one caused a crash (see SF bug 567538):
|
||||
|
||||
|
@ -1525,27 +1525,27 @@ def printsolution(self, x):
|
|||
>>> f=lambda: (yield 1),(yield 2)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'yield' outside function (<doctest test.test_generators.__test__.coroutine[21]>, line 1)
|
||||
SyntaxError: 'yield' outside function
|
||||
|
||||
>>> def f(): return lambda x=(yield): 1
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'return' with argument inside generator (<doctest test.test_generators.__test__.coroutine[22]>, line 1)
|
||||
SyntaxError: 'return' with argument inside generator
|
||||
|
||||
>>> def f(): x = yield = y
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[23]>, line 1)
|
||||
SyntaxError: assignment to yield expression not possible
|
||||
|
||||
>>> def f(): (yield bar) = y
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can't assign to yield expression (<doctest test.test_generators.__test__.coroutine[24]>, line 1)
|
||||
SyntaxError: can't assign to yield expression
|
||||
|
||||
>>> def f(): (yield bar) += y
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: augmented assignment to yield expression not possible (<doctest test.test_generators.__test__.coroutine[25]>, line 1)
|
||||
SyntaxError: augmented assignment to yield expression not possible
|
||||
|
||||
|
||||
Now check some throw() conditions:
|
||||
|
|
|
@ -137,12 +137,12 @@
|
|||
>>> (y for y in (1,2)) = 10
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can't assign to generator expression (<doctest test.test_genexps.__test__.doctests[40]>, line 1)
|
||||
SyntaxError: can't assign to generator expression
|
||||
|
||||
>>> (y for y in (1,2)) += 10
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: augmented assignment to generator expression not possible (<doctest test.test_genexps.__test__.doctests[41]>, line 1)
|
||||
SyntaxError: augmented assignment to generator expression not possible
|
||||
|
||||
|
||||
########### Tests borrowed from or inspired by test_generators.py ############
|
||||
|
|
|
@ -1,92 +0,0 @@
|
|||
from test import test_support
|
||||
test_support.requires('audio')
|
||||
|
||||
from test.test_support import verbose, findfile, TestFailed, TestSkipped
|
||||
|
||||
import errno
|
||||
import fcntl
|
||||
import linuxaudiodev
|
||||
import os
|
||||
import sys
|
||||
import select
|
||||
import sunaudio
|
||||
import time
|
||||
import audioop
|
||||
|
||||
SND_FORMAT_MULAW_8 = 1
|
||||
|
||||
def play_sound_file(path):
|
||||
fp = open(path, 'r')
|
||||
size, enc, rate, nchannels, extra = sunaudio.gethdr(fp)
|
||||
data = fp.read()
|
||||
fp.close()
|
||||
|
||||
if enc != SND_FORMAT_MULAW_8:
|
||||
print("Expect .au file with 8-bit mu-law samples")
|
||||
return
|
||||
|
||||
try:
|
||||
a = linuxaudiodev.open('w')
|
||||
except linuxaudiodev.error as msg:
|
||||
if msg.args[0] in (errno.EACCES, errno.ENOENT, errno.ENODEV, errno.EBUSY):
|
||||
raise TestSkipped, msg
|
||||
raise TestFailed, msg
|
||||
|
||||
# convert the data to 16-bit signed
|
||||
data = audioop.ulaw2lin(data, 2)
|
||||
|
||||
# set the data format
|
||||
if sys.byteorder == 'little':
|
||||
fmt = linuxaudiodev.AFMT_S16_LE
|
||||
else:
|
||||
fmt = linuxaudiodev.AFMT_S16_BE
|
||||
|
||||
# at least check that these methods can be invoked
|
||||
a.bufsize()
|
||||
a.obufcount()
|
||||
a.obuffree()
|
||||
a.getptr()
|
||||
a.fileno()
|
||||
|
||||
# set parameters based on .au file headers
|
||||
a.setparameters(rate, 16, nchannels, fmt)
|
||||
a.write(data)
|
||||
a.flush()
|
||||
a.close()
|
||||
|
||||
def test_errors():
|
||||
a = linuxaudiodev.open("w")
|
||||
size = 8
|
||||
fmt = linuxaudiodev.AFMT_U8
|
||||
rate = 8000
|
||||
nchannels = 1
|
||||
try:
|
||||
a.setparameters(-1, size, nchannels, fmt)
|
||||
except ValueError as msg:
|
||||
print(msg)
|
||||
try:
|
||||
a.setparameters(rate, -2, nchannels, fmt)
|
||||
except ValueError as msg:
|
||||
print(msg)
|
||||
try:
|
||||
a.setparameters(rate, size, 3, fmt)
|
||||
except ValueError as msg:
|
||||
print(msg)
|
||||
try:
|
||||
a.setparameters(rate, size, nchannels, 177)
|
||||
except ValueError as msg:
|
||||
print(msg)
|
||||
try:
|
||||
a.setparameters(rate, size, nchannels, linuxaudiodev.AFMT_U16_LE)
|
||||
except ValueError as msg:
|
||||
print(msg)
|
||||
try:
|
||||
a.setparameters(rate, 16, nchannels, fmt)
|
||||
except ValueError as msg:
|
||||
print(msg)
|
||||
|
||||
def test():
|
||||
play_sound_file(findfile('audiotest.au'))
|
||||
test_errors()
|
||||
|
||||
test()
|
|
@ -223,25 +223,6 @@ def g():
|
|||
return getrefcount # global or local?
|
||||
""")
|
||||
|
||||
# and verify a few cases that should work
|
||||
|
||||
exec("""
|
||||
def noproblem1():
|
||||
from sys import *
|
||||
f = lambda x:x
|
||||
|
||||
def noproblem2():
|
||||
from sys import *
|
||||
def f(x):
|
||||
return x + 1
|
||||
|
||||
def noproblem3():
|
||||
from sys import *
|
||||
def f(x):
|
||||
global y
|
||||
y = x
|
||||
""")
|
||||
|
||||
def testLambdas(self):
|
||||
|
||||
f1 = lambda x: lambda y: x + y
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
from test.test_support import verbose, findfile, TestFailed, TestSkipped
|
||||
import sunaudiodev
|
||||
import os
|
||||
|
||||
try:
|
||||
audiodev = os.environ["AUDIODEV"]
|
||||
except KeyError:
|
||||
audiodev = "/dev/audio"
|
||||
|
||||
if not os.path.exists(audiodev):
|
||||
raise TestSkipped("no audio device found!")
|
||||
|
||||
def play_sound_file(path):
|
||||
fp = open(path, 'r')
|
||||
data = fp.read()
|
||||
fp.close()
|
||||
try:
|
||||
a = sunaudiodev.open('w')
|
||||
except sunaudiodev.error as msg:
|
||||
raise TestFailed, msg
|
||||
else:
|
||||
a.write(data)
|
||||
a.close()
|
||||
|
||||
def test():
|
||||
play_sound_file(findfile('audiotest.au'))
|
||||
|
||||
test()
|
|
@ -13,7 +13,6 @@
|
|||
import SimpleHTTPServer
|
||||
import SimpleXMLRPCServer
|
||||
import aifc
|
||||
import audiodev
|
||||
import bdb
|
||||
import cgitb
|
||||
import cmd
|
||||
|
@ -99,7 +98,6 @@
|
|||
import tabnanny
|
||||
import telnetlib
|
||||
import timeit
|
||||
import toaiff
|
||||
import token
|
||||
try:
|
||||
import tty # not available on Windows
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
>>> None = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: assignment to keyword (<doctest test.test_syntax[2]>, line 1)
|
||||
SyntaxError: assignment to keyword
|
||||
|
||||
It's a syntax error to assign to the empty tuple. Why isn't it an
|
||||
error to assign to the empty list? It will always raise some error at
|
||||
|
@ -41,31 +41,31 @@
|
|||
|
||||
>>> () = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to () (<doctest test.test_syntax[3]>, line 1)
|
||||
SyntaxError: can't assign to ()
|
||||
|
||||
>>> f() = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to function call (<doctest test.test_syntax[4]>, line 1)
|
||||
SyntaxError: can't assign to function call
|
||||
|
||||
>>> del f()
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't delete function call (<doctest test.test_syntax[5]>, line 1)
|
||||
SyntaxError: can't delete function call
|
||||
|
||||
>>> a + 1 = 2
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to operator (<doctest test.test_syntax[6]>, line 1)
|
||||
SyntaxError: can't assign to operator
|
||||
|
||||
>>> (x for x in x) = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to generator expression (<doctest test.test_syntax[7]>, line 1)
|
||||
SyntaxError: can't assign to generator expression
|
||||
|
||||
>>> 1 = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to literal (<doctest test.test_syntax[8]>, line 1)
|
||||
SyntaxError: can't assign to literal
|
||||
|
||||
>>> "abc" = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to literal (<doctest test.test_syntax[9]>, line 1)
|
||||
SyntaxError: can't assign to literal
|
||||
|
||||
>>> `1` = 1
|
||||
Traceback (most recent call last):
|
||||
|
@ -78,15 +78,15 @@
|
|||
|
||||
>>> (a, "b", c) = (1, 2, 3)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to literal (<doctest test.test_syntax[11]>, line 1)
|
||||
SyntaxError: can't assign to literal
|
||||
|
||||
>>> [a, b, c + 1] = [1, 2, 3]
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to operator (<doctest test.test_syntax[12]>, line 1)
|
||||
SyntaxError: can't assign to operator
|
||||
|
||||
>>> a if 1 else b = 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: can't assign to conditional expression (<doctest test.test_syntax[13]>, line 1)
|
||||
SyntaxError: can't assign to conditional expression
|
||||
|
||||
From compiler_complex_args():
|
||||
|
||||
|
@ -101,7 +101,7 @@
|
|||
>>> def f(x, y=1, z):
|
||||
... pass
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: non-default argument follows default argument (<doctest test.test_syntax[15]>, line 1)
|
||||
SyntaxError: non-default argument follows default argument
|
||||
|
||||
>>> def f(x, None):
|
||||
... pass
|
||||
|
@ -136,7 +136,7 @@
|
|||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
>>> f(x for x in L, 1)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: Generator expression must be parenthesized if not sole argument (<doctest test.test_syntax[23]>, line 1)
|
||||
SyntaxError: Generator expression must be parenthesized if not sole argument
|
||||
>>> f((x for x in L), 1)
|
||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
|
||||
|
@ -168,7 +168,7 @@
|
|||
... i244, i245, i246, i247, i248, i249, i250, i251, i252,
|
||||
... i253, i254, i255)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: more than 255 arguments (<doctest test.test_syntax[25]>, line 1)
|
||||
SyntaxError: more than 255 arguments
|
||||
|
||||
The actual error cases counts positional arguments, keyword arguments,
|
||||
and generator expression arguments separately. This test combines the
|
||||
|
@ -202,37 +202,37 @@
|
|||
... (x for x in i244), i245, i246, i247, i248, i249, i250, i251,
|
||||
... i252=1, i253=1, i254=1, i255=1)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: more than 255 arguments (<doctest test.test_syntax[26]>, line 1)
|
||||
SyntaxError: more than 255 arguments
|
||||
|
||||
>>> f(lambda x: x[0] = 3)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: lambda cannot contain assignment (<doctest test.test_syntax[27]>, line 1)
|
||||
SyntaxError: lambda cannot contain assignment
|
||||
|
||||
The grammar accepts any test (basically, any expression) in the
|
||||
keyword slot of a call site. Test a few different options.
|
||||
|
||||
>>> f(x()=2)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: keyword can't be an expression (<doctest test.test_syntax[28]>, line 1)
|
||||
SyntaxError: keyword can't be an expression
|
||||
>>> f(a or b=1)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: keyword can't be an expression (<doctest test.test_syntax[29]>, line 1)
|
||||
SyntaxError: keyword can't be an expression
|
||||
>>> f(x.y=1)
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: keyword can't be an expression (<doctest test.test_syntax[30]>, line 1)
|
||||
SyntaxError: keyword can't be an expression
|
||||
|
||||
|
||||
From ast_for_expr_stmt():
|
||||
|
||||
>>> (x for x in x) += 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: augmented assignment to generator expression not possible (<doctest test.test_syntax[31]>, line 1)
|
||||
SyntaxError: augmented assignment to generator expression not possible
|
||||
>>> None += 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: assignment to keyword (<doctest test.test_syntax[32]>, line 1)
|
||||
SyntaxError: assignment to keyword
|
||||
>>> f() += 1
|
||||
Traceback (most recent call last):
|
||||
SyntaxError: illegal expression for augmented assignment (<doctest test.test_syntax[33]>, line 1)
|
||||
SyntaxError: illegal expression for augmented assignment
|
||||
|
||||
|
||||
Test continue in finally in weird combinations.
|
||||
|
@ -259,7 +259,7 @@
|
|||
... continue
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[36]>, line 6)
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause
|
||||
|
||||
This is essentially a continue in a finally which should not be allowed.
|
||||
|
||||
|
@ -274,7 +274,7 @@
|
|||
... pass
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[37]>, line 7)
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause
|
||||
|
||||
>>> def foo():
|
||||
... try:
|
||||
|
@ -283,7 +283,7 @@
|
|||
... continue
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[38]>, line 5)
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause
|
||||
|
||||
>>> def foo():
|
||||
... for a in ():
|
||||
|
@ -293,7 +293,7 @@
|
|||
... continue
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[39]>, line 6)
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause
|
||||
|
||||
>>> def foo():
|
||||
... for a in ():
|
||||
|
@ -306,7 +306,7 @@
|
|||
... pass
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[40]>, line 7)
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause
|
||||
|
||||
>>> def foo():
|
||||
... for a in ():
|
||||
|
@ -318,7 +318,7 @@
|
|||
... continue
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause (<doctest test.test_syntax[41]>, line 8)
|
||||
SyntaxError: 'continue' not supported inside 'finally' clause
|
||||
|
||||
There is one test for a break that is not in a loop. The compiler
|
||||
uses a single data structure to keep track of try-finally and loops,
|
||||
|
@ -333,7 +333,7 @@
|
|||
... print(3)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: 'break' outside loop (<doctest test.test_syntax[42]>, line 3)
|
||||
SyntaxError: 'break' outside loop
|
||||
|
||||
This should probably raise a better error than a SystemError (or none at all).
|
||||
In 2.5 there was a missing exception and an assert was triggered in a debug
|
||||
|
@ -420,7 +420,7 @@
|
|||
... pass
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can't assign to function call (<doctest test.test_syntax[48]>, line 2)
|
||||
SyntaxError: can't assign to function call
|
||||
|
||||
>>> if 1:
|
||||
... pass
|
||||
|
@ -428,7 +428,7 @@
|
|||
... x() = 1
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can't assign to function call (<doctest test.test_syntax[49]>, line 4)
|
||||
SyntaxError: can't assign to function call
|
||||
|
||||
>>> if 1:
|
||||
... x() = 1
|
||||
|
@ -438,7 +438,7 @@
|
|||
... pass
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can't assign to function call (<doctest test.test_syntax[50]>, line 2)
|
||||
SyntaxError: can't assign to function call
|
||||
|
||||
>>> if 1:
|
||||
... pass
|
||||
|
@ -448,7 +448,7 @@
|
|||
... pass
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can't assign to function call (<doctest test.test_syntax[51]>, line 4)
|
||||
SyntaxError: can't assign to function call
|
||||
|
||||
>>> if 1:
|
||||
... pass
|
||||
|
@ -458,7 +458,7 @@
|
|||
... x() = 1
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can't assign to function call (<doctest test.test_syntax[52]>, line 6)
|
||||
SyntaxError: can't assign to function call
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -116,32 +116,32 @@
|
|||
>>> a, *b, c, *d, e = range(10) # doctest:+ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: two starred expressions in assignment (...)
|
||||
SyntaxError: two starred expressions in assignment
|
||||
|
||||
>>> [*b, *c] = range(10) # doctest:+ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: two starred expressions in assignment (...)
|
||||
SyntaxError: two starred expressions in assignment
|
||||
|
||||
>>> *a = range(10) # doctest:+ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: starred assignment target must be in a list or tuple (...)
|
||||
SyntaxError: starred assignment target must be in a list or tuple
|
||||
|
||||
>>> *a # doctest:+ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can use starred expression only as assignment target (...)
|
||||
SyntaxError: can use starred expression only as assignment target
|
||||
|
||||
>>> *1 # doctest:+ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can use starred expression only as assignment target (...)
|
||||
SyntaxError: can use starred expression only as assignment target
|
||||
|
||||
>>> x = *a # doctest:+ELLIPSIS
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
SyntaxError: can use starred expression only as assignment target (...)
|
||||
SyntaxError: can use starred expression only as assignment target
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
@ -161,7 +161,6 @@ def format_exception_only(etype, value):
|
|||
string in the list.
|
||||
|
||||
"""
|
||||
|
||||
# Gracefully handle (the way Python 2.4 and earlier did) the case of
|
||||
# being called with (None, None).
|
||||
if etype is None:
|
||||
|
@ -177,28 +176,24 @@ def format_exception_only(etype, value):
|
|||
|
||||
# It was a syntax error; show exactly where the problem was found.
|
||||
lines = []
|
||||
try:
|
||||
msg, (filename, lineno, offset, badline) = value.args
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
filename = filename or "<string>"
|
||||
lines.append(' File "%s", line %d\n' % (filename, lineno))
|
||||
if badline is not None:
|
||||
lines.append(' %s\n' % badline.strip())
|
||||
if offset is not None:
|
||||
caretspace = badline[:offset].lstrip()
|
||||
# non-space whitespace (likes tabs) must be kept for alignment
|
||||
caretspace = ((c.isspace() and c or ' ') for c in caretspace)
|
||||
# only three spaces to account for offset1 == pos 0
|
||||
lines.append(' %s^\n' % ''.join(caretspace))
|
||||
value = msg
|
||||
|
||||
lines.append(_format_final_exc_line(stype, value))
|
||||
filename = value.filename or "<string>"
|
||||
lineno = str(value.lineno) or '?'
|
||||
lines.append(' File "%s", line %s\n' % (filename, lineno))
|
||||
badline = value.text
|
||||
offset = value.offset
|
||||
if badline is not None:
|
||||
lines.append(' %s\n' % badline.strip())
|
||||
if offset is not None:
|
||||
caretspace = badline[:offset].lstrip()
|
||||
# non-space whitespace (likes tabs) must be kept for alignment
|
||||
caretspace = ((c.isspace() and c or ' ') for c in caretspace)
|
||||
# only three spaces to account for offset1 == pos 0
|
||||
lines.append(' %s^\n' % ''.join(caretspace))
|
||||
msg = value.msg or "<no detail available>"
|
||||
lines.append("%s: %s\n" % (stype, msg))
|
||||
return lines
|
||||
|
||||
def _format_final_exc_line(etype, value):
|
||||
"""Return a list of a single line -- normal case for format_exception_only"""
|
||||
valuestr = _some_str(value)
|
||||
if value is None or not valuestr:
|
||||
line = "%s\n" % etype
|
||||
|
|
|
@ -1,180 +0,0 @@
|
|||
import sys, math, audiodev
|
||||
|
||||
DOT = 30
|
||||
DAH = 80
|
||||
OCTAVE = 2 # 1 == 441 Hz, 2 == 882 Hz, ...
|
||||
SAMPWIDTH = 2
|
||||
FRAMERATE = 44100
|
||||
BASEFREQ = 441
|
||||
QSIZE = 20000
|
||||
|
||||
morsetab = {
|
||||
'A': '.-', 'a': '.-',
|
||||
'B': '-...', 'b': '-...',
|
||||
'C': '-.-.', 'c': '-.-.',
|
||||
'D': '-..', 'd': '-..',
|
||||
'E': '.', 'e': '.',
|
||||
'F': '..-.', 'f': '..-.',
|
||||
'G': '--.', 'g': '--.',
|
||||
'H': '....', 'h': '....',
|
||||
'I': '..', 'i': '..',
|
||||
'J': '.---', 'j': '.---',
|
||||
'K': '-.-', 'k': '-.-',
|
||||
'L': '.-..', 'l': '.-..',
|
||||
'M': '--', 'm': '--',
|
||||
'N': '-.', 'n': '-.',
|
||||
'O': '---', 'o': '---',
|
||||
'P': '.--.', 'p': '.--.',
|
||||
'Q': '--.-', 'q': '--.-',
|
||||
'R': '.-.', 'r': '.-.',
|
||||
'S': '...', 's': '...',
|
||||
'T': '-', 't': '-',
|
||||
'U': '..-', 'u': '..-',
|
||||
'V': '...-', 'v': '...-',
|
||||
'W': '.--', 'w': '.--',
|
||||
'X': '-..-', 'x': '-..-',
|
||||
'Y': '-.--', 'y': '-.--',
|
||||
'Z': '--..', 'z': '--..',
|
||||
'0': '-----',
|
||||
'1': '.----',
|
||||
'2': '..---',
|
||||
'3': '...--',
|
||||
'4': '....-',
|
||||
'5': '.....',
|
||||
'6': '-....',
|
||||
'7': '--...',
|
||||
'8': '---..',
|
||||
'9': '----.',
|
||||
',': '--..--',
|
||||
'.': '.-.-.-',
|
||||
'?': '..--..',
|
||||
';': '-.-.-.',
|
||||
':': '---...',
|
||||
"'": '.----.',
|
||||
'-': '-....-',
|
||||
'/': '-..-.',
|
||||
'(': '-.--.-',
|
||||
')': '-.--.-',
|
||||
'_': '..--.-',
|
||||
' ': ' '
|
||||
}
|
||||
|
||||
# If we play at 44.1 kHz (which we do), then if we produce one sine
|
||||
# wave in 100 samples, we get a tone of 441 Hz. If we produce two
|
||||
# sine waves in these 100 samples, we get a tone of 882 Hz. 882 Hz
|
||||
# appears to be a nice one for playing morse code.
|
||||
def mkwave(octave):
|
||||
global sinewave, nowave
|
||||
sinewave = ''
|
||||
n = int(FRAMERATE / BASEFREQ)
|
||||
for i in range(n):
|
||||
val = int(math.sin(2 * math.pi * i * octave / n) * 0x7fff)
|
||||
sample = chr((val >> 8) & 255) + chr(val & 255)
|
||||
sinewave = sinewave + sample[:SAMPWIDTH]
|
||||
nowave = '\0' * (n*SAMPWIDTH)
|
||||
|
||||
mkwave(OCTAVE)
|
||||
|
||||
class BufferedAudioDev:
|
||||
def __init__(self, *args):
|
||||
import audiodev
|
||||
self._base = audiodev.AudioDev(*args)
|
||||
self._buffer = []
|
||||
self._filled = 0
|
||||
self._addmethods(self._base, self._base.__class__)
|
||||
def _addmethods(self, inst, cls):
|
||||
for name in cls.__dict__.keys():
|
||||
if not hasattr(self, name):
|
||||
try:
|
||||
setattr(self, name, getattr(inst, name))
|
||||
except:
|
||||
pass
|
||||
for basecls in cls.__bases__:
|
||||
self._addmethods(self, inst, basecls)
|
||||
def writeframesraw(self, frames):
|
||||
self._buffer.append(frames)
|
||||
self._filled = self._filled + len(frames)
|
||||
if self._filled >= QSIZE:
|
||||
self.flush()
|
||||
def wait(self):
|
||||
self.flush()
|
||||
self._base.wait()
|
||||
def flush(self):
|
||||
print 'flush: %d blocks, %d bytes' % (len(self._buffer), self._filled)
|
||||
if self._buffer:
|
||||
import string
|
||||
self._base.writeframes(string.joinfields(self._buffer, ''))
|
||||
self._buffer = []
|
||||
self._filled = 0
|
||||
|
||||
def main(args = sys.argv[1:]):
|
||||
import getopt, string
|
||||
try:
|
||||
opts, args = getopt.getopt(args, 'o:p:')
|
||||
except getopt.error:
|
||||
sys.stderr.write('Usage ' + sys.argv[0] +
|
||||
' [ -o outfile ] [ args ] ...\n')
|
||||
sys.exit(1)
|
||||
dev = None
|
||||
for o, a in opts:
|
||||
if o == '-o':
|
||||
import aifc
|
||||
dev = aifc.open(a, 'w')
|
||||
dev.setframerate(FRAMERATE)
|
||||
dev.setsampwidth(SAMPWIDTH)
|
||||
dev.setnchannels(1)
|
||||
if o == '-p':
|
||||
mkwave(string.atoi(a))
|
||||
if not dev:
|
||||
dev = BufferedAudioDev()
|
||||
dev.setoutrate(FRAMERATE)
|
||||
dev.setsampwidth(SAMPWIDTH)
|
||||
dev.setnchannels(1)
|
||||
dev.close = dev.stop
|
||||
if args:
|
||||
line = string.join(args)
|
||||
else:
|
||||
line = sys.stdin.readline()
|
||||
while line:
|
||||
print line
|
||||
mline = morse(line)
|
||||
print mline
|
||||
play(mline, dev)
|
||||
if hasattr(dev, 'wait'):
|
||||
dev.wait()
|
||||
if not args:
|
||||
line = sys.stdin.readline()
|
||||
else:
|
||||
line = ''
|
||||
dev.close()
|
||||
|
||||
# Convert a string to morse code with \001 between the characters in
|
||||
# the string.
|
||||
def morse(line):
|
||||
res = ''
|
||||
for c in line:
|
||||
try:
|
||||
res = res + morsetab[c] + '\001'
|
||||
except KeyError:
|
||||
pass
|
||||
return res
|
||||
|
||||
# Play a line of morse code.
|
||||
def play(line, dev):
|
||||
for c in line:
|
||||
if c == '.':
|
||||
sine(dev, DOT)
|
||||
elif c == '-':
|
||||
sine(dev, DAH)
|
||||
else:
|
||||
pause(dev, DAH)
|
||||
pause(dev, DOT)
|
||||
|
||||
def sine(dev, length):
|
||||
dev.writeframesraw(sinewave*length)
|
||||
|
||||
def pause(dev, length):
|
||||
dev.writeframesraw(nowave*length)
|
||||
|
||||
if __name__ == '__main__' or sys.argv[0] == __name__:
|
||||
main()
|
|
@ -608,7 +608,7 @@ buildbottest: all platform
|
|||
|
||||
QUICKTESTOPTS= $(TESTOPTS) -x test_thread test_signal test_strftime \
|
||||
test_unicodedata test_re test_sre test_select test_poll \
|
||||
test_linuxaudiodev test_struct test_sunaudiodev test_zlib
|
||||
test_struct test_zlib
|
||||
quicktest: all platform
|
||||
-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
|
||||
-$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
|
||||
|
|
|
@ -445,15 +445,6 @@ def detect_modules(self):
|
|||
define_macros = expat_defs,
|
||||
libraries = ['expat']) )
|
||||
|
||||
# Platform-specific libraries
|
||||
if platform == 'linux2':
|
||||
# Linux-specific modules
|
||||
exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
|
||||
|
||||
if platform == 'sunos5':
|
||||
# SunOS specific modules
|
||||
exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
|
||||
|
||||
self.extensions.extend(exts)
|
||||
|
||||
# Call the method for detecting whether _tkinter can be compiled
|
||||
|
|
|
@ -186,8 +186,12 @@ Library
|
|||
AST -> bytecode mechanism.
|
||||
|
||||
- Removed these modules:
|
||||
* Bastion, bsddb185, exceptions, md5, MimeWriter, mimify, popen2, rexec,
|
||||
sets, sha, stringold, strop, timing, xmllib.
|
||||
* audiodev, Bastion, bsddb185, exceptions, linuxaudiodev,
|
||||
md5, MimeWriter, mimify, popen2,
|
||||
rexec, sets, sha, stringold, strop, sunaudiodev, timing, xmllib.
|
||||
|
||||
- Moved these modules to Tools/Demos:
|
||||
* toaiff
|
||||
|
||||
- Remove obsolete IRIX modules: al/AL, cd/CD, cddb, cdplayer, cl/CL, DEVICE,
|
||||
ERRNO, FILE, fl/FL, flp, fm, GET, gl/GL, GLWS, IN, imgfile, IOCTL, jpeg,
|
||||
|
|
|
@ -1808,7 +1808,6 @@ anydbm Generic interface to all dbm clones. (dbhash, gdbm,
|
|||
asynchat Support for 'chat' style protocols
|
||||
asyncore Asynchronous File I/O (in select style)
|
||||
atexit Register functions to be called at exit of Python interpreter.
|
||||
audiodev Audio support for a few platforms.
|
||||
base64 Conversions to/from base64 RFC-MIME transport encoding .
|
||||
BaseHTTPServer Base class forhttp services.
|
||||
Bastion "Bastionification" utility (control access to instance vars)
|
||||
|
@ -1871,7 +1870,6 @@ imputil Privides a way of writing customised import hooks.
|
|||
inspect Tool for probing live Python objects.
|
||||
keyword List of Python keywords.
|
||||
linecache Cache lines from files.
|
||||
linuxaudiodev Lunix /dev/audio support.
|
||||
locale Support for number formatting using the current locale
|
||||
settings.
|
||||
logging Python logging facility.
|
||||
|
@ -1946,7 +1944,6 @@ tempfile Temporary file name allocation.
|
|||
textwrap Object for wrapping and filling text.
|
||||
threading Proposed new higher-level threading interfaces
|
||||
threading_api (doc of the threading module)
|
||||
toaiff Convert "arbitrary" sound files to AIFF files .
|
||||
token Tokens (from "token.h").
|
||||
tokenize Compiles a regular expression that recognizes Python tokens.
|
||||
traceback Format and print Python stack traces.
|
||||
|
@ -2042,10 +2039,6 @@ zipfile Read & write PK zipped files.
|
|||
DEVICE More constants for gl
|
||||
imgfile Imglib image file interface
|
||||
|
||||
* Suns *
|
||||
|
||||
sunaudiodev Access to sun audio interface
|
||||
|
||||
|
||||
Workspace exploration and idiom hints
|
||||
|
||||
|
|
|
@ -236,17 +236,6 @@ _symtable symtablemodule.c
|
|||
#_sha shamodule.c
|
||||
|
||||
|
||||
# SunOS specific modules -- off by default:
|
||||
|
||||
#sunaudiodev sunaudiodev.c
|
||||
|
||||
|
||||
# A Linux specific module -- off by default; this may also work on
|
||||
# some *BSDs.
|
||||
|
||||
#linuxaudiodev linuxaudiodev.c
|
||||
|
||||
|
||||
# The _tkinter module.
|
||||
#
|
||||
# The command for _tkinter is long and site specific. Please
|
||||
|
|
|
@ -861,8 +861,8 @@ static struct PyMethodDef Reader_methods[] = {
|
|||
#define R_OFF(x) offsetof(ReaderObj, x)
|
||||
|
||||
static struct PyMemberDef Reader_memberlist[] = {
|
||||
{ "dialect", T_OBJECT, R_OFF(dialect), RO },
|
||||
{ "line_num", T_ULONG, R_OFF(line_num), RO },
|
||||
{ "dialect", T_OBJECT, R_OFF(dialect), READONLY },
|
||||
{ "line_num", T_ULONG, R_OFF(line_num), READONLY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
@ -1239,7 +1239,7 @@ static struct PyMethodDef Writer_methods[] = {
|
|||
#define W_OFF(x) offsetof(WriterObj, x)
|
||||
|
||||
static struct PyMemberDef Writer_memberlist[] = {
|
||||
{ "dialect", T_OBJECT, W_OFF(dialect), RO },
|
||||
{ "dialect", T_OBJECT, W_OFF(dialect), READONLY },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
|
|
|
@ -1266,7 +1266,7 @@ static PyMethodDef logreader_methods[] = {
|
|||
};
|
||||
|
||||
static PyMemberDef logreader_members[] = {
|
||||
{"info", T_OBJECT, offsetof(LogReaderObject, info), RO,
|
||||
{"info", T_OBJECT, offsetof(LogReaderObject, info), READONLY,
|
||||
PyDoc_STR("Dictionary mapping informational keys to lists of values.")},
|
||||
{NULL}
|
||||
};
|
||||
|
|
|
@ -1624,7 +1624,7 @@ static PyTypeObject BZ2Comp_Type = {
|
|||
#define OFF(x) offsetof(BZ2DecompObject, x)
|
||||
|
||||
static PyMemberDef BZ2Decomp_members[] = {
|
||||
{"unused_data", T_OBJECT, OFF(unused_data), RO},
|
||||
{"unused_data", T_OBJECT, OFF(unused_data), READONLY},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -1,501 +0,0 @@
|
|||
/* Hey Emacs, this is -*-C-*-
|
||||
******************************************************************************
|
||||
* linuxaudiodev.c -- Linux audio device for python.
|
||||
*
|
||||
* Author : Peter Bosch
|
||||
* Created On : Thu Mar 2 21:10:33 2000
|
||||
* Status : Unknown, Use with caution!
|
||||
*
|
||||
* Unless other notices are present in any part of this file
|
||||
* explicitly claiming copyrights for other people and/or
|
||||
* organizations, the contents of this file is fully copyright
|
||||
* (C) 2000 Peter Bosch, all rights reserved.
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include "Python.h"
|
||||
#include "structmember.h"
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#else
|
||||
#define O_RDONLY 00
|
||||
#define O_WRONLY 01
|
||||
#endif
|
||||
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#if defined(linux)
|
||||
#include <linux/soundcard.h>
|
||||
|
||||
#ifndef HAVE_STDINT_H
|
||||
typedef unsigned long uint32_t;
|
||||
#endif
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
#include <machine/soundcard.h>
|
||||
|
||||
#ifndef SNDCTL_DSP_CHANNELS
|
||||
#define SNDCTL_DSP_CHANNELS SOUND_PCM_WRITE_CHANNELS
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
int x_fd; /* The open file */
|
||||
int x_mode; /* file mode */
|
||||
int x_icount; /* Input count */
|
||||
int x_ocount; /* Output count */
|
||||
uint32_t x_afmts; /* Audio formats supported by hardware*/
|
||||
} lad_t;
|
||||
|
||||
/* XXX several format defined in soundcard.h are not supported,
|
||||
including _NE (native endian) options and S32 options
|
||||
*/
|
||||
|
||||
static struct {
|
||||
int a_bps;
|
||||
uint32_t a_fmt;
|
||||
char *a_name;
|
||||
} audio_types[] = {
|
||||
{ 8, AFMT_MU_LAW, "logarithmic mu-law 8-bit audio" },
|
||||
{ 8, AFMT_A_LAW, "logarithmic A-law 8-bit audio" },
|
||||
{ 8, AFMT_U8, "linear unsigned 8-bit audio" },
|
||||
{ 8, AFMT_S8, "linear signed 8-bit audio" },
|
||||
{ 16, AFMT_U16_BE, "linear unsigned 16-bit big-endian audio" },
|
||||
{ 16, AFMT_U16_LE, "linear unsigned 16-bit little-endian audio" },
|
||||
{ 16, AFMT_S16_BE, "linear signed 16-bit big-endian audio" },
|
||||
{ 16, AFMT_S16_LE, "linear signed 16-bit little-endian audio" },
|
||||
{ 16, AFMT_S16_NE, "linear signed 16-bit native-endian audio" },
|
||||
};
|
||||
|
||||
static int n_audio_types = sizeof(audio_types) / sizeof(audio_types[0]);
|
||||
|
||||
static PyTypeObject Ladtype;
|
||||
|
||||
static PyObject *LinuxAudioError;
|
||||
|
||||
static lad_t *
|
||||
newladobject(PyObject *arg)
|
||||
{
|
||||
lad_t *xp;
|
||||
int fd, afmts, imode;
|
||||
char *basedev = NULL;
|
||||
char *mode = NULL;
|
||||
|
||||
/* Two ways to call linuxaudiodev.open():
|
||||
open(device, mode) (for consistency with builtin open())
|
||||
open(mode) (for backwards compatibility)
|
||||
because the *first* argument is optional, parsing args is
|
||||
a wee bit tricky. */
|
||||
if (!PyArg_ParseTuple(arg, "s|s:open", &basedev, &mode))
|
||||
return NULL;
|
||||
if (mode == NULL) { /* only one arg supplied */
|
||||
mode = basedev;
|
||||
basedev = NULL;
|
||||
}
|
||||
|
||||
if (strcmp(mode, "r") == 0)
|
||||
imode = O_RDONLY;
|
||||
else if (strcmp(mode, "w") == 0)
|
||||
imode = O_WRONLY;
|
||||
else {
|
||||
PyErr_SetString(LinuxAudioError, "mode should be 'r' or 'w'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Open the correct device. The base device name comes from the
|
||||
* AUDIODEV environment variable first, then /dev/dsp. The
|
||||
* control device tacks "ctl" onto the base device name.
|
||||
*
|
||||
* Note that the only difference between /dev/audio and /dev/dsp
|
||||
* is that the former uses logarithmic mu-law encoding and the
|
||||
* latter uses 8-bit unsigned encoding.
|
||||
*/
|
||||
|
||||
if (basedev == NULL) { /* called with one arg */
|
||||
basedev = getenv("AUDIODEV");
|
||||
if (basedev == NULL) /* $AUDIODEV not set */
|
||||
basedev = "/dev/dsp";
|
||||
}
|
||||
|
||||
if ((fd = open(basedev, imode)) == -1) {
|
||||
PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
|
||||
return NULL;
|
||||
}
|
||||
if (imode == O_WRONLY && ioctl(fd, SNDCTL_DSP_NONBLOCK, NULL) == -1) {
|
||||
PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(fd, SNDCTL_DSP_GETFMTS, &afmts) == -1) {
|
||||
PyErr_SetFromErrnoWithFilename(LinuxAudioError, basedev);
|
||||
return NULL;
|
||||
}
|
||||
/* Create and initialize the object */
|
||||
if ((xp = PyObject_New(lad_t, &Ladtype)) == NULL) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
xp->x_fd = fd;
|
||||
xp->x_mode = imode;
|
||||
xp->x_icount = xp->x_ocount = 0;
|
||||
xp->x_afmts = afmts;
|
||||
return xp;
|
||||
}
|
||||
|
||||
static void
|
||||
lad_dealloc(lad_t *xp)
|
||||
{
|
||||
/* if already closed, don't reclose it */
|
||||
if (xp->x_fd != -1)
|
||||
close(xp->x_fd);
|
||||
PyObject_Del(xp);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
lad_read(lad_t *self, PyObject *args)
|
||||
{
|
||||
int size, count;
|
||||
char *cp;
|
||||
PyObject *rv;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i:read", &size))
|
||||
return NULL;
|
||||
rv = PyString_FromStringAndSize(NULL, size);
|
||||
if (rv == NULL)
|
||||
return NULL;
|
||||
cp = PyString_AS_STRING(rv);
|
||||
if ((count = read(self->x_fd, cp, size)) < 0) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
Py_DECREF(rv);
|
||||
return NULL;
|
||||
}
|
||||
self->x_icount += count;
|
||||
_PyString_Resize(&rv, count);
|
||||
return rv;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
lad_write(lad_t *self, PyObject *args)
|
||||
{
|
||||
char *cp;
|
||||
int rv, size;
|
||||
fd_set write_set_fds;
|
||||
struct timeval tv;
|
||||
int select_retval;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
|
||||
return NULL;
|
||||
|
||||
/* use select to wait for audio device to be available */
|
||||
FD_ZERO(&write_set_fds);
|
||||
FD_SET(self->x_fd, &write_set_fds);
|
||||
tv.tv_sec = 4; /* timeout values */
|
||||
tv.tv_usec = 0;
|
||||
|
||||
while (size > 0) {
|
||||
select_retval = select(self->x_fd+1, NULL, &write_set_fds, NULL, &tv);
|
||||
tv.tv_sec = 1; tv.tv_usec = 0; /* willing to wait this long next time*/
|
||||
if (select_retval) {
|
||||
if ((rv = write(self->x_fd, cp, size)) == -1) {
|
||||
if (errno != EAGAIN) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
} else {
|
||||
errno = 0; /* EAGAIN: buffer is full, try again */
|
||||
}
|
||||
} else {
|
||||
self->x_ocount += rv;
|
||||
size -= rv;
|
||||
cp += rv;
|
||||
}
|
||||
} else {
|
||||
/* printf("Not able to write to linux audio device within %ld seconds\n", tv.tv_sec); */
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
lad_close(lad_t *self, PyObject *unused)
|
||||
{
|
||||
if (self->x_fd >= 0) {
|
||||
close(self->x_fd);
|
||||
self->x_fd = -1;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
lad_fileno(lad_t *self, PyObject *unused)
|
||||
{
|
||||
return PyInt_FromLong(self->x_fd);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
lad_setparameters(lad_t *self, PyObject *args)
|
||||
{
|
||||
int rate, ssize, nchannels, n, fmt, emulate=0;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "iiii|i:setparameters",
|
||||
&rate, &ssize, &nchannels, &fmt, &emulate))
|
||||
return NULL;
|
||||
|
||||
if (rate < 0) {
|
||||
PyErr_Format(PyExc_ValueError, "expected rate >= 0, not %d",
|
||||
rate);
|
||||
return NULL;
|
||||
}
|
||||
if (ssize < 0) {
|
||||
PyErr_Format(PyExc_ValueError, "expected sample size >= 0, not %d",
|
||||
ssize);
|
||||
return NULL;
|
||||
}
|
||||
if (nchannels != 1 && nchannels != 2) {
|
||||
PyErr_Format(PyExc_ValueError, "nchannels must be 1 or 2, not %d",
|
||||
nchannels);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (n = 0; n < n_audio_types; n++)
|
||||
if (fmt == audio_types[n].a_fmt)
|
||||
break;
|
||||
if (n == n_audio_types) {
|
||||
PyErr_Format(PyExc_ValueError, "unknown audio encoding: %d", fmt);
|
||||
return NULL;
|
||||
}
|
||||
if (audio_types[n].a_bps != ssize) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"for %s, expected sample size %d, not %d",
|
||||
audio_types[n].a_name, audio_types[n].a_bps, ssize);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (emulate == 0) {
|
||||
if ((self->x_afmts & audio_types[n].a_fmt) == 0) {
|
||||
PyErr_Format(PyExc_ValueError,
|
||||
"%s format not supported by device",
|
||||
audio_types[n].a_name);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT,
|
||||
&audio_types[n].a_fmt) == -1) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, &nchannels) == -1) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_SPEED, &rate) == -1) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static int
|
||||
_ssize(lad_t *self, int *nchannels, int *ssize)
|
||||
{
|
||||
int fmt;
|
||||
|
||||
fmt = 0;
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_SETFMT, &fmt) < 0)
|
||||
return -errno;
|
||||
|
||||
switch (fmt) {
|
||||
case AFMT_MU_LAW:
|
||||
case AFMT_A_LAW:
|
||||
case AFMT_U8:
|
||||
case AFMT_S8:
|
||||
*ssize = sizeof(char);
|
||||
break;
|
||||
case AFMT_S16_LE:
|
||||
case AFMT_S16_BE:
|
||||
case AFMT_U16_LE:
|
||||
case AFMT_U16_BE:
|
||||
*ssize = sizeof(short);
|
||||
break;
|
||||
case AFMT_MPEG:
|
||||
case AFMT_IMA_ADPCM:
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_CHANNELS, nchannels) < 0)
|
||||
return -errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* bufsize returns the size of the hardware audio buffer in number
|
||||
of samples */
|
||||
static PyObject *
|
||||
lad_bufsize(lad_t *self, PyObject *unused)
|
||||
{
|
||||
audio_buf_info ai;
|
||||
int nchannels=0, ssize=0;
|
||||
|
||||
if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
return PyInt_FromLong((ai.fragstotal * ai.fragsize) / (nchannels * ssize));
|
||||
}
|
||||
|
||||
/* obufcount returns the number of samples that are available in the
|
||||
hardware for playing */
|
||||
static PyObject *
|
||||
lad_obufcount(lad_t *self, PyObject *unused)
|
||||
{
|
||||
audio_buf_info ai;
|
||||
int nchannels=0, ssize=0;
|
||||
|
||||
if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
return PyInt_FromLong((ai.fragstotal * ai.fragsize - ai.bytes) /
|
||||
(ssize * nchannels));
|
||||
}
|
||||
|
||||
/* obufcount returns the number of samples that can be played without
|
||||
blocking */
|
||||
static PyObject *
|
||||
lad_obuffree(lad_t *self, PyObject *unused)
|
||||
{
|
||||
audio_buf_info ai;
|
||||
int nchannels=0, ssize=0;
|
||||
|
||||
if (_ssize(self, &nchannels, &ssize) < 0 || !ssize || !nchannels) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_GETOSPACE, &ai) < 0) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
return PyInt_FromLong(ai.bytes / (ssize * nchannels));
|
||||
}
|
||||
|
||||
/* Flush the device */
|
||||
static PyObject *
|
||||
lad_flush(lad_t *self, PyObject *unused)
|
||||
{
|
||||
if (ioctl(self->x_fd, SNDCTL_DSP_SYNC, NULL) == -1) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
lad_getptr(lad_t *self, PyObject *unused)
|
||||
{
|
||||
count_info info;
|
||||
int req;
|
||||
|
||||
if (self->x_mode == O_RDONLY)
|
||||
req = SNDCTL_DSP_GETIPTR;
|
||||
else
|
||||
req = SNDCTL_DSP_GETOPTR;
|
||||
if (ioctl(self->x_fd, req, &info) == -1) {
|
||||
PyErr_SetFromErrno(LinuxAudioError);
|
||||
return NULL;
|
||||
}
|
||||
return Py_BuildValue("iii", info.bytes, info.blocks, info.ptr);
|
||||
}
|
||||
|
||||
static PyMethodDef lad_methods[] = {
|
||||
{ "read", (PyCFunction)lad_read, METH_VARARGS },
|
||||
{ "write", (PyCFunction)lad_write, METH_VARARGS },
|
||||
{ "setparameters", (PyCFunction)lad_setparameters, METH_VARARGS },
|
||||
{ "bufsize", (PyCFunction)lad_bufsize, METH_VARARGS },
|
||||
{ "obufcount", (PyCFunction)lad_obufcount, METH_NOARGS },
|
||||
{ "obuffree", (PyCFunction)lad_obuffree, METH_NOARGS },
|
||||
{ "flush", (PyCFunction)lad_flush, METH_NOARGS },
|
||||
{ "close", (PyCFunction)lad_close, METH_NOARGS },
|
||||
{ "fileno", (PyCFunction)lad_fileno, METH_NOARGS },
|
||||
{ "getptr", (PyCFunction)lad_getptr, METH_NOARGS },
|
||||
{ NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
lad_getattr(lad_t *xp, char *name)
|
||||
{
|
||||
return Py_FindMethod(lad_methods, (PyObject *)xp, name);
|
||||
}
|
||||
|
||||
static PyTypeObject Ladtype = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"linuxaudiodev.linux_audio_device", /*tp_name*/
|
||||
sizeof(lad_t), /*tp_size*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)lad_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
(getattrfunc)lad_getattr, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
ladopen(PyObject *self, PyObject *args)
|
||||
{
|
||||
return (PyObject *)newladobject(args);
|
||||
}
|
||||
|
||||
static PyMethodDef linuxaudiodev_methods[] = {
|
||||
{ "open", ladopen, METH_VARARGS },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
void
|
||||
initlinuxaudiodev(void)
|
||||
{
|
||||
PyObject *m;
|
||||
|
||||
m = Py_InitModule("linuxaudiodev", linuxaudiodev_methods);
|
||||
if (m == NULL)
|
||||
return;
|
||||
|
||||
LinuxAudioError = PyErr_NewException("linuxaudiodev.error", NULL, NULL);
|
||||
if (LinuxAudioError)
|
||||
PyModule_AddObject(m, "error", LinuxAudioError);
|
||||
|
||||
if (PyModule_AddIntConstant(m, "AFMT_MU_LAW", (long)AFMT_MU_LAW) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_A_LAW", (long)AFMT_A_LAW) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_U8", (long)AFMT_U8) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_S8", (long)AFMT_S8) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_U16_BE", (long)AFMT_U16_BE) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_U16_LE", (long)AFMT_U16_LE) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_S16_BE", (long)AFMT_S16_BE) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_S16_LE", (long)AFMT_S16_LE) == -1)
|
||||
return;
|
||||
if (PyModule_AddIntConstant(m, "AFMT_S16_NE", (long)AFMT_S16_NE) == -1)
|
||||
return;
|
||||
|
||||
return;
|
||||
}
|
|
@ -1,463 +0,0 @@
|
|||
|
||||
/* Sad objects */
|
||||
|
||||
#include "Python.h"
|
||||
#include "structmember.h"
|
||||
|
||||
#ifdef HAVE_SYS_AUDIOIO_H
|
||||
#define SOLARIS
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#include <stropts.h>
|
||||
#include <sys/ioctl.h>
|
||||
#ifdef SOLARIS
|
||||
#include <sys/audioio.h>
|
||||
#else
|
||||
#include <sun/audioio.h>
|
||||
#endif
|
||||
|
||||
/* #define offsetof(str,mem) ((int)(((str *)0)->mem)) */
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
int x_fd; /* The open file */
|
||||
int x_icount; /* # samples read */
|
||||
int x_ocount; /* # samples written */
|
||||
int x_isctl; /* True if control device */
|
||||
|
||||
} sadobject;
|
||||
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
audio_info_t ai;
|
||||
} sadstatusobject;
|
||||
|
||||
static PyTypeObject Sadtype;
|
||||
static PyTypeObject Sadstatustype;
|
||||
static sadstatusobject *sads_alloc(void); /* Forward */
|
||||
|
||||
static PyObject *SunAudioError;
|
||||
|
||||
#define is_sadobject(v) (Py_Type(v) == &Sadtype)
|
||||
#define is_sadstatusobject(v) (Py_Type(v) == &Sadstatustype)
|
||||
|
||||
|
||||
static sadobject *
|
||||
newsadobject(PyObject *args)
|
||||
{
|
||||
sadobject *xp;
|
||||
int fd;
|
||||
char *mode;
|
||||
int imode;
|
||||
char* basedev;
|
||||
char* ctldev;
|
||||
char* opendev;
|
||||
|
||||
/* Check arg for r/w/rw */
|
||||
if (!PyArg_ParseTuple(args, "s", &mode))
|
||||
return NULL;
|
||||
if (strcmp(mode, "r") == 0)
|
||||
imode = 0;
|
||||
else if (strcmp(mode, "w") == 0)
|
||||
imode = 1;
|
||||
else if (strcmp(mode, "rw") == 0)
|
||||
imode = 2;
|
||||
else if (strcmp(mode, "control") == 0)
|
||||
imode = -1;
|
||||
else {
|
||||
PyErr_SetString(SunAudioError,
|
||||
"Mode should be one of 'r', 'w', 'rw' or 'control'");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Open the correct device. The base device name comes from the
|
||||
* AUDIODEV environment variable first, then /dev/audio. The
|
||||
* control device tacks "ctl" onto the base device name.
|
||||
*/
|
||||
basedev = getenv("AUDIODEV");
|
||||
if (!basedev)
|
||||
basedev = "/dev/audio";
|
||||
ctldev = PyMem_NEW(char, strlen(basedev) + 4);
|
||||
if (!ctldev) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
strcpy(ctldev, basedev);
|
||||
strcat(ctldev, "ctl");
|
||||
|
||||
if (imode < 0) {
|
||||
opendev = ctldev;
|
||||
fd = open(ctldev, 2);
|
||||
}
|
||||
else {
|
||||
opendev = basedev;
|
||||
fd = open(basedev, imode);
|
||||
}
|
||||
if (fd < 0) {
|
||||
PyErr_SetFromErrnoWithFilename(SunAudioError, opendev);
|
||||
PyMem_DEL(ctldev);
|
||||
return NULL;
|
||||
}
|
||||
PyMem_DEL(ctldev);
|
||||
|
||||
/* Create and initialize the object */
|
||||
xp = PyObject_New(sadobject, &Sadtype);
|
||||
if (xp == NULL) {
|
||||
close(fd);
|
||||
return NULL;
|
||||
}
|
||||
xp->x_fd = fd;
|
||||
xp->x_icount = xp->x_ocount = 0;
|
||||
xp->x_isctl = (imode < 0);
|
||||
|
||||
return xp;
|
||||
}
|
||||
|
||||
/* Sad methods */
|
||||
|
||||
static void
|
||||
sad_dealloc(sadobject *xp)
|
||||
{
|
||||
close(xp->x_fd);
|
||||
PyObject_Del(xp);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_read(sadobject *self, PyObject *args)
|
||||
{
|
||||
int size, count;
|
||||
char *cp;
|
||||
PyObject *rv;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "i:read", &size))
|
||||
return NULL;
|
||||
rv = PyString_FromStringAndSize(NULL, size);
|
||||
if (rv == NULL)
|
||||
return NULL;
|
||||
|
||||
if (!(cp = PyString_AsString(rv)))
|
||||
goto finally;
|
||||
|
||||
count = read(self->x_fd, cp, size);
|
||||
if (count < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
goto finally;
|
||||
}
|
||||
#if 0
|
||||
/* TBD: why print this message if you can handle the condition?
|
||||
* assume it's debugging info which we can just as well get rid
|
||||
* of. in any case this message should *not* be using printf!
|
||||
*/
|
||||
if (count != size)
|
||||
printf("sunaudio: funny read rv %d wtd %d\n", count, size);
|
||||
#endif
|
||||
self->x_icount += count;
|
||||
return rv;
|
||||
|
||||
finally:
|
||||
Py_DECREF(rv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_write(sadobject *self, PyObject *args)
|
||||
{
|
||||
char *cp;
|
||||
int count, size;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s#:write", &cp, &size))
|
||||
return NULL;
|
||||
|
||||
count = write(self->x_fd, cp, size);
|
||||
if (count < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
return NULL;
|
||||
}
|
||||
#if 0
|
||||
if (count != size)
|
||||
printf("sunaudio: funny write rv %d wanted %d\n", count, size);
|
||||
#endif
|
||||
self->x_ocount += count;
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_getinfo(sadobject *self)
|
||||
{
|
||||
sadstatusobject *rv;
|
||||
|
||||
if (!(rv = sads_alloc()))
|
||||
return NULL;
|
||||
|
||||
if (ioctl(self->x_fd, AUDIO_GETINFO, &rv->ai) < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
Py_DECREF(rv);
|
||||
return NULL;
|
||||
}
|
||||
return (PyObject *)rv;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_setinfo(sadobject *self, sadstatusobject *arg)
|
||||
{
|
||||
if (!is_sadstatusobject(arg)) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"Must be sun audio status object");
|
||||
return NULL;
|
||||
}
|
||||
if (ioctl(self->x_fd, AUDIO_SETINFO, &arg->ai) < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_ibufcount(sadobject *self)
|
||||
{
|
||||
audio_info_t ai;
|
||||
|
||||
if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
return NULL;
|
||||
}
|
||||
return PyInt_FromLong(ai.record.samples - self->x_icount);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_obufcount(sadobject *self)
|
||||
{
|
||||
audio_info_t ai;
|
||||
|
||||
if (ioctl(self->x_fd, AUDIO_GETINFO, &ai) < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
return NULL;
|
||||
}
|
||||
/* x_ocount is in bytes, whereas play.samples is in frames */
|
||||
/* we want frames */
|
||||
return PyInt_FromLong(self->x_ocount / (ai.play.channels *
|
||||
ai.play.precision / 8) -
|
||||
ai.play.samples);
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_drain(sadobject *self)
|
||||
{
|
||||
if (ioctl(self->x_fd, AUDIO_DRAIN, 0) < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
#ifdef SOLARIS
|
||||
static PyObject *
|
||||
sad_getdev(sadobject *self)
|
||||
{
|
||||
struct audio_device ad;
|
||||
|
||||
if (ioctl(self->x_fd, AUDIO_GETDEV, &ad) < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
return NULL;
|
||||
}
|
||||
return Py_BuildValue("(sss)", ad.name, ad.version, ad.config);
|
||||
}
|
||||
#endif
|
||||
|
||||
static PyObject *
|
||||
sad_flush(sadobject *self)
|
||||
{
|
||||
if (ioctl(self->x_fd, I_FLUSH, FLUSHW) < 0) {
|
||||
PyErr_SetFromErrno(SunAudioError);
|
||||
return NULL;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_close(sadobject *self)
|
||||
{
|
||||
|
||||
if (self->x_fd >= 0) {
|
||||
close(self->x_fd);
|
||||
self->x_fd = -1;
|
||||
}
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
sad_fileno(sadobject *self)
|
||||
{
|
||||
return PyInt_FromLong(self->x_fd);
|
||||
}
|
||||
|
||||
|
||||
static PyMethodDef sad_methods[] = {
|
||||
{ "read", (PyCFunction)sad_read, METH_VARARGS },
|
||||
{ "write", (PyCFunction)sad_write, METH_VARARGS },
|
||||
{ "ibufcount", (PyCFunction)sad_ibufcount, METH_NOARGS },
|
||||
{ "obufcount", (PyCFunction)sad_obufcount, METH_NOARGS },
|
||||
#define CTL_METHODS 4
|
||||
{ "getinfo", (PyCFunction)sad_getinfo, METH_NOARGS },
|
||||
{ "setinfo", (PyCFunction)sad_setinfo, METH_O},
|
||||
{ "drain", (PyCFunction)sad_drain, METH_NOARGS },
|
||||
{ "flush", (PyCFunction)sad_flush, METH_NOARGS },
|
||||
#ifdef SOLARIS
|
||||
{ "getdev", (PyCFunction)sad_getdev, METH_NOARGS },
|
||||
#endif
|
||||
{ "close", (PyCFunction)sad_close, METH_NOARGS },
|
||||
{ "fileno", (PyCFunction)sad_fileno, METH_NOARGS },
|
||||
{NULL, NULL} /* sentinel */
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
sad_getattr(sadobject *xp, char *name)
|
||||
{
|
||||
if (xp->x_isctl)
|
||||
return Py_FindMethod(sad_methods+CTL_METHODS,
|
||||
(PyObject *)xp, name);
|
||||
else
|
||||
return Py_FindMethod(sad_methods, (PyObject *)xp, name);
|
||||
}
|
||||
|
||||
/* ----------------------------------------------------------------- */
|
||||
|
||||
static sadstatusobject *
|
||||
sads_alloc(void) {
|
||||
return PyObject_New(sadstatusobject, &Sadstatustype);
|
||||
}
|
||||
|
||||
static void
|
||||
sads_dealloc(sadstatusobject *xp)
|
||||
{
|
||||
PyMem_DEL(xp);
|
||||
}
|
||||
|
||||
#define OFF(x) offsetof(audio_info_t,x)
|
||||
static struct memberlist sads_ml[] = {
|
||||
{ "i_sample_rate", T_UINT, OFF(record.sample_rate) },
|
||||
{ "i_channels", T_UINT, OFF(record.channels) },
|
||||
{ "i_precision", T_UINT, OFF(record.precision) },
|
||||
{ "i_encoding", T_UINT, OFF(record.encoding) },
|
||||
{ "i_gain", T_UINT, OFF(record.gain) },
|
||||
{ "i_port", T_UINT, OFF(record.port) },
|
||||
{ "i_samples", T_UINT, OFF(record.samples) },
|
||||
{ "i_eof", T_UINT, OFF(record.eof) },
|
||||
{ "i_pause", T_UBYTE, OFF(record.pause) },
|
||||
{ "i_error", T_UBYTE, OFF(record.error) },
|
||||
{ "i_waiting", T_UBYTE, OFF(record.waiting) },
|
||||
{ "i_open", T_UBYTE, OFF(record.open) , RO},
|
||||
{ "i_active", T_UBYTE, OFF(record.active) , RO},
|
||||
#ifdef SOLARIS
|
||||
{ "i_buffer_size", T_UINT, OFF(record.buffer_size) },
|
||||
{ "i_balance", T_UBYTE, OFF(record.balance) },
|
||||
{ "i_avail_ports", T_UINT, OFF(record.avail_ports) },
|
||||
#endif
|
||||
|
||||
{ "o_sample_rate", T_UINT, OFF(play.sample_rate) },
|
||||
{ "o_channels", T_UINT, OFF(play.channels) },
|
||||
{ "o_precision", T_UINT, OFF(play.precision) },
|
||||
{ "o_encoding", T_UINT, OFF(play.encoding) },
|
||||
{ "o_gain", T_UINT, OFF(play.gain) },
|
||||
{ "o_port", T_UINT, OFF(play.port) },
|
||||
{ "o_samples", T_UINT, OFF(play.samples) },
|
||||
{ "o_eof", T_UINT, OFF(play.eof) },
|
||||
{ "o_pause", T_UBYTE, OFF(play.pause) },
|
||||
{ "o_error", T_UBYTE, OFF(play.error) },
|
||||
{ "o_waiting", T_UBYTE, OFF(play.waiting) },
|
||||
{ "o_open", T_UBYTE, OFF(play.open) , RO},
|
||||
{ "o_active", T_UBYTE, OFF(play.active) , RO},
|
||||
#ifdef SOLARIS
|
||||
{ "o_buffer_size", T_UINT, OFF(play.buffer_size) },
|
||||
{ "o_balance", T_UBYTE, OFF(play.balance) },
|
||||
{ "o_avail_ports", T_UINT, OFF(play.avail_ports) },
|
||||
#endif
|
||||
|
||||
{ "monitor_gain", T_UINT, OFF(monitor_gain) },
|
||||
{ NULL, 0, 0},
|
||||
};
|
||||
|
||||
static PyObject *
|
||||
sads_getattr(sadstatusobject *xp, char *name)
|
||||
{
|
||||
return PyMember_Get((char *)&xp->ai, sads_ml, name);
|
||||
}
|
||||
|
||||
static int
|
||||
sads_setattr(sadstatusobject *xp, char *name, PyObject *v)
|
||||
{
|
||||
|
||||
if (v == NULL) {
|
||||
PyErr_SetString(PyExc_TypeError,
|
||||
"can't delete sun audio status attributes");
|
||||
return -1;
|
||||
}
|
||||
return PyMember_Set((char *)&xp->ai, sads_ml, name, v);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
|
||||
static PyTypeObject Sadtype = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"sunaudiodev.sun_audio_device", /*tp_name*/
|
||||
sizeof(sadobject), /*tp_size*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)sad_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
(getattrfunc)sad_getattr, /*tp_getattr*/
|
||||
0, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
};
|
||||
|
||||
static PyTypeObject Sadstatustype = {
|
||||
PyVarObject_HEAD_INIT(&PyType_Type, 0)
|
||||
"sunaudiodev.sun_audio_device_status", /*tp_name*/
|
||||
sizeof(sadstatusobject), /*tp_size*/
|
||||
0, /*tp_itemsize*/
|
||||
/* methods */
|
||||
(destructor)sads_dealloc, /*tp_dealloc*/
|
||||
0, /*tp_print*/
|
||||
(getattrfunc)sads_getattr, /*tp_getattr*/
|
||||
(setattrfunc)sads_setattr, /*tp_setattr*/
|
||||
0, /*tp_compare*/
|
||||
0, /*tp_repr*/
|
||||
};
|
||||
/* ------------------------------------------------------------------- */
|
||||
|
||||
static PyObject *
|
||||
sadopen(PyObject *self, PyObject *args)
|
||||
{
|
||||
return (PyObject *)newsadobject(args);
|
||||
}
|
||||
|
||||
static PyMethodDef sunaudiodev_methods[] = {
|
||||
{ "open", sadopen, METH_VARARGS },
|
||||
{ 0, 0 },
|
||||
};
|
||||
|
||||
void
|
||||
initsunaudiodev(void)
|
||||
{
|
||||
PyObject *m, *d;
|
||||
|
||||
m = Py_InitModule("sunaudiodev", sunaudiodev_methods);
|
||||
if (m == NULL)
|
||||
return;
|
||||
d = PyModule_GetDict(m);
|
||||
SunAudioError = PyErr_NewException("sunaudiodev.error", NULL, NULL);
|
||||
if (SunAudioError)
|
||||
PyDict_SetItemString(d, "error", SunAudioError);
|
||||
}
|
|
@ -15,11 +15,11 @@
|
|||
#define OFF(x) offsetof(PyFrameObject, x)
|
||||
|
||||
static PyMemberDef frame_memberlist[] = {
|
||||
{"f_back", T_OBJECT, OFF(f_back), RO},
|
||||
{"f_code", T_OBJECT, OFF(f_code), RO},
|
||||
{"f_builtins", T_OBJECT, OFF(f_builtins),RO},
|
||||
{"f_globals", T_OBJECT, OFF(f_globals), RO},
|
||||
{"f_lasti", T_INT, OFF(f_lasti), RO},
|
||||
{"f_back", T_OBJECT, OFF(f_back), READONLY},
|
||||
{"f_code", T_OBJECT, OFF(f_code), READONLY},
|
||||
{"f_builtins", T_OBJECT, OFF(f_builtins),READONLY},
|
||||
{"f_globals", T_OBJECT, OFF(f_globals), READONLY},
|
||||
{"f_lasti", T_INT, OFF(f_lasti), READONLY},
|
||||
{"f_exc_type", T_OBJECT, OFF(f_exc_type)},
|
||||
{"f_exc_value", T_OBJECT, OFF(f_exc_value)},
|
||||
{"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)},
|
||||
|
|
|
@ -282,8 +282,8 @@ gen_iternext(PyGenObject *gen)
|
|||
|
||||
|
||||
static PyMemberDef gen_memberlist[] = {
|
||||
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), RO},
|
||||
{"gi_running", T_INT, offsetof(PyGenObject, gi_running), RO},
|
||||
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
|
||||
{"gi_running", T_INT, offsetof(PyGenObject, gi_running), READONLY},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
|
|
|
@ -856,20 +856,6 @@ structmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
|
|||
$(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
|
||||
$(PY_INCLUDE)\tupleobject.h
|
||||
|
||||
sunaudiodev.obj: $(PY_INCLUDE)\abstract.h $(OS2TCPIP)\Include\sys\ioctl.h $(PY_INCLUDE)\ceval.h \
|
||||
$(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
|
||||
pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
|
||||
$(PY_INCLUDE)\floatobject.h $(PY_INCLUDE)\funcobject.h $(PY_INCLUDE)\import.h \
|
||||
$(PY_INCLUDE)\intobject.h $(PY_INCLUDE)\intrcheck.h $(PY_INCLUDE)\listobject.h \
|
||||
$(PY_INCLUDE)\longobject.h $(PY_INCLUDE)\methodobject.h \
|
||||
$(PY_INCLUDE)\modsupport.h $(PY_INCLUDE)\moduleobject.h $(PY_INCLUDE)\mymalloc.h \
|
||||
$(PY_INCLUDE)\myproto.h $(PY_INCLUDE)\object.h $(PY_INCLUDE)\objimpl.h \
|
||||
$(PY_INCLUDE)\pydebug.h $(PY_INCLUDE)\pyerrors.h $(PY_INCLUDE)\pyfpe.h \
|
||||
$(PY_INCLUDE)\pystate.h $(PY_INCLUDE)\python.h $(PY_INCLUDE)\pythonrun.h \
|
||||
$(PY_INCLUDE)\rangeobject.h $(PY_INCLUDE)\sliceobject.h \
|
||||
$(PY_INCLUDE)\stringobject.h $(PY_INCLUDE)\structmember.h \
|
||||
$(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h $(PY_INCLUDE)\tupleobject.h
|
||||
|
||||
syslogmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
|
||||
$(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
|
||||
pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
|
||||
|
|
|
@ -171,8 +171,6 @@ MODULES = \
|
|||
#
|
||||
# Multimedia:
|
||||
# audioop.c -- Various Compute Operations on Audio Samples
|
||||
# imageop.c -- Various Compute Operations on Video Samples
|
||||
# sunaudiodev.c -- Wrapper of Sun Audio Device API
|
||||
|
||||
# Database:
|
||||
# dbmmodule.c -- Wrapper of DBM Database API (Generic Flavor)
|
||||
|
@ -627,15 +625,6 @@ structmodule.obj: abstract.h ceval.h classobject.h cobject.h \
|
|||
pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
|
||||
stringobject.h sysmodule.h traceback.h tupleobject.h
|
||||
|
||||
sunaudiodev.obj: abstract.h c:\mptn\include\sys\ioctl.h ceval.h \
|
||||
classobject.h cobject.h complexobject.h pyconfig.h dictobject.h \
|
||||
fileobject.h floatobject.h funcobject.h import.h intobject.h \
|
||||
intrcheck.h listobject.h longobject.h methodobject.h modsupport.h \
|
||||
moduleobject.h mymalloc.h myproto.h object.h objimpl.h pydebug.h \
|
||||
pyerrors.h pyfpe.h pystate.h python.h pythonrun.h rangeobject.h \
|
||||
sliceobject.h stringobject.h structmember.h sysmodule.h \
|
||||
traceback.h tupleobject.h
|
||||
|
||||
syslogmodule.obj: abstract.h ceval.h classobject.h cobject.h \
|
||||
complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
|
||||
funcobject.h import.h intobject.h intrcheck.h listobject.h \
|
||||
|
|
|
@ -1471,10 +1471,10 @@ symtable_visit_alias(struct symtable *st, alias_ty a)
|
|||
else {
|
||||
if (st->st_cur->ste_type != ModuleBlock) {
|
||||
int lineno = st->st_cur->ste_lineno;
|
||||
if (!symtable_warn(st, IMPORT_STAR_WARNING, lineno)) {
|
||||
Py_DECREF(store_name);
|
||||
return 0;
|
||||
}
|
||||
PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING);
|
||||
PyErr_SyntaxLocation(st->st_filename, lineno);
|
||||
Py_DECREF(store_name);
|
||||
return 0;
|
||||
}
|
||||
st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR;
|
||||
Py_DECREF(store_name);
|
||||
|
|
|
@ -1,112 +0,0 @@
|
|||
audiopy - a program to control the Solaris audio device.
|
||||
|
||||
Contact: Barry Warsaw
|
||||
Email: bwarsaw@python.org
|
||||
Version: 1.1
|
||||
|
||||
Introduction
|
||||
|
||||
Audiopy is a program to control the Solaris audio device, allowing
|
||||
you to choose both the input and output devices, and to set the
|
||||
output volume. It can be run either as a standalone command-line
|
||||
script, or as a Tkinter based GUI application.
|
||||
|
||||
Note that your version of Python must have been built with the
|
||||
sunaudiodev module enabled. It is not enabled by default however!
|
||||
You will need to edit your Modules/Setup file, uncomment the
|
||||
sunaudiodev module spec line and rebuild Python.
|
||||
|
||||
Using audiopy, you can select one of three possible input devices:
|
||||
the microphone, the line-in jack, or the CD in. These choices are
|
||||
mutually exclusive; you can only have one active input device at
|
||||
any one time (this is enforced by the underlying device). Some
|
||||
input devices may not be supported on all Solaris machines.
|
||||
|
||||
You can also choose to enable any of the three possible output
|
||||
devices: the headphone jack, the speakers, or the line-out jack.
|
||||
You can enable any combination of these three devices.
|
||||
|
||||
You can also set the output gain (volume) level.
|
||||
|
||||
Running as a GUI
|
||||
|
||||
Simply start audiopy with no arguments to start it as a Tkinter
|
||||
based GUI application. It will pop up a window with two sections:
|
||||
the top portion contains three radio buttons indicating your
|
||||
selected input device; the middle portion contains three
|
||||
checkboxes indicating your selected output devices; the bottom
|
||||
portion contains a slider that changes the output gain.
|
||||
|
||||
Note the underlined characters in the button labels. These
|
||||
indicate keyboard accelerators so that pressing Alt+character you
|
||||
can select that device. For example, Alt-s toggles the Speaker
|
||||
device. The Alt accelerators are the same as those you'd use in
|
||||
as the short-form command line switches (see below).
|
||||
|
||||
Alt-q is also an accelerator for selecting Quit from the File
|
||||
menu.
|
||||
|
||||
Unsupported devices will appear dimmed out in the GUI. When run
|
||||
as a GUI, audiopy monitors the audio device and automatically
|
||||
updates its display if the state of the device is changed by some
|
||||
other means. With Python versions before 1.5.2 this is done by
|
||||
occasionally polling the device, but in Python 1.5.2 no polling is
|
||||
necessary (you don't really need to know this, but I thought I'd
|
||||
plug 1.5.2 :-).
|
||||
|
||||
Running as a Command Line Program
|
||||
|
||||
You can run audiopy from the command line to select any
|
||||
combination of input or output device, by using the command line
|
||||
options. Actually, any option forces audiopy to run as a command
|
||||
line program and not display its GUI.
|
||||
|
||||
Options have the general form
|
||||
|
||||
--device[={0,1}]
|
||||
-d[-{0,1}]
|
||||
|
||||
meaning there is both a long-form and short-form of the switch,
|
||||
where `device' or `d' is one of the following:
|
||||
|
||||
(input)
|
||||
microphone -- m
|
||||
linein -- i
|
||||
cd -- c
|
||||
|
||||
(output)
|
||||
headphones -- p
|
||||
speaker -- s
|
||||
lineout -- o
|
||||
|
||||
When no value is given, the switch just toggles the specified
|
||||
device. With a value, 0 turns the device off and 1 turns the
|
||||
device on. Any other value is an error.
|
||||
|
||||
For example, to turn the speakers off, turn the headphones on, and
|
||||
toggle the cd input device, run audiopy from the command line like
|
||||
so:
|
||||
|
||||
% ./audiopy -s=0 -p=1 -c
|
||||
|
||||
Audiopy understands these other command line options:
|
||||
|
||||
--gain volume
|
||||
-g volume
|
||||
Sets the output volume to the specified gain level. This must
|
||||
be an integer between MIN_GAIN and MAX_GAIN (usually [0..255],
|
||||
but use the -h option to find the exact values).
|
||||
|
||||
--version
|
||||
-v
|
||||
Print the version number and exit
|
||||
|
||||
--help
|
||||
-h
|
||||
Print a help message and exit
|
||||
|
||||
|
||||
|
||||
Local Variables:
|
||||
indent-tabs-mode: nil
|
||||
End:
|
|
@ -1,508 +0,0 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
"""audiopy -- a program to control the Solaris audio device.
|
||||
|
||||
Contact: Barry Warsaw
|
||||
Email: bwarsaw@python.org
|
||||
Version: %(__version__)s
|
||||
|
||||
When no arguments are given, this pops up a graphical window which lets you
|
||||
choose the audio input and output devices, and set the output volume.
|
||||
|
||||
This program can be driven via the command line, and when done so, no window
|
||||
pops up. Most options have the general form:
|
||||
|
||||
--device[={0,1}]
|
||||
-d[={0,1}]
|
||||
Set the I/O device. With no value, it toggles the specified device.
|
||||
With a value, 0 turns the device off and 1 turns the device on.
|
||||
|
||||
The list of devices and their short options are:
|
||||
|
||||
(input)
|
||||
microphone -- m
|
||||
linein -- i
|
||||
cd -- c
|
||||
|
||||
(output)
|
||||
headphones -- p
|
||||
speaker -- s
|
||||
lineout -- o
|
||||
|
||||
Other options are:
|
||||
|
||||
--gain volume
|
||||
-g volume
|
||||
Sets the output gain to the specified volume, which must be an integer
|
||||
in the range [%(MIN_GAIN)s..%(MAX_GAIN)s]
|
||||
|
||||
--version
|
||||
-v
|
||||
Print the version number and exit.
|
||||
|
||||
--help
|
||||
-h
|
||||
Print this message and exit.
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import errno
|
||||
import sunaudiodev
|
||||
from SUNAUDIODEV import *
|
||||
|
||||
# Milliseconds between interrupt checks
|
||||
KEEPALIVE_TIMER = 500
|
||||
|
||||
__version__ = '1.1'
|
||||
|
||||
|
||||
|
||||
class MainWindow:
|
||||
def __init__(self, device):
|
||||
from Tkinter import *
|
||||
self.__helpwin = None
|
||||
self.__devctl = device
|
||||
info = device.getinfo()
|
||||
#
|
||||
self.__tkroot = tkroot = Tk(className='Audiopy')
|
||||
tkroot.withdraw()
|
||||
# create the menubar
|
||||
menubar = Menu(tkroot)
|
||||
filemenu = Menu(menubar, tearoff=0)
|
||||
filemenu.add_command(label='Quit',
|
||||
command=self.__quit,
|
||||
accelerator='Alt-Q',
|
||||
underline=0)
|
||||
helpmenu = Menu(menubar, name='help', tearoff=0)
|
||||
helpmenu.add_command(label='About Audiopy...',
|
||||
command=self.__popup_about,
|
||||
underline=0)
|
||||
helpmenu.add_command(label='Help...',
|
||||
command=self.__popup_using,
|
||||
underline=0)
|
||||
menubar.add_cascade(label='File',
|
||||
menu=filemenu,
|
||||
underline=0)
|
||||
menubar.add_cascade(label='Help',
|
||||
menu=helpmenu,
|
||||
underline=0)
|
||||
# now create the top level window
|
||||
root = self.__root = Toplevel(tkroot, class_='Audiopy', menu=menubar)
|
||||
root.protocol('WM_DELETE_WINDOW', self.__quit)
|
||||
root.title('audiopy ' + __version__)
|
||||
root.iconname('audiopy ' + __version__)
|
||||
root.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive)
|
||||
#
|
||||
buttons = []
|
||||
#
|
||||
# where does input come from?
|
||||
frame = Frame(root, bd=1, relief=RAISED)
|
||||
frame.grid(row=1, column=0, sticky='NSEW')
|
||||
label = Label(frame, text='Input From:')
|
||||
label.grid(row=0, column=0, sticky=E)
|
||||
self.__inputvar = IntVar()
|
||||
##
|
||||
btn = Radiobutton(frame,
|
||||
text='None',
|
||||
variable=self.__inputvar,
|
||||
value=0,
|
||||
command=self.__pushtodev,
|
||||
underline=0)
|
||||
btn.grid(row=0, column=1, sticky=W)
|
||||
root.bind('<Alt-n>', self.__none)
|
||||
root.bind('<Alt-N>', self.__none)
|
||||
if not info.i_avail_ports & MICROPHONE:
|
||||
btn.configure(state=DISABLED)
|
||||
buttons.append(btn)
|
||||
##
|
||||
btn = Radiobutton(frame,
|
||||
text='Microphone',
|
||||
variable=self.__inputvar,
|
||||
value=MICROPHONE,
|
||||
command=self.__pushtodev,
|
||||
underline=0)
|
||||
btn.grid(row=1, column=1, sticky=W)
|
||||
root.bind('<Alt-m>', self.__mic)
|
||||
root.bind('<Alt-M>', self.__mic)
|
||||
if not info.i_avail_ports & MICROPHONE:
|
||||
btn.configure(state=DISABLED)
|
||||
buttons.append(btn)
|
||||
##
|
||||
btn = Radiobutton(frame,
|
||||
text='Line In',
|
||||
variable=self.__inputvar,
|
||||
value=LINE_IN,
|
||||
command=self.__pushtodev,
|
||||
underline=5)
|
||||
btn.grid(row=2, column=1, sticky=W)
|
||||
root.bind('<Alt-i>', self.__linein)
|
||||
root.bind('<Alt-I>', self.__linein)
|
||||
if not info.i_avail_ports & LINE_IN:
|
||||
btn.configure(state=DISABLED)
|
||||
buttons.append(btn)
|
||||
## if SUNAUDIODEV was built on an older version of Solaris, the CD
|
||||
## input device won't exist
|
||||
try:
|
||||
btn = Radiobutton(frame,
|
||||
text='CD',
|
||||
variable=self.__inputvar,
|
||||
value=CD,
|
||||
command=self.__pushtodev,
|
||||
underline=0)
|
||||
btn.grid(row=3, column=1, sticky=W)
|
||||
root.bind('<Alt-c>', self.__cd)
|
||||
root.bind('<Alt-C>', self.__cd)
|
||||
if not info.i_avail_ports & CD:
|
||||
btn.configure(state=DISABLED)
|
||||
buttons.append(btn)
|
||||
except NameError:
|
||||
pass
|
||||
#
|
||||
# where does output go to?
|
||||
frame = Frame(root, bd=1, relief=RAISED)
|
||||
frame.grid(row=2, column=0, sticky='NSEW')
|
||||
label = Label(frame, text='Output To:')
|
||||
label.grid(row=0, column=0, sticky=E)
|
||||
self.__spkvar = IntVar()
|
||||
btn = Checkbutton(frame,
|
||||
text='Speaker',
|
||||
variable=self.__spkvar,
|
||||
onvalue=SPEAKER,
|
||||
command=self.__pushtodev,
|
||||
underline=0)
|
||||
btn.grid(row=0, column=1, sticky=W)
|
||||
root.bind('<Alt-s>', self.__speaker)
|
||||
root.bind('<Alt-S>', self.__speaker)
|
||||
if not info.o_avail_ports & SPEAKER:
|
||||
btn.configure(state=DISABLED)
|
||||
buttons.append(btn)
|
||||
##
|
||||
self.__headvar = IntVar()
|
||||
btn = Checkbutton(frame,
|
||||
text='Headphones',
|
||||
variable=self.__headvar,
|
||||
onvalue=HEADPHONE,
|
||||
command=self.__pushtodev,
|
||||
underline=4)
|
||||
btn.grid(row=1, column=1, sticky=W)
|
||||
root.bind('<Alt-p>', self.__headphones)
|
||||
root.bind('<Alt-P>', self.__headphones)
|
||||
if not info.o_avail_ports & HEADPHONE:
|
||||
btn.configure(state=DISABLED)
|
||||
buttons.append(btn)
|
||||
##
|
||||
self.__linevar = IntVar()
|
||||
btn = Checkbutton(frame,
|
||||
variable=self.__linevar,
|
||||
onvalue=LINE_OUT,
|
||||
text='Line Out',
|
||||
command=self.__pushtodev,
|
||||
underline=0)
|
||||
btn.grid(row=2, column=1, sticky=W)
|
||||
root.bind('<Alt-l>', self.__lineout)
|
||||
root.bind('<Alt-L>', self.__lineout)
|
||||
if not info.o_avail_ports & LINE_OUT:
|
||||
btn.configure(state=DISABLED)
|
||||
buttons.append(btn)
|
||||
#
|
||||
# Fix up widths
|
||||
widest = 0
|
||||
for b in buttons:
|
||||
width = b['width']
|
||||
if width > widest:
|
||||
widest = width
|
||||
for b in buttons:
|
||||
b.configure(width=widest)
|
||||
# root bindings
|
||||
root.bind('<Alt-q>', self.__quit)
|
||||
root.bind('<Alt-Q>', self.__quit)
|
||||
#
|
||||
# Volume
|
||||
frame = Frame(root, bd=1, relief=RAISED)
|
||||
frame.grid(row=3, column=0, sticky='NSEW')
|
||||
label = Label(frame, text='Output Volume:')
|
||||
label.grid(row=0, column=0, sticky=W)
|
||||
self.__scalevar = IntVar()
|
||||
self.__scale = Scale(frame,
|
||||
orient=HORIZONTAL,
|
||||
from_=MIN_GAIN,
|
||||
to=MAX_GAIN,
|
||||
length=200,
|
||||
variable=self.__scalevar,
|
||||
command=self.__volume)
|
||||
self.__scale.grid(row=1, column=0, sticky=EW)
|
||||
#
|
||||
# do we need to poll for changes?
|
||||
self.__needtopoll = 1
|
||||
try:
|
||||
fd = self.__devctl.fileno()
|
||||
self.__needtopoll = 0
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
import fcntl
|
||||
import signal
|
||||
import STROPTS
|
||||
# set up the signal handler
|
||||
signal.signal(signal.SIGPOLL, self.__update)
|
||||
fcntl.ioctl(fd, STROPTS.I_SETSIG, STROPTS.S_MSG)
|
||||
self.__update()
|
||||
|
||||
def __quit(self, event=None):
|
||||
self.__devctl.close()
|
||||
self.__root.quit()
|
||||
|
||||
def __popup_about(self, event=None):
|
||||
import tkMessageBox
|
||||
tkMessageBox.showinfo('About Audiopy ' + __version__,
|
||||
'''\
|
||||
Audiopy %s
|
||||
Control the Solaris audio device
|
||||
|
||||
For information
|
||||
Contact: Barry A. Warsaw
|
||||
Email: bwarsaw@python.org''' % __version__)
|
||||
|
||||
def __popup_using(self, event=None):
|
||||
if not self.__helpwin:
|
||||
self.__helpwin = Helpwin(self.__tkroot, self.__quit)
|
||||
self.__helpwin.deiconify()
|
||||
|
||||
|
||||
def __keepalive(self):
|
||||
# Exercise the Python interpreter regularly so keyboard interrupts get
|
||||
# through.
|
||||
self.__tkroot.tk.createtimerhandler(KEEPALIVE_TIMER, self.__keepalive)
|
||||
if self.__needtopoll:
|
||||
self.__update()
|
||||
|
||||
def __update(self, num=None, frame=None):
|
||||
# It's possible (although I have never seen it) to get an interrupted
|
||||
# system call during the getinfo() call. If so, and we're polling,
|
||||
# don't sweat it because we'll come around again later. Otherwise,
|
||||
# we'll give it a couple of tries and then give up until next time.
|
||||
tries = 0
|
||||
while 1:
|
||||
try:
|
||||
info = self.__devctl.getinfo()
|
||||
break
|
||||
except sunaudiodev.error:
|
||||
if self.__needtopoll or tries > 3:
|
||||
return
|
||||
tries = tries + 1
|
||||
# input
|
||||
self.__inputvar.set(info.i_port)
|
||||
# output
|
||||
self.__spkvar.set(info.o_port & SPEAKER)
|
||||
self.__headvar.set(info.o_port & HEADPHONE)
|
||||
self.__linevar.set(info.o_port & LINE_OUT)
|
||||
# volume
|
||||
self.__scalevar.set(info.o_gain)
|
||||
|
||||
def __pushtodev(self, event=None):
|
||||
info = self.__devctl.getinfo()
|
||||
info.o_port = self.__spkvar.get() + \
|
||||
self.__headvar.get() + \
|
||||
self.__linevar.get()
|
||||
info.i_port = self.__inputvar.get()
|
||||
info.o_gain = self.__scalevar.get()
|
||||
try:
|
||||
self.__devctl.setinfo(info)
|
||||
except sunaudiodev.error as msg:
|
||||
# TBD: what to do? it's probably temporary.
|
||||
pass
|
||||
|
||||
def __getset(self, var, onvalue):
|
||||
if var.get() == onvalue:
|
||||
var.set(0)
|
||||
else:
|
||||
var.set(onvalue)
|
||||
self.__pushtodev()
|
||||
|
||||
def __none(self, event=None):
|
||||
self.__inputvar.set(0)
|
||||
self.__pushtodev()
|
||||
|
||||
def __mic(self, event=None):
|
||||
self.__getset(self.__inputvar, MICROPHONE)
|
||||
|
||||
def __linein(self, event=None):
|
||||
self.__getset(self.__inputvar, LINE_IN)
|
||||
|
||||
def __cd(self, event=None):
|
||||
self.__getset(self.__inputvar, CD)
|
||||
|
||||
def __speaker(self, event=None):
|
||||
self.__getset(self.__spkvar, SPEAKER)
|
||||
|
||||
def __headphones(self, event=None):
|
||||
self.__getset(self.__headvar, HEADPHONE)
|
||||
|
||||
def __lineout(self, event=None):
|
||||
self.__getset(self.__linevar, LINE_OUT)
|
||||
|
||||
def __volume(self, event=None):
|
||||
self.__pushtodev()
|
||||
|
||||
def start(self):
|
||||
self.__keepalive()
|
||||
self.__tkroot.mainloop()
|
||||
|
||||
|
||||
|
||||
class Helpwin:
|
||||
def __init__(self, master, quitfunc):
|
||||
from Tkinter import *
|
||||
self.__root = root = Toplevel(master, class_='Audiopy')
|
||||
root.protocol('WM_DELETE_WINDOW', self.__withdraw)
|
||||
root.title('Audiopy Help Window')
|
||||
root.iconname('Audiopy Help Window')
|
||||
root.bind('<Alt-q>', quitfunc)
|
||||
root.bind('<Alt-Q>', quitfunc)
|
||||
root.bind('<Alt-w>', self.__withdraw)
|
||||
root.bind('<Alt-W>', self.__withdraw)
|
||||
|
||||
# more elaborate help is available in the README file
|
||||
readmefile = os.path.join(sys.path[0], 'README')
|
||||
try:
|
||||
fp = None
|
||||
try:
|
||||
fp = open(readmefile)
|
||||
contents = fp.read()
|
||||
# wax the last page, it contains Emacs cruft
|
||||
i = contents.rfind('\f')
|
||||
if i > 0:
|
||||
contents = contents[:i].rstrip()
|
||||
finally:
|
||||
if fp:
|
||||
fp.close()
|
||||
except IOError:
|
||||
sys.stderr.write("Couldn't open audiopy's README, "
|
||||
'using docstring instead.\n')
|
||||
contents = __doc__ % globals()
|
||||
|
||||
self.__text = text = Text(root, relief=SUNKEN,
|
||||
width=80, height=24)
|
||||
text.insert(0.0, contents)
|
||||
scrollbar = Scrollbar(root)
|
||||
scrollbar.pack(fill=Y, side=RIGHT)
|
||||
text.pack(fill=BOTH, expand=YES)
|
||||
text.configure(yscrollcommand=(scrollbar, 'set'))
|
||||
scrollbar.configure(command=(text, 'yview'))
|
||||
|
||||
def __withdraw(self, event=None):
|
||||
self.__root.withdraw()
|
||||
|
||||
def deiconify(self):
|
||||
self.__root.deiconify()
|
||||
|
||||
|
||||
|
||||
|
||||
def usage(code, msg=''):
|
||||
print(__doc__ % globals())
|
||||
if msg:
|
||||
print(msg)
|
||||
sys.exit(code)
|
||||
|
||||
|
||||
def main():
|
||||
#
|
||||
# Open up the audio control device and query for the current output
|
||||
# device
|
||||
device = sunaudiodev.open('control')
|
||||
|
||||
if len(sys.argv) == 1:
|
||||
# GUI
|
||||
w = MainWindow(device)
|
||||
try:
|
||||
w.start()
|
||||
except KeyboardInterrupt:
|
||||
pass
|
||||
return
|
||||
|
||||
# spec: LONG OPT, SHORT OPT, 0=input,1=output, MASK
|
||||
options = [('--microphone', '-m', 0, MICROPHONE),
|
||||
('--linein', '-i', 0, LINE_IN),
|
||||
('--headphones', '-p', 1, HEADPHONE),
|
||||
('--speaker', '-s', 1, SPEAKER),
|
||||
('--lineout', '-o', 1, LINE_OUT),
|
||||
]
|
||||
# See the comment above about `CD'
|
||||
try:
|
||||
options.append(('--cd', '-c', 0, CD))
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
info = device.getinfo()
|
||||
# first get the existing values
|
||||
i = 0
|
||||
while i < len(sys.argv)-1:
|
||||
i = i + 1
|
||||
arg = sys.argv[i]
|
||||
if arg in ('-h', '--help'):
|
||||
usage(0)
|
||||
# does not return
|
||||
elif arg in ('-g', '--gain'):
|
||||
gainspec = '<missing>'
|
||||
try:
|
||||
gainspec = sys.argv[i+1]
|
||||
gain = int(gainspec)
|
||||
except (ValueError, IndexError):
|
||||
usage(1, 'Bad gain specification: ' + gainspec)
|
||||
info.o_gain = gain
|
||||
i = i + 1
|
||||
continue
|
||||
elif arg in ('-v', '--version'):
|
||||
print('''\
|
||||
audiopy -- a program to control the Solaris audio device.
|
||||
Contact: Barry Warsaw
|
||||
Email: bwarsaw@python.org
|
||||
Version: %s''' % __version__)
|
||||
sys.exit(0)
|
||||
for long, short, io, mask in options:
|
||||
if arg in (long, short):
|
||||
# toggle the option
|
||||
if io == 0:
|
||||
info.i_port = info.i_port ^ mask
|
||||
else:
|
||||
info.o_port = info.o_port ^ mask
|
||||
break
|
||||
val = None
|
||||
try:
|
||||
if arg[:len(long)+1] == long+'=':
|
||||
val = int(arg[len(long)+1:])
|
||||
elif arg[:len(short)+1] == short+'=':
|
||||
val = int(arg[len(short)+1:])
|
||||
except ValueError:
|
||||
usage(1, msg='Invalid option: ' + arg)
|
||||
# does not return
|
||||
if val == 0:
|
||||
if io == 0:
|
||||
info.i_port = info.i_port & ~mask
|
||||
else:
|
||||
info.o_port = info.o_port & ~mask
|
||||
break
|
||||
elif val == 1:
|
||||
if io == 0:
|
||||
info.i_port = info.i_port | mask
|
||||
else:
|
||||
info.o_port = info.o_port | mask
|
||||
break
|
||||
# else keep trying next option
|
||||
else:
|
||||
usage(1, msg='Invalid option: ' + arg)
|
||||
# now set the values
|
||||
try:
|
||||
device.setinfo(info)
|
||||
except sunaudiodev.error as e:
|
||||
(code, msg) = e
|
||||
if code <> errno.EINVAL:
|
||||
raise
|
||||
device.close()
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
12
setup.py
12
setup.py
|
@ -1074,24 +1074,12 @@ class db_found(Exception): pass
|
|||
exts.append(Extension('_fileio', ['_fileio.c']))
|
||||
|
||||
# Platform-specific libraries
|
||||
if platform == 'linux2':
|
||||
# Linux-specific modules
|
||||
exts.append( Extension('linuxaudiodev', ['linuxaudiodev.c']) )
|
||||
else:
|
||||
missing.append('linuxaudiodev')
|
||||
|
||||
if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
|
||||
'freebsd7'):
|
||||
exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
|
||||
else:
|
||||
missing.append('ossaudiodev')
|
||||
|
||||
if platform == 'sunos5':
|
||||
# SunOS specific modules
|
||||
exts.append( Extension('sunaudiodev', ['sunaudiodev.c']) )
|
||||
else:
|
||||
missing.append('sunaudiodev')
|
||||
|
||||
if platform == 'darwin' and ("--disable-toolbox-glue" not in
|
||||
sysconfig.get_config_var("CONFIG_ARGS")):
|
||||
|
||||
|
|
Loading…
Reference in a new issue