Skip to content

Commit 57db7a3

Browse files
committed
add PaErrorCode enum; allow code-less pa errors
+ Added PaErrorCode enumeration of portaudio error codes + Modified PortAudioError to allow for exception cases when there is no associated portaudio error code. (paerrcode = None) + Corrected two PortAudioError exception cases to ValueError exceptions + Added attributes documentation to PortAudioError class + changed *errno PortAudioError attributes to *errcode to avoid confusion with OSError errno attribute
1 parent f435854 commit 57db7a3

File tree

1 file changed

+60
-32
lines changed

1 file changed

+60
-32
lines changed

sounddevice.py

Lines changed: 60 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ def playrec(data, samplerate=None, channels=None, dtype=None,
517517
input_frames = ctx.check_out(out, output_frames, channels, dtype,
518518
input_mapping)
519519
if input_frames != output_frames:
520-
raise PortAudioError('len(data) != len(out)')
520+
raise ValueError('len(data) != len(out)')
521521
ctx.frames = input_frames
522522

523523
def callback(indata, outdata, frames, time, status):
@@ -924,7 +924,7 @@ def __init__(self, kind, samplerate=None, blocksize=None, device=None,
924924
self._channels = iparameters.channelCount, oparameters.channelCount
925925
self._samplesize = isize, osize
926926
if isamplerate != osamplerate:
927-
raise PortAudioError(
927+
raise ValueError(
928928
'Input and output device must have the same samplerate')
929929
else:
930930
samplerate = isamplerate
@@ -2265,38 +2265,66 @@ def reset(self):
22652265
if not hasattr(_ffi, 'I_AM_FAKE'):
22662266
# This object shadows the 'default' class, except when building the docs.
22672267
default = default()
2268-
2268+
# A simple enumeration of the Portaudio error codes
2269+
PaErrorCode = type('PaErrorCode', (), _ffi.typeof('PaErrorCode').relements)
22692270

22702271
class PortAudioError(Exception):
2271-
"""This exception will be raised on PortAudio errors."""
2272-
def __init__(self, *args):
2273-
"""PortAudioError(PaErrorCode[,msg])
2274-
"""
2275-
super(PortAudioError, self).__init__(*args)
2276-
self.paerrno = args[0]
2277-
self.hosterrno = self.hostapi = self.hosterrmsg = None
2278-
2279-
if self.paerrno == _lib.paUnanticipatedHostError:
2280-
info = _lib.Pa_GetLastHostErrorInfo()
2281-
hostapi = _lib.Pa_HostApiTypeIdToHostApiIndex(info.hostApiType)
2282-
apiinfo = _lib.Pa_GetHostApiInfo(hostapi)
2283-
apiname = _ffi.string(apiinfo.name).decode() if apiinfo else 'unknown'
2284-
errmsg = _ffi.string(info.errorText).decode()
2285-
self.hosterrno = info.errorCode
2286-
self.hostapi = apiname
2287-
self.hosterrmsg = errmsg
2272+
"""This exception will be raised on PortAudio errors.
22882273
2289-
def __str__(self):
2290-
errmsg = "[PaErrno {0:d}] ".format(self.paerrno)
2291-
if self.hosterrno is not None:
2292-
errmsg += "Unanticipated {0:r} host error".format(self.hostapi)
2274+
Parameters
2275+
----------
2276+
msg : optional
2277+
User error message.
2278+
errcode : int or None, optional
2279+
PaErrorCode value or None if there is no PaErrorCode associated
2280+
with the error.
2281+
2282+
Notes
2283+
-----
2284+
- Some PortAudioError's do not have an associated PaErrorCode. In
2285+
such a case `paerrcode` will be None.
2286+
2287+
- The `hostapi`, `hosterrcode`, and `hosterrmsg` attributes will be
2288+
None except for the case when `paerrcode` ==
2289+
`paUnanticipatedHostError`.
2290+
2291+
Attributes
2292+
----------
2293+
paerrcode : int or None
2294+
The PaErrorCode integer value or None if there is no associated
2295+
error code.
2296+
hostapi : str or None
2297+
The name of the host API which returned the error code.
2298+
hosterrcode : int or None
2299+
The host error code returned.
2300+
hosterrmsg : str or None
2301+
A textual description of the host error if available, otherwise
2302+
a zero-length string.
2303+
"""
2304+
def __init__(self, msg=None, errcode=None):
2305+
self.paerrcode = errcode
2306+
self.hosterrcode = self.hostapi = self.hosterrmsg = None
2307+
2308+
if errcode:
2309+
errmsg = "[PaErrorCode {0:d}] ".format(self.paerrcode)
2310+
if errcode == _lib.paUnanticipatedHostError:
2311+
info = _lib.Pa_GetLastHostErrorInfo()
2312+
hostapi = _lib.Pa_HostApiTypeIdToHostApiIndex(info.hostApiType)
2313+
apiinfo = _lib.Pa_GetHostApiInfo(hostapi)
2314+
self.hosterrcode = info.errorCode
2315+
self.hostapi = _ffi.string(apiinfo.name).decode() if apiinfo else 'unknown'
2316+
self.hosterrmsg = _ffi.string(info.errorText).decode()
2317+
errmsg += "Unanticipated {0!r} host error".format(self.hostapi)
2318+
else:
2319+
errmsg += _ffi.string(_lib.Pa_GetErrorText(errcode)).decode()
2320+
if msg is not None:
2321+
errmsg += ": {0!s}".format(msg)
2322+
elif self.hosterrmsg:
2323+
errmsg += ": {0}".format(self.hosterrmsg)
22932324
else:
2294-
errmsg += _ffi.string(_lib.Pa_GetErrorText(paerrno)).decode()
2295-
if len(self.args) > 1:
2296-
errmsg += ": {0!s}".format(self.args[1])
2297-
elif self.hosterrmsg:
2298-
errmsg += ": {0}".format(self.hosterrmsg)
2299-
return errmsg
2325+
errmsg = msg or ''
2326+
2327+
super(PortAudioError, self).__init__(errmsg)
23002328

23012329

23022330
class CallbackStop(Exception):
@@ -2685,10 +2713,10 @@ def _split(value):
26852713
return invalue, outvalue
26862714

26872715

2688-
def _check(err, msg=""):
2716+
def _check(err, msg=None):
26892717
"""Raise error for non-zero error codes."""
26902718
if err < 0:
2691-
raise PortAudioError(err, msg)
2719+
raise PortAudioError(msg, err)
26922720
return err
26932721

26942722

0 commit comments

Comments
 (0)