mirror of
https://github.com/python/cpython
synced 2024-09-18 20:21:42 +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/libcrypto.tex \
|
||||||
lib/libhashlib.tex \
|
lib/libhashlib.tex \
|
||||||
lib/libhmac.tex \
|
lib/libhmac.tex \
|
||||||
lib/libsun.tex \
|
|
||||||
lib/libxdrlib.tex \
|
lib/libxdrlib.tex \
|
||||||
lib/libimghdr.tex \
|
lib/libimghdr.tex \
|
||||||
lib/libformatter.tex \
|
lib/libformatter.tex \
|
||||||
|
@ -259,7 +258,6 @@ LIBFILES= $(MANSTYLES) $(INDEXSTYLES) $(COMMONTEX) \
|
||||||
lib/libsymbol.tex \
|
lib/libsymbol.tex \
|
||||||
lib/libbinhex.tex \
|
lib/libbinhex.tex \
|
||||||
lib/libuu.tex \
|
lib/libuu.tex \
|
||||||
lib/libsunaudio.tex \
|
|
||||||
lib/libfileinput.tex \
|
lib/libfileinput.tex \
|
||||||
lib/libimaplib.tex \
|
lib/libimaplib.tex \
|
||||||
lib/libpoplib.tex \
|
lib/libpoplib.tex \
|
||||||
|
|
|
@ -416,10 +416,6 @@ and how to embed it in other applications.
|
||||||
% OTHER PLATFORM-SPECIFIC STUFF
|
% 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{windows} % MS Windows ONLY
|
||||||
\input{libmsilib}
|
\input{libmsilib}
|
||||||
\input{libmsvcrt}
|
\input{libmsvcrt}
|
||||||
|
@ -430,9 +426,6 @@ and how to embed it in other applications.
|
||||||
\input{libundoc}
|
\input{libundoc}
|
||||||
|
|
||||||
%\chapter{Obsolete Modules}
|
%\chapter{Obsolete Modules}
|
||||||
%\input{libcmpcache}
|
|
||||||
%\input{libcmp}
|
|
||||||
%\input{libni}
|
|
||||||
|
|
||||||
\chapter{Reporting Bugs}
|
\chapter{Reporting Bugs}
|
||||||
\input{reportingbugs}
|
\input{reportingbugs}
|
||||||
|
|
|
@ -7,9 +7,8 @@
|
||||||
|
|
||||||
The \module{audioop} module contains some useful operations on sound
|
The \module{audioop} module contains some useful operations on sound
|
||||||
fragments. It operates on sound fragments consisting of signed
|
fragments. It operates on sound fragments consisting of signed
|
||||||
integer samples 8, 16 or 32 bits wide, stored in Python strings. This
|
integer samples 8, 16 or 32 bits wide, stored in Python strings.
|
||||||
is the same format as used by the \refmodule{al} and \refmodule{sunaudiodev}
|
All scalar items are integers, unless specified otherwise.
|
||||||
modules. All scalar items are integers, unless specified otherwise.
|
|
||||||
|
|
||||||
% This para is mostly here to provide an excuse for the index entries...
|
% 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.
|
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}
|
\section{Multimedia}
|
||||||
|
|
||||||
\begin{description}
|
\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}]
|
\item[\module{sunaudio}]
|
||||||
--- Interpret Sun audio headers (may become obsolete or a tool/demo).
|
--- 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}
|
\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:
|
if filename and type is SyntaxError:
|
||||||
# Work hard to stuff the correct filename in the exception
|
# Work hard to stuff the correct filename in the exception
|
||||||
try:
|
try:
|
||||||
msg, (dummy_filename, lineno, offset, line) = value
|
msg, (dummy_filename, lineno, offset, line) = value.args
|
||||||
except:
|
except ValueError:
|
||||||
# Not the format we expect; leave it alone
|
# Not the format we expect; leave it alone
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# Stuff in the right filename
|
# Stuff in the right filename
|
||||||
value = SyntaxError(msg, (filename, lineno, offset, line))
|
value = SyntaxError(msg, (filename, lineno, offset, line))
|
||||||
sys.last_value = value
|
sys.last_value = value
|
||||||
list = traceback.format_exception_only(type, value)
|
lines = traceback.format_exception_only(type, value)
|
||||||
map(self.write, list)
|
self.write(''.join(lines))
|
||||||
|
|
||||||
def showtraceback(self):
|
def showtraceback(self):
|
||||||
"""Display the exception that just occurred.
|
"""Display the exception that just occurred.
|
||||||
|
@ -137,13 +137,13 @@ def showtraceback(self):
|
||||||
sys.last_traceback = tb
|
sys.last_traceback = tb
|
||||||
tblist = traceback.extract_tb(tb)
|
tblist = traceback.extract_tb(tb)
|
||||||
del tblist[:1]
|
del tblist[:1]
|
||||||
list = traceback.format_list(tblist)
|
lines = traceback.format_list(tblist)
|
||||||
if list:
|
if lines:
|
||||||
list.insert(0, "Traceback (most recent call last):\n")
|
lines.insert(0, "Traceback (most recent call last):\n")
|
||||||
list[len(list):] = traceback.format_exception_only(type, value)
|
lines.extend(traceback.format_exception_only(type, value))
|
||||||
finally:
|
finally:
|
||||||
tblist = tb = None
|
tblist = tb = None
|
||||||
map(self.write, list)
|
self.write(''.join(lines))
|
||||||
|
|
||||||
def write(self, data):
|
def write(self, data):
|
||||||
"""Write a string.
|
"""Write a string.
|
||||||
|
@ -184,7 +184,7 @@ def resetbuffer(self):
|
||||||
def interact(self, banner=None):
|
def interact(self, banner=None):
|
||||||
"""Closely emulate the interactive Python console.
|
"""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
|
before the first interaction; by default it prints a banner
|
||||||
similar to the one printed by the real Python interpreter,
|
similar to the one printed by the real Python interpreter,
|
||||||
followed by the current class name in parentheses (so as not
|
followed by the current class name in parentheses (so as not
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import string
|
||||||
import imp
|
import imp
|
||||||
from itertools import count
|
from itertools import count
|
||||||
from Tkinter import *
|
from Tkinter import *
|
||||||
|
@ -602,6 +603,19 @@ def ResetColorizer(self):
|
||||||
theme = idleConf.GetOption('main','Theme','name')
|
theme = idleConf.GetOption('main','Theme','name')
|
||||||
self.text.config(idleConf.GetHighlight(theme, "normal"))
|
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):
|
def ResetFont(self):
|
||||||
"Update the text widgets' font if it is changed"
|
"Update the text widgets' font if it is changed"
|
||||||
# Called from configDialog.py
|
# Called from configDialog.py
|
||||||
|
@ -1004,6 +1018,8 @@ def set_tabwidth(self, newtabwidth):
|
||||||
"n" * newtabwidth)
|
"n" * newtabwidth)
|
||||||
text.configure(tabs=pixels)
|
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
|
# If ispythonsource and guess are true, guess a good value for
|
||||||
# indentwidth based on file content (if possible), and if
|
# indentwidth based on file content (if possible), and if
|
||||||
# indentwidth != tabwidth set usetabs false.
|
# indentwidth != tabwidth set usetabs false.
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import sys
|
import sys
|
||||||
import string
|
|
||||||
import getopt
|
import getopt
|
||||||
import re
|
import re
|
||||||
import socket
|
import socket
|
||||||
|
@ -35,7 +34,6 @@
|
||||||
from . import RemoteDebugger
|
from . import RemoteDebugger
|
||||||
from . import macosxSupport
|
from . import macosxSupport
|
||||||
|
|
||||||
IDENTCHARS = string.ascii_letters + string.digits + "_"
|
|
||||||
LOCALHOST = '127.0.0.1'
|
LOCALHOST = '127.0.0.1'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -624,47 +622,30 @@ def prepend_syspath(self, filename):
|
||||||
\n""" % (filename,))
|
\n""" % (filename,))
|
||||||
|
|
||||||
def showsyntaxerror(self, filename=None):
|
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
|
Color the offending position instead of printing it and pointing at it
|
||||||
with a caret.
|
with a caret.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
text = self.tkconsole.text
|
tkconsole = self.tkconsole
|
||||||
stuff = self.unpackerror()
|
text = tkconsole.text
|
||||||
if stuff:
|
text.tag_remove("ERROR", "1.0", "end")
|
||||||
msg, lineno, offset, line = stuff
|
type, value, tb = sys.exc_info()
|
||||||
|
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:
|
if lineno == 1:
|
||||||
pos = "iomark + %d chars" % (offset-1)
|
pos = "iomark + %d chars" % (offset-1)
|
||||||
else:
|
else:
|
||||||
pos = "iomark linestart + %d lines + %d chars" % \
|
pos = "iomark linestart + %d lines + %d chars" % \
|
||||||
(lineno-1, offset-1)
|
(lineno-1, offset-1)
|
||||||
text.tag_add("ERROR", pos)
|
tkconsole.colorize_syntax_error(text, pos)
|
||||||
text.see(pos)
|
tkconsole.resetoutput()
|
||||||
char = text.get(pos)
|
self.write("SyntaxError: %s\n" % msg)
|
||||||
if char and char in IDENTCHARS:
|
tkconsole.showprompt()
|
||||||
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):
|
|
||||||
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
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def showtraceback(self):
|
def showtraceback(self):
|
||||||
"Extend base class method to reset output properly"
|
"Extend base class method to reset output properly"
|
||||||
|
|
|
@ -23,12 +23,11 @@
|
||||||
import tabnanny
|
import tabnanny
|
||||||
import tokenize
|
import tokenize
|
||||||
import tkMessageBox
|
import tkMessageBox
|
||||||
|
from .EditorWindow import EditorWindow
|
||||||
from . import PyShell
|
from . import PyShell
|
||||||
|
|
||||||
from .configHandler import idleConf
|
from .configHandler import idleConf
|
||||||
|
|
||||||
IDENTCHARS = string.ascii_letters + string.digits + "_"
|
|
||||||
|
|
||||||
indent_message = """Error: Inconsistent indentation detected!
|
indent_message = """Error: Inconsistent indentation detected!
|
||||||
|
|
||||||
1) Your indentation is outright incorrect (easy to fix), OR
|
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()
|
self.shell = shell = self.flist.open_shell()
|
||||||
saved_stream = shell.get_warning_stream()
|
saved_stream = shell.get_warning_stream()
|
||||||
shell.set_warning_stream(shell.stderr)
|
shell.set_warning_stream(shell.stderr)
|
||||||
f = open(filename, 'r')
|
f = file(filename, 'r')
|
||||||
source = f.read()
|
source = f.read()
|
||||||
f.close()
|
f.close()
|
||||||
if '\r' in source:
|
if '\r' in source:
|
||||||
|
@ -91,40 +90,25 @@ def checksyntax(self, filename):
|
||||||
source = re.sub(r"\r", "\n", source)
|
source = re.sub(r"\r", "\n", source)
|
||||||
if source and source[-1] != '\n':
|
if source and source[-1] != '\n':
|
||||||
source = source + '\n'
|
source = source + '\n'
|
||||||
text = self.editwin.text
|
editwin = self.editwin
|
||||||
|
text = editwin.text
|
||||||
text.tag_remove("ERROR", "1.0", "end")
|
text.tag_remove("ERROR", "1.0", "end")
|
||||||
try:
|
|
||||||
try:
|
try:
|
||||||
# If successful, return the compiled code
|
# If successful, return the compiled code
|
||||||
return compile(source, filename, "exec")
|
return compile(source, filename, "exec")
|
||||||
except (SyntaxError, OverflowError) as err:
|
except (SyntaxError, OverflowError) as value:
|
||||||
try:
|
msg = value.msg or "<no detail available>"
|
||||||
msg, (errorfilename, lineno, offset, line) = err.args
|
lineno = value.lineno or 1
|
||||||
if not errorfilename:
|
offset = value.offset or 0
|
||||||
err.args = msg, (filename, lineno, offset, line)
|
if offset == 0:
|
||||||
err.filename = filename
|
lineno += 1 #mark end of offending line
|
||||||
self.colorize_syntax_error(msg, lineno, offset)
|
pos = "0.0 + %d lines + %d chars" % (lineno-1, offset-1)
|
||||||
except:
|
editwin.colorize_syntax_error(text, pos)
|
||||||
msg = str(err)
|
self.errorbox("SyntaxError", "%-20s" % msg)
|
||||||
self.errorbox("Syntax error",
|
|
||||||
"There's an error in your program:\n" + msg)
|
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
shell.set_warning_stream(saved_stream)
|
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):
|
def run_module_event(self, event):
|
||||||
"""Run the module after setting up the environment.
|
"""Run the module after setting up the environment.
|
||||||
|
|
||||||
|
@ -199,10 +183,10 @@ def ask_save_dialog(self):
|
||||||
icon=tkMessageBox.QUESTION,
|
icon=tkMessageBox.QUESTION,
|
||||||
type=tkMessageBox.OKCANCEL,
|
type=tkMessageBox.OKCANCEL,
|
||||||
default=tkMessageBox.OK,
|
default=tkMessageBox.OK,
|
||||||
master=self.editwin.text)
|
parent=self.editwin.text)
|
||||||
return mb.show()
|
return mb.show()
|
||||||
|
|
||||||
def errorbox(self, title, message):
|
def errorbox(self, title, message):
|
||||||
# XXX This should really be a function of EditorWindow...
|
# 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()
|
self.editwin.text.focus_set()
|
||||||
|
|
|
@ -149,7 +149,7 @@ def print_exception():
|
||||||
typ, val, tb = excinfo = sys.exc_info()
|
typ, val, tb = excinfo = sys.exc_info()
|
||||||
sys.last_type, sys.last_value, sys.last_traceback = excinfo
|
sys.last_type, sys.last_value, sys.last_traceback = excinfo
|
||||||
tbe = traceback.extract_tb(tb)
|
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",
|
exclude = ("run.py", "rpc.py", "threading.py", "Queue.py",
|
||||||
"RemoteDebugger.py", "bdb.py")
|
"RemoteDebugger.py", "bdb.py")
|
||||||
cleanup_traceback(tbe, exclude)
|
cleanup_traceback(tbe, exclude)
|
||||||
|
|
|
@ -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
|
* ``findfile(file)`` - you can call this function to locate a file
|
||||||
somewhere along sys.path or in the Lib/test tree - see
|
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
|
* ``fcmp(x,y)`` - you can call this function to compare two floating
|
||||||
point numbers when you expect them to only be approximately equal
|
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())
|
self.expected = set(s.split())
|
||||||
|
|
||||||
# expected to be skipped on every platform, even Linux
|
# expected to be skipped on every platform, even Linux
|
||||||
self.expected.add('test_linuxaudiodev')
|
|
||||||
|
|
||||||
if not os.path.supports_unicode_filenames:
|
if not os.path.supports_unicode_filenames:
|
||||||
self.expected.add('test_pep277')
|
self.expected.add('test_pep277')
|
||||||
|
|
||||||
|
@ -1134,7 +1132,6 @@ def __init__(self):
|
||||||
self.expected.add(skip)
|
self.expected.add(skip)
|
||||||
|
|
||||||
if sys.platform != 'sunos5':
|
if sys.platform != 'sunos5':
|
||||||
self.expected.add('test_sunaudiodev')
|
|
||||||
self.expected.add('test_nis')
|
self.expected.add('test_nis')
|
||||||
|
|
||||||
self.valid = True
|
self.valid = True
|
||||||
|
|
|
@ -39,7 +39,6 @@ def test_all(self):
|
||||||
self.check_all("StringIO")
|
self.check_all("StringIO")
|
||||||
self.check_all("UserString")
|
self.check_all("UserString")
|
||||||
self.check_all("aifc")
|
self.check_all("aifc")
|
||||||
self.check_all("audiodev")
|
|
||||||
self.check_all("base64")
|
self.check_all("base64")
|
||||||
self.check_all("bdb")
|
self.check_all("bdb")
|
||||||
self.check_all("binhex")
|
self.check_all("binhex")
|
||||||
|
@ -135,7 +134,6 @@ def test_all(self):
|
||||||
self.check_all("textwrap")
|
self.check_all("textwrap")
|
||||||
self.check_all("threading")
|
self.check_all("threading")
|
||||||
self.check_all("timeit")
|
self.check_all("timeit")
|
||||||
self.check_all("toaiff")
|
|
||||||
self.check_all("tokenize")
|
self.check_all("tokenize")
|
||||||
self.check_all("traceback")
|
self.check_all("traceback")
|
||||||
self.check_all("tty")
|
self.check_all("tty")
|
||||||
|
|
|
@ -733,14 +733,14 @@
|
||||||
... yield 1
|
... yield 1
|
||||||
Traceback (most recent call last):
|
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():
|
>>> def f():
|
||||||
... yield 1
|
... yield 1
|
||||||
... return 22
|
... return 22
|
||||||
Traceback (most recent call last):
|
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:
|
"return None" is not the same as "return" in a generator:
|
||||||
|
|
||||||
|
@ -749,7 +749,7 @@
|
||||||
... return None
|
... return None
|
||||||
Traceback (most recent call last):
|
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:
|
These are fine:
|
||||||
|
|
||||||
|
@ -878,7 +878,7 @@
|
||||||
... if 0:
|
... if 0:
|
||||||
... yield 2 # because it's a generator (line 10)
|
... yield 2 # because it's a generator (line 10)
|
||||||
Traceback (most recent call last):
|
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):
|
This one caused a crash (see SF bug 567538):
|
||||||
|
|
||||||
|
@ -1525,27 +1525,27 @@ def printsolution(self, x):
|
||||||
>>> f=lambda: (yield 1),(yield 2)
|
>>> f=lambda: (yield 1),(yield 2)
|
||||||
Traceback (most recent call last):
|
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
|
>>> def f(): return lambda x=(yield): 1
|
||||||
Traceback (most recent call last):
|
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
|
>>> def f(): x = yield = y
|
||||||
Traceback (most recent call last):
|
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
|
>>> def f(): (yield bar) = y
|
||||||
Traceback (most recent call last):
|
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
|
>>> def f(): (yield bar) += y
|
||||||
Traceback (most recent call last):
|
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:
|
Now check some throw() conditions:
|
||||||
|
|
|
@ -137,12 +137,12 @@
|
||||||
>>> (y for y in (1,2)) = 10
|
>>> (y for y in (1,2)) = 10
|
||||||
Traceback (most recent call last):
|
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
|
>>> (y for y in (1,2)) += 10
|
||||||
Traceback (most recent call last):
|
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 ############
|
########### 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?
|
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):
|
def testLambdas(self):
|
||||||
|
|
||||||
f1 = lambda x: lambda y: x + y
|
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 SimpleHTTPServer
|
||||||
import SimpleXMLRPCServer
|
import SimpleXMLRPCServer
|
||||||
import aifc
|
import aifc
|
||||||
import audiodev
|
|
||||||
import bdb
|
import bdb
|
||||||
import cgitb
|
import cgitb
|
||||||
import cmd
|
import cmd
|
||||||
|
@ -99,7 +98,6 @@
|
||||||
import tabnanny
|
import tabnanny
|
||||||
import telnetlib
|
import telnetlib
|
||||||
import timeit
|
import timeit
|
||||||
import toaiff
|
|
||||||
import token
|
import token
|
||||||
try:
|
try:
|
||||||
import tty # not available on Windows
|
import tty # not available on Windows
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
|
|
||||||
>>> None = 1
|
>>> None = 1
|
||||||
Traceback (most recent call last):
|
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
|
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
|
error to assign to the empty list? It will always raise some error at
|
||||||
|
@ -41,31 +41,31 @@
|
||||||
|
|
||||||
>>> () = 1
|
>>> () = 1
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
SyntaxError: can't assign to () (<doctest test.test_syntax[3]>, line 1)
|
SyntaxError: can't assign to ()
|
||||||
|
|
||||||
>>> f() = 1
|
>>> f() = 1
|
||||||
Traceback (most recent call last):
|
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()
|
>>> del f()
|
||||||
Traceback (most recent call last):
|
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
|
>>> a + 1 = 2
|
||||||
Traceback (most recent call last):
|
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
|
>>> (x for x in x) = 1
|
||||||
Traceback (most recent call last):
|
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
|
>>> 1 = 1
|
||||||
Traceback (most recent call last):
|
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
|
>>> "abc" = 1
|
||||||
Traceback (most recent call last):
|
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
|
>>> `1` = 1
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
|
@ -78,15 +78,15 @@
|
||||||
|
|
||||||
>>> (a, "b", c) = (1, 2, 3)
|
>>> (a, "b", c) = (1, 2, 3)
|
||||||
Traceback (most recent call last):
|
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]
|
>>> [a, b, c + 1] = [1, 2, 3]
|
||||||
Traceback (most recent call last):
|
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
|
>>> a if 1 else b = 1
|
||||||
Traceback (most recent call last):
|
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():
|
From compiler_complex_args():
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@
|
||||||
>>> def f(x, y=1, z):
|
>>> def f(x, y=1, z):
|
||||||
... pass
|
... pass
|
||||||
Traceback (most recent call last):
|
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):
|
>>> def f(x, None):
|
||||||
... pass
|
... pass
|
||||||
|
@ -136,7 +136,7 @@
|
||||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
>>> f(x for x in L, 1)
|
>>> f(x for x in L, 1)
|
||||||
Traceback (most recent call last):
|
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)
|
>>> f((x for x in L), 1)
|
||||||
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@
|
||||||
... i244, i245, i246, i247, i248, i249, i250, i251, i252,
|
... i244, i245, i246, i247, i248, i249, i250, i251, i252,
|
||||||
... i253, i254, i255)
|
... i253, i254, i255)
|
||||||
Traceback (most recent call last):
|
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,
|
The actual error cases counts positional arguments, keyword arguments,
|
||||||
and generator expression arguments separately. This test combines the
|
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,
|
... (x for x in i244), i245, i246, i247, i248, i249, i250, i251,
|
||||||
... i252=1, i253=1, i254=1, i255=1)
|
... i252=1, i253=1, i254=1, i255=1)
|
||||||
Traceback (most recent call last):
|
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)
|
>>> f(lambda x: x[0] = 3)
|
||||||
Traceback (most recent call last):
|
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
|
The grammar accepts any test (basically, any expression) in the
|
||||||
keyword slot of a call site. Test a few different options.
|
keyword slot of a call site. Test a few different options.
|
||||||
|
|
||||||
>>> f(x()=2)
|
>>> f(x()=2)
|
||||||
Traceback (most recent call last):
|
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)
|
>>> f(a or b=1)
|
||||||
Traceback (most recent call last):
|
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)
|
>>> f(x.y=1)
|
||||||
Traceback (most recent call last):
|
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():
|
From ast_for_expr_stmt():
|
||||||
|
|
||||||
>>> (x for x in x) += 1
|
>>> (x for x in x) += 1
|
||||||
Traceback (most recent call last):
|
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
|
>>> None += 1
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
SyntaxError: assignment to keyword (<doctest test.test_syntax[32]>, line 1)
|
SyntaxError: assignment to keyword
|
||||||
>>> f() += 1
|
>>> f() += 1
|
||||||
Traceback (most recent call last):
|
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.
|
Test continue in finally in weird combinations.
|
||||||
|
@ -259,7 +259,7 @@
|
||||||
... continue
|
... continue
|
||||||
Traceback (most recent call last):
|
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.
|
This is essentially a continue in a finally which should not be allowed.
|
||||||
|
|
||||||
|
@ -274,7 +274,7 @@
|
||||||
... pass
|
... pass
|
||||||
Traceback (most recent call last):
|
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():
|
>>> def foo():
|
||||||
... try:
|
... try:
|
||||||
|
@ -283,7 +283,7 @@
|
||||||
... continue
|
... continue
|
||||||
Traceback (most recent call last):
|
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():
|
>>> def foo():
|
||||||
... for a in ():
|
... for a in ():
|
||||||
|
@ -293,7 +293,7 @@
|
||||||
... continue
|
... continue
|
||||||
Traceback (most recent call last):
|
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():
|
>>> def foo():
|
||||||
... for a in ():
|
... for a in ():
|
||||||
|
@ -306,7 +306,7 @@
|
||||||
... pass
|
... pass
|
||||||
Traceback (most recent call last):
|
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():
|
>>> def foo():
|
||||||
... for a in ():
|
... for a in ():
|
||||||
|
@ -318,7 +318,7 @@
|
||||||
... continue
|
... continue
|
||||||
Traceback (most recent call last):
|
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
|
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,
|
uses a single data structure to keep track of try-finally and loops,
|
||||||
|
@ -333,7 +333,7 @@
|
||||||
... print(3)
|
... print(3)
|
||||||
Traceback (most recent call last):
|
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).
|
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
|
In 2.5 there was a missing exception and an assert was triggered in a debug
|
||||||
|
@ -420,7 +420,7 @@
|
||||||
... pass
|
... pass
|
||||||
Traceback (most recent call last):
|
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:
|
>>> if 1:
|
||||||
... pass
|
... pass
|
||||||
|
@ -428,7 +428,7 @@
|
||||||
... x() = 1
|
... x() = 1
|
||||||
Traceback (most recent call last):
|
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:
|
>>> if 1:
|
||||||
... x() = 1
|
... x() = 1
|
||||||
|
@ -438,7 +438,7 @@
|
||||||
... pass
|
... pass
|
||||||
Traceback (most recent call last):
|
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:
|
>>> if 1:
|
||||||
... pass
|
... pass
|
||||||
|
@ -448,7 +448,7 @@
|
||||||
... pass
|
... pass
|
||||||
Traceback (most recent call last):
|
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:
|
>>> if 1:
|
||||||
... pass
|
... pass
|
||||||
|
@ -458,7 +458,7 @@
|
||||||
... x() = 1
|
... x() = 1
|
||||||
Traceback (most recent call last):
|
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
|
>>> a, *b, c, *d, e = range(10) # doctest:+ELLIPSIS
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
SyntaxError: two starred expressions in assignment (...)
|
SyntaxError: two starred expressions in assignment
|
||||||
|
|
||||||
>>> [*b, *c] = range(10) # doctest:+ELLIPSIS
|
>>> [*b, *c] = range(10) # doctest:+ELLIPSIS
|
||||||
Traceback (most recent call last):
|
Traceback (most recent call last):
|
||||||
...
|
...
|
||||||
SyntaxError: two starred expressions in assignment (...)
|
SyntaxError: two starred expressions in assignment
|
||||||
|
|
||||||
>>> *a = range(10) # doctest:+ELLIPSIS
|
>>> *a = range(10) # doctest:+ELLIPSIS
|
||||||
Traceback (most recent call last):
|
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
|
>>> *a # doctest:+ELLIPSIS
|
||||||
Traceback (most recent call last):
|
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
|
>>> *1 # doctest:+ELLIPSIS
|
||||||
Traceback (most recent call last):
|
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
|
>>> x = *a # doctest:+ELLIPSIS
|
||||||
Traceback (most recent call last):
|
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.
|
string in the list.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Gracefully handle (the way Python 2.4 and earlier did) the case of
|
# Gracefully handle (the way Python 2.4 and earlier did) the case of
|
||||||
# being called with (None, None).
|
# being called with (None, None).
|
||||||
if etype is None:
|
if etype is None:
|
||||||
|
@ -177,13 +176,11 @@ def format_exception_only(etype, value):
|
||||||
|
|
||||||
# It was a syntax error; show exactly where the problem was found.
|
# It was a syntax error; show exactly where the problem was found.
|
||||||
lines = []
|
lines = []
|
||||||
try:
|
filename = value.filename or "<string>"
|
||||||
msg, (filename, lineno, offset, badline) = value.args
|
lineno = str(value.lineno) or '?'
|
||||||
except Exception:
|
lines.append(' File "%s", line %s\n' % (filename, lineno))
|
||||||
pass
|
badline = value.text
|
||||||
else:
|
offset = value.offset
|
||||||
filename = filename or "<string>"
|
|
||||||
lines.append(' File "%s", line %d\n' % (filename, lineno))
|
|
||||||
if badline is not None:
|
if badline is not None:
|
||||||
lines.append(' %s\n' % badline.strip())
|
lines.append(' %s\n' % badline.strip())
|
||||||
if offset is not None:
|
if offset is not None:
|
||||||
|
@ -192,13 +189,11 @@ def format_exception_only(etype, value):
|
||||||
caretspace = ((c.isspace() and c or ' ') for c in caretspace)
|
caretspace = ((c.isspace() and c or ' ') for c in caretspace)
|
||||||
# only three spaces to account for offset1 == pos 0
|
# only three spaces to account for offset1 == pos 0
|
||||||
lines.append(' %s^\n' % ''.join(caretspace))
|
lines.append(' %s^\n' % ''.join(caretspace))
|
||||||
value = msg
|
msg = value.msg or "<no detail available>"
|
||||||
|
lines.append("%s: %s\n" % (stype, msg))
|
||||||
lines.append(_format_final_exc_line(stype, value))
|
|
||||||
return lines
|
return lines
|
||||||
|
|
||||||
def _format_final_exc_line(etype, value):
|
def _format_final_exc_line(etype, value):
|
||||||
"""Return a list of a single line -- normal case for format_exception_only"""
|
|
||||||
valuestr = _some_str(value)
|
valuestr = _some_str(value)
|
||||||
if value is None or not valuestr:
|
if value is None or not valuestr:
|
||||||
line = "%s\n" % etype
|
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 \
|
QUICKTESTOPTS= $(TESTOPTS) -x test_thread test_signal test_strftime \
|
||||||
test_unicodedata test_re test_sre test_select test_poll \
|
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
|
quicktest: all platform
|
||||||
-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
|
-find $(srcdir)/Lib -name '*.py[co]' -print | xargs rm -f
|
||||||
-$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
|
-$(TESTPYTHON) $(TESTPROG) $(QUICKTESTOPTS)
|
||||||
|
|
|
@ -445,15 +445,6 @@ def detect_modules(self):
|
||||||
define_macros = expat_defs,
|
define_macros = expat_defs,
|
||||||
libraries = ['expat']) )
|
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)
|
self.extensions.extend(exts)
|
||||||
|
|
||||||
# Call the method for detecting whether _tkinter can be compiled
|
# Call the method for detecting whether _tkinter can be compiled
|
||||||
|
|
|
@ -186,8 +186,12 @@ Library
|
||||||
AST -> bytecode mechanism.
|
AST -> bytecode mechanism.
|
||||||
|
|
||||||
- Removed these modules:
|
- Removed these modules:
|
||||||
* Bastion, bsddb185, exceptions, md5, MimeWriter, mimify, popen2, rexec,
|
* audiodev, Bastion, bsddb185, exceptions, linuxaudiodev,
|
||||||
sets, sha, stringold, strop, timing, xmllib.
|
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,
|
- 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,
|
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
|
asynchat Support for 'chat' style protocols
|
||||||
asyncore Asynchronous File I/O (in select style)
|
asyncore Asynchronous File I/O (in select style)
|
||||||
atexit Register functions to be called at exit of Python interpreter.
|
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 .
|
base64 Conversions to/from base64 RFC-MIME transport encoding .
|
||||||
BaseHTTPServer Base class forhttp services.
|
BaseHTTPServer Base class forhttp services.
|
||||||
Bastion "Bastionification" utility (control access to instance vars)
|
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.
|
inspect Tool for probing live Python objects.
|
||||||
keyword List of Python keywords.
|
keyword List of Python keywords.
|
||||||
linecache Cache lines from files.
|
linecache Cache lines from files.
|
||||||
linuxaudiodev Lunix /dev/audio support.
|
|
||||||
locale Support for number formatting using the current locale
|
locale Support for number formatting using the current locale
|
||||||
settings.
|
settings.
|
||||||
logging Python logging facility.
|
logging Python logging facility.
|
||||||
|
@ -1946,7 +1944,6 @@ tempfile Temporary file name allocation.
|
||||||
textwrap Object for wrapping and filling text.
|
textwrap Object for wrapping and filling text.
|
||||||
threading Proposed new higher-level threading interfaces
|
threading Proposed new higher-level threading interfaces
|
||||||
threading_api (doc of the threading module)
|
threading_api (doc of the threading module)
|
||||||
toaiff Convert "arbitrary" sound files to AIFF files .
|
|
||||||
token Tokens (from "token.h").
|
token Tokens (from "token.h").
|
||||||
tokenize Compiles a regular expression that recognizes Python tokens.
|
tokenize Compiles a regular expression that recognizes Python tokens.
|
||||||
traceback Format and print Python stack traces.
|
traceback Format and print Python stack traces.
|
||||||
|
@ -2042,10 +2039,6 @@ zipfile Read & write PK zipped files.
|
||||||
DEVICE More constants for gl
|
DEVICE More constants for gl
|
||||||
imgfile Imglib image file interface
|
imgfile Imglib image file interface
|
||||||
|
|
||||||
* Suns *
|
|
||||||
|
|
||||||
sunaudiodev Access to sun audio interface
|
|
||||||
|
|
||||||
|
|
||||||
Workspace exploration and idiom hints
|
Workspace exploration and idiom hints
|
||||||
|
|
||||||
|
|
|
@ -236,17 +236,6 @@ _symtable symtablemodule.c
|
||||||
#_sha shamodule.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 _tkinter module.
|
||||||
#
|
#
|
||||||
# The command for _tkinter is long and site specific. Please
|
# 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)
|
#define R_OFF(x) offsetof(ReaderObj, x)
|
||||||
|
|
||||||
static struct PyMemberDef Reader_memberlist[] = {
|
static struct PyMemberDef Reader_memberlist[] = {
|
||||||
{ "dialect", T_OBJECT, R_OFF(dialect), RO },
|
{ "dialect", T_OBJECT, R_OFF(dialect), READONLY },
|
||||||
{ "line_num", T_ULONG, R_OFF(line_num), RO },
|
{ "line_num", T_ULONG, R_OFF(line_num), READONLY },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1239,7 +1239,7 @@ static struct PyMethodDef Writer_methods[] = {
|
||||||
#define W_OFF(x) offsetof(WriterObj, x)
|
#define W_OFF(x) offsetof(WriterObj, x)
|
||||||
|
|
||||||
static struct PyMemberDef Writer_memberlist[] = {
|
static struct PyMemberDef Writer_memberlist[] = {
|
||||||
{ "dialect", T_OBJECT, W_OFF(dialect), RO },
|
{ "dialect", T_OBJECT, W_OFF(dialect), READONLY },
|
||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1266,7 +1266,7 @@ static PyMethodDef logreader_methods[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static PyMemberDef logreader_members[] = {
|
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.")},
|
PyDoc_STR("Dictionary mapping informational keys to lists of values.")},
|
||||||
{NULL}
|
{NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1624,7 +1624,7 @@ static PyTypeObject BZ2Comp_Type = {
|
||||||
#define OFF(x) offsetof(BZ2DecompObject, x)
|
#define OFF(x) offsetof(BZ2DecompObject, x)
|
||||||
|
|
||||||
static PyMemberDef BZ2Decomp_members[] = {
|
static PyMemberDef BZ2Decomp_members[] = {
|
||||||
{"unused_data", T_OBJECT, OFF(unused_data), RO},
|
{"unused_data", T_OBJECT, OFF(unused_data), READONLY},
|
||||||
{NULL} /* Sentinel */
|
{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)
|
#define OFF(x) offsetof(PyFrameObject, x)
|
||||||
|
|
||||||
static PyMemberDef frame_memberlist[] = {
|
static PyMemberDef frame_memberlist[] = {
|
||||||
{"f_back", T_OBJECT, OFF(f_back), RO},
|
{"f_back", T_OBJECT, OFF(f_back), READONLY},
|
||||||
{"f_code", T_OBJECT, OFF(f_code), RO},
|
{"f_code", T_OBJECT, OFF(f_code), READONLY},
|
||||||
{"f_builtins", T_OBJECT, OFF(f_builtins),RO},
|
{"f_builtins", T_OBJECT, OFF(f_builtins),READONLY},
|
||||||
{"f_globals", T_OBJECT, OFF(f_globals), RO},
|
{"f_globals", T_OBJECT, OFF(f_globals), READONLY},
|
||||||
{"f_lasti", T_INT, OFF(f_lasti), RO},
|
{"f_lasti", T_INT, OFF(f_lasti), READONLY},
|
||||||
{"f_exc_type", T_OBJECT, OFF(f_exc_type)},
|
{"f_exc_type", T_OBJECT, OFF(f_exc_type)},
|
||||||
{"f_exc_value", T_OBJECT, OFF(f_exc_value)},
|
{"f_exc_value", T_OBJECT, OFF(f_exc_value)},
|
||||||
{"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)},
|
{"f_exc_traceback", T_OBJECT, OFF(f_exc_traceback)},
|
||||||
|
|
|
@ -282,8 +282,8 @@ gen_iternext(PyGenObject *gen)
|
||||||
|
|
||||||
|
|
||||||
static PyMemberDef gen_memberlist[] = {
|
static PyMemberDef gen_memberlist[] = {
|
||||||
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), RO},
|
{"gi_frame", T_OBJECT, offsetof(PyGenObject, gi_frame), READONLY},
|
||||||
{"gi_running", T_INT, offsetof(PyGenObject, gi_running), RO},
|
{"gi_running", T_INT, offsetof(PyGenObject, gi_running), READONLY},
|
||||||
{NULL} /* Sentinel */
|
{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)\stringobject.h $(PY_INCLUDE)\sysmodule.h $(PY_INCLUDE)\traceback.h \
|
||||||
$(PY_INCLUDE)\tupleobject.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 \
|
syslogmodule.obj: $(PY_INCLUDE)\abstract.h $(PY_INCLUDE)\ceval.h \
|
||||||
$(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
|
$(PY_INCLUDE)\classobject.h $(PY_INCLUDE)\cobject.h $(PY_INCLUDE)\complexobject.h \
|
||||||
pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
|
pyconfig.h $(PY_INCLUDE)\dictobject.h $(PY_INCLUDE)\fileobject.h \
|
||||||
|
|
|
@ -171,8 +171,6 @@ MODULES = \
|
||||||
#
|
#
|
||||||
# Multimedia:
|
# Multimedia:
|
||||||
# audioop.c -- Various Compute Operations on Audio Samples
|
# 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:
|
# Database:
|
||||||
# dbmmodule.c -- Wrapper of DBM Database API (Generic Flavor)
|
# 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 \
|
pystate.h python.h pythonrun.h rangeobject.h sliceobject.h \
|
||||||
stringobject.h sysmodule.h traceback.h tupleobject.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 \
|
syslogmodule.obj: abstract.h ceval.h classobject.h cobject.h \
|
||||||
complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
|
complexobject.h pyconfig.h dictobject.h fileobject.h floatobject.h \
|
||||||
funcobject.h import.h intobject.h intrcheck.h listobject.h \
|
funcobject.h import.h intobject.h intrcheck.h listobject.h \
|
||||||
|
|
|
@ -1471,11 +1471,11 @@ symtable_visit_alias(struct symtable *st, alias_ty a)
|
||||||
else {
|
else {
|
||||||
if (st->st_cur->ste_type != ModuleBlock) {
|
if (st->st_cur->ste_type != ModuleBlock) {
|
||||||
int lineno = st->st_cur->ste_lineno;
|
int lineno = st->st_cur->ste_lineno;
|
||||||
if (!symtable_warn(st, IMPORT_STAR_WARNING, lineno)) {
|
PyErr_SetString(PyExc_SyntaxError, IMPORT_STAR_WARNING);
|
||||||
|
PyErr_SyntaxLocation(st->st_filename, lineno);
|
||||||
Py_DECREF(store_name);
|
Py_DECREF(store_name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR;
|
st->st_cur->ste_unoptimized |= OPT_IMPORT_STAR;
|
||||||
Py_DECREF(store_name);
|
Py_DECREF(store_name);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -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']))
|
exts.append(Extension('_fileio', ['_fileio.c']))
|
||||||
|
|
||||||
# Platform-specific libraries
|
# 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',
|
if platform in ('linux2', 'freebsd4', 'freebsd5', 'freebsd6',
|
||||||
'freebsd7'):
|
'freebsd7'):
|
||||||
exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
|
exts.append( Extension('ossaudiodev', ['ossaudiodev.c']) )
|
||||||
else:
|
else:
|
||||||
missing.append('ossaudiodev')
|
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
|
if platform == 'darwin' and ("--disable-toolbox-glue" not in
|
||||||
sysconfig.get_config_var("CONFIG_ARGS")):
|
sysconfig.get_config_var("CONFIG_ARGS")):
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue