anki/thirdparty/pyaudio.py
2012-12-21 16:51:59 +09:00

1083 lines
33 KiB
Python

# PyAudio : Python Bindings for PortAudio.
# Copyright (c) 2006-2010 Hubert Pham
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
""" PyAudio : Python Bindings for PortAudio v19.
**These bindings only support PortAudio blocking mode.**
:var PaSampleFormat:
A list of all PortAudio ``PaSampleFormat`` value constants.
See: `paInt32`, `paInt24`, `paInt16`, `paInt8`, and `paUInt8`.
:var PaHostApiTypeId:
A list of all PortAudio ``PaHostApiTypeId`` constants.
See: `paInDevelopment`, `paDirectSound`, `paMME`, `paASIO`,
`paSoundManager`, `paCoreAudio`, `paOSS`, `paALSA`, `paAL`, *et al...*
:var PaErrorCode:
A list of all PortAudio ``PaErrorCode`` constants.
Typically, error code constants are included in Python
exception objects (as the second argument).
See: `paNoError`, `paNotInitialized`, `paUnanticipatedHostError`,
*et al...*
:group PortAudio Constants:
PaSampleFormat, PaHostApiTypeId, PaErrorCode
:group PaSampleFormat Values:
paFloat32, paInt32, paInt24, paInt16,
paInt8, paUInt8, paCustomFormat
:group PaHostApiTypeId Values:
paInDevelopment, paDirectSound, paMME, paASIO,
paSoundManager, paCoreAudio, paOSS, paALSA
paAL, paBeOS, paWDMKS, paJACK, paWASAPI, paNoDevice
:group PaErrorCode Values:
paNoError,
paNotInitialized, paUnanticipatedHostError,
paInvalidChannelCount, paInvalidSampleRate,
paInvalidDevice, paInvalidFlag,
paSampleFormatNotSupported, paBadIODeviceCombination,
paInsufficientMemory, paBufferTooBig,
paBufferTooSmall, paNullCallback,
paBadStreamPtr, paTimedOut,
paInternalError, paDeviceUnavailable,
paIncompatibleHostApiSpecificStreamInfo, paStreamIsStopped,
paStreamIsNotStopped, paInputOverflowed,
paOutputUnderflowed, paHostApiNotFound,
paInvalidHostApi, paCanNotReadFromACallbackStream,
paCanNotWriteToACallbackStream,
paCanNotReadFromAnOutputOnlyStream,
paCanNotWriteToAnInputOnlyStream,
paIncompatibleStreamHostApi
:group Stream Conversion Convenience Functions:
get_sample_size, get_format_from_width
:group PortAudio version:
get_portaudio_version, get_portaudio_version_text
:sort: PaSampleFormat, PaHostApiTypeId, PaErrorCode
:sort: PortAudio Constants, PaSampleFormat Values,
PaHostApiTypeId Values, PaErrorCode Values
"""
__author__ = "Hubert Pham"
__version__ = "0.2.4"
__docformat__ = "restructuredtext en"
import sys
# attempt to import PortAudio
try:
import _portaudio as pa
except ImportError:
print "Please build and install the PortAudio Python " +\
"bindings first."
sys.exit(-1)
# Try to use Python 2.4's built in `set'
try:
a = set()
del a
except NameError:
from sets import Set as set
############################################################
# GLOBALS
############################################################
##### PaSampleFormat Sample Formats #####
paFloat32 = pa.paFloat32
paInt32 = pa.paInt32
paInt24 = pa.paInt24
paInt16 = pa.paInt16
paInt8 = pa.paInt8
paUInt8 = pa.paUInt8
paCustomFormat = pa.paCustomFormat
# group them together for epydoc
PaSampleFormat = ['paFloat32', 'paInt32', 'paInt24', 'paInt16',
'paInt8', 'paUInt8', 'paCustomFormat']
###### HostAPI TypeId #####
paInDevelopment = pa.paInDevelopment
paDirectSound = pa.paDirectSound
paMME = pa.paMME
paASIO = pa.paASIO
paSoundManager = pa.paSoundManager
paCoreAudio = pa.paCoreAudio
paOSS = pa.paOSS
paALSA = pa.paALSA
paAL = pa.paAL
paBeOS = pa.paBeOS
paWDMKS = pa.paWDMKS
paJACK = pa.paJACK
paWASAPI = pa.paWASAPI
paNoDevice = pa.paNoDevice
# group them together for epydoc
PaHostApiTypeId = ['paInDevelopment', 'paDirectSound', 'paMME',
'paASIO', 'paSoundManager', 'paCoreAudio',
'paOSS', 'paALSA', 'paAL', 'paBeOS',
'paWDMKS', 'paJACK', 'paWASAPI', 'paNoDevice']
###### portaudio error codes #####
paNoError = pa.paNoError
paNotInitialized = pa.paNotInitialized
paUnanticipatedHostError = pa.paUnanticipatedHostError
paInvalidChannelCount = pa.paInvalidChannelCount
paInvalidSampleRate = pa.paInvalidSampleRate
paInvalidDevice = pa.paInvalidDevice
paInvalidFlag = pa.paInvalidFlag
paSampleFormatNotSupported = pa.paSampleFormatNotSupported
paBadIODeviceCombination = pa.paBadIODeviceCombination
paInsufficientMemory = pa.paInsufficientMemory
paBufferTooBig = pa.paBufferTooBig
paBufferTooSmall = pa.paBufferTooSmall
paNullCallback = pa.paNullCallback
paBadStreamPtr = pa.paBadStreamPtr
paTimedOut = pa.paTimedOut
paInternalError = pa.paInternalError
paDeviceUnavailable = pa.paDeviceUnavailable
paIncompatibleHostApiSpecificStreamInfo = pa.paIncompatibleHostApiSpecificStreamInfo
paStreamIsStopped = pa.paStreamIsStopped
paStreamIsNotStopped = pa.paStreamIsNotStopped
paInputOverflowed = pa.paInputOverflowed
paOutputUnderflowed = pa.paOutputUnderflowed
paHostApiNotFound = pa.paHostApiNotFound
paInvalidHostApi = pa.paInvalidHostApi
paCanNotReadFromACallbackStream = pa.paCanNotReadFromACallbackStream
paCanNotWriteToACallbackStream = pa.paCanNotWriteToACallbackStream
paCanNotReadFromAnOutputOnlyStream = pa.paCanNotReadFromAnOutputOnlyStream
paCanNotWriteToAnInputOnlyStream = pa.paCanNotWriteToAnInputOnlyStream
paIncompatibleStreamHostApi = pa.paIncompatibleStreamHostApi
# group them together for epydoc
PaErrorCode = ['paNoError',
'paNotInitialized', 'paUnanticipatedHostError',
'paInvalidChannelCount', 'paInvalidSampleRate',
'paInvalidDevice', 'paInvalidFlag',
'paSampleFormatNotSupported', 'paBadIODeviceCombination',
'paInsufficientMemory', 'paBufferTooBig',
'paBufferTooSmall', 'paNullCallback',
'paBadStreamPtr', 'paTimedOut',
'paInternalError', 'paDeviceUnavailable',
'paIncompatibleHostApiSpecificStreamInfo', 'paStreamIsStopped',
'paStreamIsNotStopped', 'paInputOverflowed',
'paOutputUnderflowed', 'paHostApiNotFound',
'paInvalidHostApi', 'paCanNotReadFromACallbackStream',
'paCanNotWriteToACallbackStream',
'paCanNotReadFromAnOutputOnlyStream',
'paCanNotWriteToAnInputOnlyStream',
'paIncompatibleStreamHostApi']
############################################################
# Convenience Functions
############################################################
def get_sample_size(format):
"""
Returns the size (in bytes) for the specified
sample `format` (a `PaSampleFormat` constant).
:param `format`:
PortAudio sample format constant `PaSampleFormat`.
:raises ValueError: Invalid specified `format`.
:rtype: int
"""
return pa.get_sample_size(format)
def get_format_from_width(width, unsigned = True):
"""
Returns a PortAudio format constant for
the specified `width`.
:param `width`:
The desired sample width in bytes (1, 2, 3, or 4)
:param `unsigned`:
For 1 byte width, specifies signed or unsigned
format.
:raises ValueError: for invalid `width`
:rtype: `PaSampleFormat`
"""
if width == 1:
if unsigned:
return paUInt8
else:
return paInt8
elif width == 2:
return paInt16
elif width == 3:
return paInt24
elif width == 4:
return paFloat32
else:
raise ValueError, "Invalid width: %d" % width
############################################################
# Versioning
############################################################
def get_portaudio_version():
"""
Returns portaudio version.
:rtype: str """
return pa.get_version()
def get_portaudio_version_text():
"""
Returns PortAudio version as a text string.
:rtype: str """
return pa.get_version_text()
############################################################
# Wrapper around _portaudio Stream (Internal)
############################################################
# Note: See PyAudio class below for main export.
class Stream:
"""
PortAudio Stream Wrapper. Use `PyAudio.open` to make a new
`Stream`.
:group Opening and Closing:
__init__, close
:group Stream Info:
get_input_latency, get_output_latency, get_time, get_cpu_load
:group Stream Management:
start_stream, stop_stream, is_active, is_stopped
:group Input Output:
write, read, get_read_available, get_write_available
"""
def __init__(self,
PA_manager,
rate,
channels,
format,
input = False,
output = False,
input_device_index = None,
output_device_index = None,
frames_per_buffer = 1024,
start = True,
input_host_api_specific_stream_info = None,
output_host_api_specific_stream_info = None):
"""
Initialize a stream; this should be called by
`PyAudio.open`. A stream can either be input, output, or both.
:param `PA_manager`: A reference to the managing `PyAudio` instance
:param `rate`: Sampling rate
:param `channels`: Number of channels
:param `format`: Sampling size and format. See `PaSampleFormat`.
:param `input`: Specifies whether this is an input stream.
Defaults to False.
:param `output`: Specifies whether this is an output stream.
Defaults to False.
:param `input_device_index`: Index of Input Device to use.
Unspecified (or None) uses default device.
Ignored if `input` is False.
:param `output_device_index`:
Index of Output Device to use.
Unspecified (or None) uses the default device.
Ignored if `output` is False.
:param `frames_per_buffer`: Specifies the number of frames per buffer.
:param `start`: Start the stream running immediately.
Defaults to True. In general, there is no reason to set
this to false.
:param `input_host_api_specific_stream_info`: Specifies a host API
specific stream information data structure for input.
See `PaMacCoreStreamInfo`.
:param `output_host_api_specific_stream_info`: Specifies a host API
specific stream information data structure for output.
See `PaMacCoreStreamInfo`.
:raise ValueError: Neither input nor output
are set True.
"""
# no stupidity allowed
if not (input or output):
raise ValueError, \
"Must specify an input or output " +\
"stream."
# remember parent
self._parent = PA_manager
# remember if we are an: input, output (or both)
self._is_input = input
self._is_output = output
# are we running?
self._is_running = start
# remember some parameters
self._rate = rate
self._channels = channels
self._format = format
self._frames_per_buffer = frames_per_buffer
arguments = {
'rate' : rate,
'channels' : channels,
'format' : format,
'input' : input,
'output' : output,
'input_device_index' : input_device_index,
'output_device_index' : output_device_index,
'frames_per_buffer' : frames_per_buffer}
if input_host_api_specific_stream_info:
_l = input_host_api_specific_stream_info
arguments[
'input_host_api_specific_stream_info'
] = _l._get_host_api_stream_object()
if output_host_api_specific_stream_info:
_l = output_host_api_specific_stream_info
arguments[
'output_host_api_specific_stream_info'
] = _l._get_host_api_stream_object()
# calling pa.open returns a stream object
self._stream = pa.open(**arguments)
self._input_latency = self._stream.inputLatency
self._output_latency = self._stream.outputLatency
if self._is_running:
pa.start_stream(self._stream)
def close(self):
""" Close the stream """
pa.close(self._stream)
self._is_running = False
self._parent._remove_stream(self)
############################################################
# Stream Info
############################################################
def get_input_latency(self):
"""
Return the input latency.
:rtype: float
"""
return self._stream.inputLatency
def get_output_latency(self):
"""
Return the input latency.
:rtype: float
"""
return self._stream.outputLatency
def get_time(self):
"""
Return stream time.
:rtype: float
"""
return pa.get_stream_time(self._stream)
def get_cpu_load(self):
"""
Return the CPU load.
(Note: this is always 0.0 for the blocking API.)
:rtype: float
"""
return pa.get_stream_cpu_load(self._stream)
############################################################
# Stream Management
############################################################
def start_stream(self):
""" Start the stream. """
if self._is_running:
return
pa.start_stream(self._stream)
self._is_running = True
def stop_stream(self):
""" Stop the stream. Once the stream is stopped,
one may not call write or read. However, one may
call start_stream to resume the stream. """
if not self._is_running:
return
pa.stop_stream(self._stream)
self._is_running = False
def is_active(self):
""" Returns whether the stream is active.
:rtype: bool """
return pa.is_stream_active(self._stream)
def is_stopped(self):
""" Returns whether the stream is stopped.
:rtype: bool """
return pa.is_stream_stopped(self._stream)
############################################################
# Reading/Writing
############################################################
def write(self, frames, num_frames = None,
exception_on_underflow = False):
"""
Write samples to the stream.
:param `frames`:
The frames of data.
:param `num_frames`:
The number of frames to write.
Defaults to None, in which this value will be
automatically computed.
:param `exception_on_underflow`:
Specifies whether an exception should be thrown
(or silently ignored) on buffer underflow. Defaults
to False for improved performance, especially on
slower platforms.
:raises IOError: if the stream is not an output stream
or if the write operation was unsuccessful.
:rtype: `None`
"""
if not self._is_output:
raise IOError("Not output stream",
paCanNotWriteToAnInputOnlyStream)
if num_frames == None:
# determine how many frames to read
width = get_sample_size(self._format)
num_frames = len(frames) / (self._channels * width)
#print len(frames), self._channels, self._width, num_frames
pa.write_stream(self._stream, frames, num_frames,
exception_on_underflow)
def read(self, num_frames):
"""
Read samples from the stream.
:param `num_frames`:
The number of frames to read.
:raises IOError: if stream is not an input stream
or if the read operation was unsuccessful.
:rtype: str
"""
if not self._is_input:
raise IOError("Not input stream",
paCanNotReadFromAnOutputOnlyStream)
return pa.read_stream(self._stream, num_frames)
def get_read_available(self):
"""
Return the number of frames that can be read
without waiting.
:rtype: int
"""
return pa.get_stream_read_available(self._stream)
def get_write_available(self):
"""
Return the number of frames that can be written
without waiting.
:rtype: int
"""
return pa.get_stream_write_available(self._stream)
############################################################
# Main Export
############################################################
class PyAudio:
"""
Python interface to PortAudio. Provides methods to:
- initialize and terminate PortAudio
- open and close streams
- query and inspect the available PortAudio Host APIs
- query and inspect the available PortAudio audio
devices
Use this class to open and close streams.
:group Stream Management:
open, close
:group Host API:
get_host_api_count, get_default_host_api_info,
get_host_api_info_by_type, get_host_api_info_by_index,
get_device_info_by_host_api_device_index
:group Device API:
get_device_count, is_format_supported,
get_default_input_device_info,
get_default_output_device_info,
get_device_info_by_index
:group Stream Format Conversion:
get_sample_size, get_format_from_width
"""
############################################################
# Initialization and Termination
############################################################
def __init__(self):
""" Initialize PortAudio. """
pa.initialize()
self._streams = set()
def terminate(self):
""" Terminate PortAudio.
:attention: Be sure to call this method for every
instance of this object to release PortAudio resources.
"""
for stream in self._streams:
stream.close()
self._streams = set()
pa.terminate()
############################################################
# Stream Format
############################################################
def get_sample_size(self, format):
"""
Returns the size (in bytes) for the specified
sample `format` (a `PaSampleFormat` constant).
:param `format`:
Sample format constant (`PaSampleFormat`).
:raises ValueError: Invalid specified `format`.
:rtype: int
"""
return pa.get_sample_size(format)
def get_format_from_width(self, width, unsigned = True):
"""
Returns a PortAudio format constant for
the specified `width`.
:param `width`:
The desired sample width in bytes (1, 2, 3, or 4)
:param `unsigned`:
For 1 byte width, specifies signed or unsigned format.
:raises ValueError: for invalid `width`
:rtype: `PaSampleFormat`
"""
if width == 1:
if unsigned:
return paUInt8
else:
return paInt8
elif width == 2:
return paInt16
elif width == 3:
return paInt24
elif width == 4:
return paFloat32
else:
raise ValueError, "Invalid width: %d" % width
############################################################
# Stream Factory
############################################################
def open(self, *args, **kwargs):
"""
Open a new stream. See constructor for
`Stream.__init__` for parameter details.
:returns: `Stream` """
stream = Stream(self, *args, **kwargs)
self._streams.add(stream)
return stream
def close(self, stream):
"""
Close a stream. Typically use `Stream.close` instead.
:param `stream`:
An instance of the `Stream` object.
:raises ValueError: if stream does not exist.
"""
if stream not in self._streams:
raise ValueError, "Stream `%s' not found" % str(stream)
stream.close()
def _remove_stream(self, stream):
"""
Internal method. Removes a stream.
:param `stream`:
An instance of the `Stream` object.
"""
if stream in self._streams:
self._streams.remove(stream)
############################################################
# Host API Inspection
############################################################
def get_host_api_count(self):
"""
Return the number of PortAudio Host APIs.
:rtype: int
"""
return pa.get_host_api_count()
def get_default_host_api_info(self):
"""
Return a dictionary containing the default Host API
parameters. The keys of the dictionary mirror the data fields
of PortAudio's ``PaHostApiInfo`` structure.
:raises IOError: if no default input device available
:rtype: dict
"""
defaultHostApiIndex = pa.get_default_host_api()
return self.get_host_api_info_by_index(defaultHostApiIndex)
def get_host_api_info_by_type(self, host_api_type):
"""
Return a dictionary containing the Host API parameters for the
host API specified by the `host_api_type`. The keys of the
dictionary mirror the data fields of PortAudio's ``PaHostApiInfo``
structure.
:param `host_api_type`:
The desired Host API (`PaHostApiTypeId` constant).
:raises IOError: for invalid `host_api_type`
:rtype: dict
"""
index = pa.host_api_type_id_to_host_api_index(host_api_type)
return self.get_host_api_info_by_index(index)
def get_host_api_info_by_index(self, host_api_index):
"""
Return a dictionary containing the Host API parameters for the
host API specified by the `host_api_index`. The keys of the
dictionary mirror the data fields of PortAudio's ``PaHostApiInfo``
structure.
:param `host_api_index`: The host api index.
:raises IOError: for invalid `host_api_index`
:rtype: dict
"""
return self._make_host_api_dictionary(
host_api_index,
pa.get_host_api_info(host_api_index)
)
def get_device_info_by_host_api_device_index(self,
host_api_index,
host_api_device_index):
"""
Return a dictionary containing the Device parameters for a
given Host API's n'th device. The keys of the dictionary
mirror the data fields of PortAudio's ``PaDeviceInfo`` structure.
:param `host_api_index`:
The Host API index number.
:param `host_api_device_index`:
The *n* 'th device of the host API.
:raises IOError: for invalid indices
:rtype: dict
"""
long_method_name = pa.host_api_device_index_to_device_index
device_index = long_method_name(host_api_index,
host_api_device_index)
return self.get_device_info_by_index(device_index)
def _make_host_api_dictionary(self, index, host_api_struct):
"""
Internal method to create Host API dictionary
that mirrors PortAudio's ``PaHostApiInfo`` structure.
:rtype: dict
"""
return {'index' : index,
'structVersion' : host_api_struct.structVersion,
'type' : host_api_struct.type,
'name' : host_api_struct.name,
'deviceCount' : host_api_struct.deviceCount,
'defaultInputDevice' : host_api_struct.defaultInputDevice,
'defaultOutputDevice' : host_api_struct.defaultOutputDevice}
############################################################
# Device Inspection
############################################################
def get_device_count(self):
"""
Return the number of PortAudio Host APIs.
:rtype: int
"""
return pa.get_device_count()
def is_format_supported(self, rate,
input_device = None,
input_channels = None,
input_format = None,
output_device = None,
output_channels = None,
output_format = None):
"""
Check to see if specified device configuration
is supported. Returns True if the configuration
is supported; throws a ValueError exception otherwise.
:param `rate`:
Specifies the desired rate (in Hz)
:param `input_device`:
The input device index. Specify `None` (default) for
half-duplex output-only streams.
:param `input_channels`:
The desired number of input channels. Ignored if
`input_device` is not specified (or `None`).
:param `input_format`:
PortAudio sample format constant defined
in this module
:param `output_device`:
The output device index. Specify `None` (default) for
half-duplex input-only streams.
:param `output_channels`:
The desired number of output channels. Ignored if
`input_device` is not specified (or `None`).
:param `output_format`:
PortAudio sample format constant (`PaSampleFormat`).
:rtype: bool
:raises ValueError: tuple containing:
(error string, PortAudio error code `PaErrorCode`).
"""
if input_device == None and output_device == None:
raise ValueError("must specify stream format for input, " +\
"output, or both", paInvalidDevice);
kwargs = {}
if input_device != None:
kwargs['input_device'] = input_device
kwargs['input_channels'] = input_channels
kwargs['input_format'] = input_format
if output_device != None:
kwargs['output_device'] = output_device
kwargs['output_channels'] = output_channels
kwargs['output_format'] = output_format
return pa.is_format_supported(rate, **kwargs)
def get_default_input_device_info(self):
"""
Return the default input Device parameters as a
dictionary. The keys of the dictionary mirror the data fields
of PortAudio's ``PaDeviceInfo`` structure.
:raises IOError: No default input device available.
:rtype: dict
"""
device_index = pa.get_default_input_device()
return self.get_device_info_by_index(device_index)
def get_default_output_device_info(self):
"""
Return the default output Device parameters as a
dictionary. The keys of the dictionary mirror the data fields
of PortAudio's ``PaDeviceInfo`` structure.
:raises IOError: No default output device available.
:rtype: dict
"""
device_index = pa.get_default_output_device()
return self.get_device_info_by_index(device_index)
def get_device_info_by_index(self, device_index):
"""
Return the Device parameters for device specified in
`device_index` as a dictionary. The keys of the dictionary
mirror the data fields of PortAudio's ``PaDeviceInfo``
structure.
:param `device_index`: The device index.
:raises IOError: Invalid `device_index`.
:rtype: dict
"""
return self._make_device_info_dictionary(
device_index,
pa.get_device_info(device_index)
)
def _make_device_info_dictionary(self, index, device_info):
"""
Internal method to create Device Info dictionary
that mirrors PortAudio's ``PaDeviceInfo`` structure.
:rtype: dict
"""
return {'index' : index,
'structVersion' : device_info.structVersion,
'name' : device_info.name,
'hostApi' : device_info.hostApi,
'maxInputChannels' : device_info.maxInputChannels,
'maxOutputChannels' : device_info.maxOutputChannels,
'defaultLowInputLatency' :
device_info.defaultLowInputLatency,
'defaultLowOutputLatency' :
device_info.defaultLowOutputLatency,
'defaultHighInputLatency' :
device_info.defaultHighInputLatency,
'defaultHighOutputLatency' :
device_info.defaultHighOutputLatency,
'defaultSampleRate' :
device_info.defaultSampleRate
}
######################################################################
# Host Specific Stream Info
######################################################################
try:
paMacCoreStreamInfo = pa.paMacCoreStreamInfo
except AttributeError:
pass
else:
class PaMacCoreStreamInfo:
"""
Mac OS X-only: PaMacCoreStreamInfo is a PortAudio Host API
Specific Stream Info data structure for specifying Mac OS
X-only settings. Instantiate this class (if desired) and pass
the instance as the argument in `PyAudio.open` to parameters
``input_host_api_specific_stream_info`` or
``output_host_api_specific_stream_info``. (See `Stream.__init__`.)
:note: Mac OS X only.
:group Flags (constants):
paMacCoreChangeDeviceParameters, paMacCoreFailIfConversionRequired,
paMacCoreConversionQualityMin, paMacCoreConversionQualityMedium,
paMacCoreConversionQualityLow, paMacCoreConversionQualityHigh,
paMacCoreConversionQualityMax, paMacCorePlayNice,
paMacCorePro, paMacCoreMinimizeCPUButPlayNice, paMacCoreMinimizeCPU
:group Settings:
get_flags, get_channel_map
"""
paMacCoreChangeDeviceParameters = pa.paMacCoreChangeDeviceParameters
paMacCoreFailIfConversionRequired = pa.paMacCoreFailIfConversionRequired
paMacCoreConversionQualityMin = pa.paMacCoreConversionQualityMin
paMacCoreConversionQualityMedium = pa.paMacCoreConversionQualityMedium
paMacCoreConversionQualityLow = pa.paMacCoreConversionQualityLow
paMacCoreConversionQualityHigh = pa.paMacCoreConversionQualityHigh
paMacCoreConversionQualityMax = pa.paMacCoreConversionQualityMax
paMacCorePlayNice = pa.paMacCorePlayNice
paMacCorePro = pa.paMacCorePro
paMacCoreMinimizeCPUButPlayNice = pa.paMacCoreMinimizeCPUButPlayNice
paMacCoreMinimizeCPU = pa.paMacCoreMinimizeCPU
def __init__(self, flags = None, channel_map = None):
"""
Initialize with flags and channel_map. See PortAudio
documentation for more details on these parameters; they are
passed almost verbatim to the PortAudio library.
:param `flags`: paMacCore* flags OR'ed together.
See `PaMacCoreStreamInfo`.
:param `channel_map`: An array describing the channel mapping.
See PortAudio documentation for usage.
"""
kwargs = {"flags" : flags,
"channel_map" : channel_map}
if flags == None:
del kwargs["flags"]
if channel_map == None:
del kwargs["channel_map"]
self._paMacCoreStreamInfo = paMacCoreStreamInfo(**kwargs)
def get_flags(self):
"""
Return the flags set at instantiation.
:rtype: int
"""
return self._paMacCoreStreamInfo.flags
def get_channel_map(self):
"""
Return the channel map set at instantiation.
:rtype: tuple or None
"""
return self._paMacCoreStreamInfo.channel_map
def _get_host_api_stream_object(self):
""" Private method. """
return self._paMacCoreStreamInfo