@@ -2143,188 +2143,195 @@ def __repr__(self):
2143
2143
return '[{0[0]!r}, {0[1]!r}]' .format (self )
2144
2144
2145
2145
2146
- class default (object ):
2147
- """Get/set defaults for the *sounddevice* module.
2146
+ def _create_default ():
2147
+ class default (object ):
2148
+ """Get/set defaults for the *sounddevice* module.
2148
2149
2149
- The attributes `device`, `channels`, `dtype`, `latency` and
2150
- `extra_settings` accept single values which specify the given
2151
- property for both input and output. However, if the property
2152
- differs between input and output, pairs of values can be used, where
2153
- the first value specifies the input and the second value specifies
2154
- the output. All other attributes are always single values.
2150
+ The attributes `device`, `channels`, `dtype`, `latency` and
2151
+ `extra_settings` accept single values which specify the given
2152
+ property for both input and output. However, if the property
2153
+ differs between input and output, pairs of values can be used, where
2154
+ the first value specifies the input and the second value specifies
2155
+ the output. All other attributes are always single values.
2155
2156
2156
- Examples
2157
- --------
2157
+ Examples
2158
+ --------
2158
2159
2159
- >>> import sounddevice as sd
2160
- >>> sd.default.samplerate = 48000
2161
- >>> sd.default.dtype
2162
- ['float32', 'float32']
2160
+ >>> import sounddevice as sd
2161
+ >>> sd.default.samplerate = 48000
2162
+ >>> sd.default.dtype
2163
+ ['float32', 'float32']
2163
2164
2164
- Different values for input and output:
2165
+ Different values for input and output:
2165
2166
2166
- >>> sd.default.channels = 1, 2
2167
+ >>> sd.default.channels = 1, 2
2167
2168
2168
- A single value sets both input and output at the same time:
2169
+ A single value sets both input and output at the same time:
2169
2170
2170
- >>> sd.default.device = 5
2171
- >>> sd.default.device
2172
- [5, 5]
2171
+ >>> sd.default.device = 5
2172
+ >>> sd.default.device
2173
+ [5, 5]
2173
2174
2174
- An attribute can be set to the "factory default" by assigning
2175
- ``None``:
2175
+ An attribute can be set to the "factory default" by assigning
2176
+ ``None``:
2176
2177
2177
- >>> sd.default.samplerate = None
2178
- >>> sd.default.device = None, 4
2178
+ >>> sd.default.samplerate = None
2179
+ >>> sd.default.device = None, 4
2179
2180
2180
- Use `reset()` to reset all attributes:
2181
+ Use `reset()` to reset all attributes:
2181
2182
2182
- >>> sd.default.reset()
2183
+ >>> sd.default.reset()
2183
2184
2184
- """
2185
- _pairs = 'device' , 'channels' , 'dtype' , 'latency' , 'extra_settings'
2186
- # The class attributes listed in _pairs are only provided here for static
2187
- # analysis tools and for the docs. They're overwritten in __init__().
2188
- device = None , None
2189
- """Index or query string of default input/output device.
2185
+ """
2186
+ _pairs = 'device' , 'channels' , 'dtype' , 'latency' , 'extra_settings'
2187
+ # The class attributes listed in _pairs are only provided here for static
2188
+ # analysis tools and for the docs. They're overwritten in __init__().
2189
+ device = None , None
2190
+ """Index or query string of default input/output device.
2190
2191
2191
- If not overwritten, this is queried from PortAudio.
2192
+ If not overwritten, this is queried from PortAudio.
2192
2193
2193
- If a string is given, the device is selected which contains all
2194
- space-separated parts in the right order. Each device string
2195
- contains the name of the corresponding host API in the end.
2196
- The string comparison is case-insensitive.
2194
+ If a string is given, the device is selected which contains all
2195
+ space-separated parts in the right order. Each device string
2196
+ contains the name of the corresponding host API in the end.
2197
+ The string comparison is case-insensitive.
2197
2198
2198
- See Also
2199
- --------
2200
- :func:`query_devices`
2199
+ See Also
2200
+ --------
2201
+ :func:`query_devices`
2201
2202
2202
- """
2203
- channels = _default_channels = None , None
2204
- """Number of input/output channels.
2203
+ """
2204
+ channels = _default_channels = None , None
2205
+ """Number of input/output channels.
2205
2206
2206
- The maximum number of channels for a given device can be found out
2207
- with `query_devices()`.
2207
+ The maximum number of channels for a given device can be found out
2208
+ with `query_devices()`.
2208
2209
2209
- """
2210
- dtype = _default_dtype = 'float32' , 'float32'
2211
- """Data type used for input/output samples.
2210
+ """
2211
+ dtype = _default_dtype = 'float32' , 'float32'
2212
+ """Data type used for input/output samples.
2212
2213
2213
- The types ``'float32'``, ``'int32'``, ``'int16'``, ``'int8'`` and
2214
- ``'uint8'`` can be used for all streams and functions.
2215
- Additionally, `play()`, `rec()` and `playrec()` support
2216
- ``'float64'`` (for convenience, data is merely converted from/to
2217
- ``'float32'``) and `RawInputStream`, `RawOutputStream` and
2218
- `RawStream` support ``'int24'`` (packed 24 bit format, which is
2219
- *not* supported in NumPy!).
2214
+ The types ``'float32'``, ``'int32'``, ``'int16'``, ``'int8'`` and
2215
+ ``'uint8'`` can be used for all streams and functions.
2216
+ Additionally, `play()`, `rec()` and `playrec()` support
2217
+ ``'float64'`` (for convenience, data is merely converted from/to
2218
+ ``'float32'``) and `RawInputStream`, `RawOutputStream` and
2219
+ `RawStream` support ``'int24'`` (packed 24 bit format, which is
2220
+ *not* supported in NumPy!).
2220
2221
2221
- If NumPy is available, the corresponding `numpy.dtype` objects can
2222
- be used as well.
2222
+ If NumPy is available, the corresponding `numpy.dtype` objects can
2223
+ be used as well.
2223
2224
2224
- The floating point representations ``'float32'`` and ``'float64'``
2225
- use +1.0 and -1.0 as the maximum and minimum values, respectively.
2226
- ``'uint8'`` is an unsigned 8 bit format where 128 is considered
2227
- "ground".
2225
+ The floating point representations ``'float32'`` and ``'float64'``
2226
+ use +1.0 and -1.0 as the maximum and minimum values, respectively.
2227
+ ``'uint8'`` is an unsigned 8 bit format where 128 is considered
2228
+ "ground".
2228
2229
2229
- """
2230
- latency = _default_latency = 'high' , 'high'
2231
- """Suggested input/output latency in seconds.
2230
+ """
2231
+ latency = _default_latency = 'high' , 'high'
2232
+ """Suggested input/output latency in seconds.
2232
2233
2233
- The special values ``'low'`` and ``'high'`` can be used to select
2234
- the default low/high latency of the chosen device.
2235
- ``'high'`` is typically more robust (i.e. buffer under-/overflows
2236
- are less likely), but the latency may be too large for interactive
2237
- applications.
2234
+ The special values ``'low'`` and ``'high'`` can be used to select
2235
+ the default low/high latency of the chosen device.
2236
+ ``'high'`` is typically more robust (i.e. buffer under-/overflows
2237
+ are less likely), but the latency may be too large for interactive
2238
+ applications.
2238
2239
2239
- See Also
2240
- --------
2241
- :func:`query_devices`
2240
+ See Also
2241
+ --------
2242
+ :func:`query_devices`
2242
2243
2243
- """
2244
- extra_settings = _default_extra_settings = None , None
2245
- """Host-API-specific input/output settings.
2244
+ """
2245
+ extra_settings = _default_extra_settings = None , None
2246
+ """Host-API-specific input/output settings.
2246
2247
2247
- See Also
2248
- --------
2249
- AsioSettings, CoreAudioSettings, WasapiSettings
2248
+ See Also
2249
+ --------
2250
+ AsioSettings, CoreAudioSettings, WasapiSettings
2250
2251
2251
- """
2252
- samplerate = None
2253
- """Sampling frequency in Hertz (= frames per second).
2252
+ """
2253
+ samplerate = None
2254
+ """Sampling frequency in Hertz (= frames per second).
2254
2255
2255
- See Also
2256
- --------
2257
- :func:`query_devices`
2256
+ See Also
2257
+ --------
2258
+ :func:`query_devices`
2258
2259
2259
- """
2260
- blocksize = _lib .paFramesPerBufferUnspecified
2261
- """See the *blocksize* argument of `Stream`."""
2262
- clip_off = False
2263
- """Disable clipping.
2260
+ """
2261
+ blocksize = _lib .paFramesPerBufferUnspecified
2262
+ """See the *blocksize* argument of `Stream`."""
2263
+ clip_off = False
2264
+ """Disable clipping.
2264
2265
2265
- Set to ``True`` to disable default clipping of out of range samples.
2266
+ Set to ``True`` to disable default clipping of out of range samples.
2266
2267
2267
- """
2268
- dither_off = False
2269
- """Disable dithering.
2268
+ """
2269
+ dither_off = False
2270
+ """Disable dithering.
2270
2271
2271
- Set to ``True`` to disable default dithering.
2272
+ Set to ``True`` to disable default dithering.
2272
2273
2273
- """
2274
- never_drop_input = False
2275
- """Set behavior for input overflow of full-duplex streams.
2276
-
2277
- Set to ``True`` to request that where possible a full duplex stream
2278
- will not discard overflowed input samples without calling the stream
2279
- callback. This flag is only valid for full-duplex callback streams
2280
- (i.e. only `Stream` and `RawStream` and only if *callback* was
2281
- specified; this includes `playrec()`) and only when used in
2282
- combination with ``blocksize=0`` (the default). Using this flag
2283
- incorrectly results in an error being raised. See also
2284
- http://www.portaudio.com/docs/proposals/001-UnderflowOverflowHandling.html.
2274
+ """
2275
+ never_drop_input = False
2276
+ """Set behavior for input overflow of full-duplex streams.
2277
+
2278
+ Set to ``True`` to request that where possible a full duplex stream
2279
+ will not discard overflowed input samples without calling the stream
2280
+ callback. This flag is only valid for full-duplex callback streams
2281
+ (i.e. only `Stream` and `RawStream` and only if *callback* was
2282
+ specified; this includes `playrec()`) and only when used in
2283
+ combination with ``blocksize=0`` (the default). Using this flag
2284
+ incorrectly results in an error being raised. See also
2285
+ http://www.portaudio.com/docs/proposals/001-UnderflowOverflowHandling.html.
2285
2286
2286
- """
2287
- prime_output_buffers_using_stream_callback = False
2288
- """How to fill initial output buffers.
2287
+ """
2288
+ prime_output_buffers_using_stream_callback = False
2289
+ """How to fill initial output buffers.
2289
2290
2290
- Set to ``True`` to call the stream callback to fill initial output
2291
- buffers, rather than the default behavior of priming the buffers
2292
- with zeros (silence). This flag has no effect for input-only
2293
- (`InputStream` and `RawInputStream`) and blocking read/write streams
2294
- (i.e. if *callback* wasn't specified). See also
2295
- http://www.portaudio.com/docs/proposals/020-AllowCallbackToPrimeStream.html.
2291
+ Set to ``True`` to call the stream callback to fill initial output
2292
+ buffers, rather than the default behavior of priming the buffers
2293
+ with zeros (silence). This flag has no effect for input-only
2294
+ (`InputStream` and `RawInputStream`) and blocking read/write streams
2295
+ (i.e. if *callback* wasn't specified). See also
2296
+ http://www.portaudio.com/docs/proposals/020-AllowCallbackToPrimeStream.html.
2296
2297
2297
- """
2298
+ """
2298
2299
2299
- def __init__ (self ):
2300
- for attr in self ._pairs :
2301
- # __setattr__() must be avoided here
2302
- vars (self )[attr ] = _InputOutputPair (self , '_default_' + attr )
2303
-
2304
- def __setattr__ (self , name , value ):
2305
- """Only allow setting existing attributes."""
2306
- if name in self ._pairs :
2307
- getattr (self , name )._pair [:] = _split (value )
2308
- elif name in dir (self ) and name != 'reset' :
2309
- object .__setattr__ (self , name , value )
2310
- else :
2311
- raise AttributeError (
2312
- "'default' object has no attribute " + repr (name ))
2300
+ def __init__ (self ):
2301
+ for attr in self ._pairs :
2302
+ # __setattr__() must be avoided here
2303
+ vars (self )[attr ] = _InputOutputPair (self , '_default_' + attr )
2304
+
2305
+ def __setattr__ (self , name , value ):
2306
+ """Only allow setting existing attributes."""
2307
+ if name in self ._pairs :
2308
+ getattr (self , name )._pair [:] = _split (value )
2309
+ elif name in dir (self ) and name != 'reset' :
2310
+ object .__setattr__ (self , name , value )
2311
+ else :
2312
+ raise AttributeError (
2313
+ "'default' object has no attribute " + repr (name ))
2313
2314
2314
- @property
2315
- def _default_device (self ):
2316
- return (_lib .Pa_GetDefaultInputDevice (),
2317
- _lib .Pa_GetDefaultOutputDevice ())
2315
+ @property
2316
+ def _default_device (self ):
2317
+ return (_lib .Pa_GetDefaultInputDevice (),
2318
+ _lib .Pa_GetDefaultOutputDevice ())
2318
2319
2319
- @property
2320
- def hostapi (self ):
2321
- """Index of the default host API (read-only)."""
2322
- return _check (_lib .Pa_GetDefaultHostApi ())
2320
+ @property
2321
+ def hostapi (self ):
2322
+ """Index of the default host API (read-only)."""
2323
+ return _check (_lib .Pa_GetDefaultHostApi ())
2324
+
2325
+ def reset (self ):
2326
+ """Reset all attributes to their "factory default"."""
2327
+ vars (self ).clear ()
2328
+ self .__init__ ()
2329
+
2330
+ return default
2331
+
2332
+
2333
+ default = _create_default ()
2323
2334
2324
- def reset (self ):
2325
- """Reset all attributes to their "factory default"."""
2326
- vars (self ).clear ()
2327
- self .__init__ ()
2328
2335
2329
2336
if not hasattr (_ffi , 'I_AM_FAKE' ):
2330
2337
# This object shadows the 'default' class, except when building the docs.
@@ -2450,7 +2457,8 @@ def _populate_hostapis():
2450
2457
_HostAPI = _namedtuple ('_HostAPI' , ('name' , 'devices' ,
2451
2458
'default_input_device' ,
2452
2459
'default_output_device' ,
2453
- 'apiname' , 'api' ))
2460
+ 'apiname' , 'api' , 'default' ))
2461
+
2454
2462
class HostAPIs (_namedtuple ('HostAPIs' , (h ['apiname' ] for h in hostapi_list ))):
2455
2463
"""Access to PortAudio Host API's"""
2456
2464
__slots__ = ()
@@ -2460,6 +2468,8 @@ class HostAPIs(_namedtuple('HostAPIs', (h['apiname'] for h in hostapi_list))):
2460
2468
for apiname in missing_apinames :
2461
2469
setattr (HostAPIs , apiname , None )
2462
2470
2471
+ for hostapi in hostapi_list :
2472
+ hostapi ['default' ] = _create_default ()
2463
2473
hostapis = HostAPIs (* (_HostAPI (** h ) for h in hostapi_list ))
2464
2474
2465
2475
@@ -3092,6 +3102,14 @@ def _check_dtype(dtype):
3092
3102
return dtype
3093
3103
3094
3104
3105
+ def _get_device_hostapi (device ):
3106
+ """Find a device's in hostapis"""
3107
+ for hostapi in hostapis :
3108
+ if device in hostapi .devices :
3109
+ return hostapi
3110
+ return None
3111
+
3112
+
3095
3113
def _get_stream_parameters (kind , device , channels , dtype , latency ,
3096
3114
extra_settings , samplerate ):
3097
3115
"""Get parameters for one direction (input or output) of a stream."""
@@ -3110,6 +3128,19 @@ def _get_stream_parameters(kind, device, channels, dtype, latency,
3110
3128
samplerate = default .samplerate
3111
3129
3112
3130
device = _get_device_id (device , kind , raise_on_error = True )
3131
+ hostapi = _get_device_hostapi (device )
3132
+ if hostapi :
3133
+ if channels is None :
3134
+ channels = hostapi .default .channels [kind ]
3135
+ if dtype is None :
3136
+ dtype = hostapi .default .dtype [kind ]
3137
+ if latency is None :
3138
+ latency = hostapi .default .latency [kind ]
3139
+ if extra_settings is None :
3140
+ extra_settings = hostapi .default .extra_settings [kind ]
3141
+ if samplerate is None :
3142
+ samplerate = hostapi .default .samplerate
3143
+
3113
3144
info = query_devices (device )
3114
3145
if channels is None :
3115
3146
channels = info ['max_' + kind + '_channels' ]
0 commit comments