Compare commits

..

3 Commits

Author SHA1 Message Date
Lars Immisch 917a11b398 Report volume like alsamixer. Maybe.
I have no idea how they calculate dB.
2017-11-07 00:57:02 +01:00
Lars Immisch ce84e69cc1 Fix kwargs, and modernize mixertest.py a bit
Preliminary error handling for dB volume settings
2017-11-06 23:32:24 +01:00
Lars Immisch c2cfe0211b Add setting/getting volume in dB.
Potentially breaking change: getvolume now always returns a list of float values,
not integers as before.
2017-11-03 00:01:56 +01:00
7 changed files with 403 additions and 455 deletions
-29
View File
@@ -1,32 +1,3 @@
Version 0.8.6:
- Added four methods to the 'PCM' class to allow users to get detailed information about the device:
- 'getformats()' returns a dictionary of name / value pairs, one for each of the card's
supported formats - e.g. '{"U8": 1, "S16_LE": 2}',
- 'getchannels()' returns a list of the supported channel numbers, e.g. '[1, 2]',
- 'getrates()' returns supported sample rates for the device, e.g. '[48000]',
- 'getratebounds()' returns the device's official minimum and maximum supported
sample rates as a tuple, e.g. '(4000, 48000)'.
(#82 contributed by @jdstmporter)
- Prevent hang on close after capturing audio (#80 contributed by @daym)
Version 0.8.5:
- Return an empty string/bytestring when 'read()' detects an
overrun. Previously the returned data was undefined (contributed by @jcea)
- Unlimited setperiod buffer size when reading frames (contributed by @jcea)
Version 0.8.4:
- Fix Python3 API usage broken in 0.8.3
Version 0.8.3:
- Add DSD sample formats (contributed by @lintweaker)
- Add Mixer.handleevents() to acknowledge events identified by select.poll (contributed by @PaulSD)
- Add functions for listing cards and their names (contributed by @chrisdiamand)
- Add a method for setting enums (contributed by @chrisdiamand)
Version 0.8.2: Version 0.8.2:
- fix #3 (we cannot get the revision from git for pip installs) - fix #3 (we cannot get the revision from git for pip installs)
+376 -407
View File
File diff suppressed because it is too large Load Diff
+13 -9
View File
@@ -443,31 +443,35 @@ Mixer objects have the following methods:
This method will fail if the mixer has no capture switch capabilities. This method will fail if the mixer has no capture switch capabilities.
.. method:: Mixer.getvolume([direction]) .. method:: Mixer.getvolume(direction=PCM_PLAYBACK, unit=Percent)
Returns a list with the current volume settings for each channel. The list Returns a list with the current volume settings for each channel. The list
elements are integer percentages. elements are percentages or dB values, depending on *unit*.
The optional *direction* argument can be either :const:`PCM_PLAYBACK` or The *direction* argument can be either :const:`PCM_PLAYBACK` or
:const:`PCM_CAPTURE`, which is relevant if the mixer can control both :const:`PCM_CAPTURE`, which is relevant if the mixer can control both
playback and capture volume. The default value is :const:`PCM_PLAYBACK` playback and capture volume. The default value is :const:`PCM_PLAYBACK`
if the mixer has playback channels, otherwise it is :const:`PCM_CAPTURE`. if the mixer has playback channels, otherwise it is :const:`PCM_CAPTURE`.
.. method:: Mixer.setvolume(volume, [channel], [direction]) .. method:: Mixer.setvolume(volume, channel=MIXER_CHANNEL_ALL, direction=PCM_PLAYBACK, unit=Percent)
Change the current volume settings for this mixer. The *volume* argument Change the current volume settings for this mixer. The *volume* argument
controls the new volume setting as an integer percentage. controls the new volume setting as either a percentage or a dB value. Both
integer and floating point values can be given.
If the optional argument *channel* is present, the volume is set The *channel* argument can be used to restrict the channels for which the volume is
only for this channel. This assumes that the mixer can control the set. By default, the volume of all channels is adjusted. This assumes that the mixer
volume for the channels independently. can control the volume for the channels independently.
The optional *direction* argument can be either :const:`PCM_PLAYBACK` or The *direction* argument can be either :const:`PCM_PLAYBACK` or
:const:`PCM_CAPTURE`, which is relevant if the mixer can control both :const:`PCM_CAPTURE`, which is relevant if the mixer can control both
playback and capture volume. The default value is :const:`PCM_PLAYBACK` playback and capture volume. The default value is :const:`PCM_PLAYBACK`
if the mixer has playback channels, otherwise it is :const:`PCM_CAPTURE`. if the mixer has playback channels, otherwise it is :const:`PCM_CAPTURE`.
The *unit* argument determines how the volume value is interpreted, as a prcentage
or as a dB value.
.. method:: Mixer.setmute(mute, [channel]) .. method:: Mixer.setmute(mute, [channel])
Sets the mute flag to a new value. The *mute* argument is either 0 for not Sets the mute flag to a new value. The *mute* argument is either 0 for not
+1 -1
View File
@@ -75,7 +75,7 @@ development at the time - and neither are very feature complete.
I wrote PyAlsaAudio to fill this gap. My long term goal is to have the module I wrote PyAlsaAudio to fill this gap. My long term goal is to have the module
included in the standard Python library, but that looks currently unlikely. included in the standard Python library, but that looks currently unlikely.
PyAlsaAudio has full support for sound capture, playback of sound, as well as PyAlsaAudio hass full support for sound capture, playback of sound, as well as
the ALSA Mixer API. the ALSA Mixer API.
MIDI support is not available, and since I don't own any MIDI hardware, it's MIDI support is not available, and since I don't own any MIDI hardware, it's
+11 -7
View File
@@ -46,13 +46,17 @@ def show_mixer(name, kwargs):
print("Capabilities: %s %s" % (' '.join(mixer.volumecap()), print("Capabilities: %s %s" % (' '.join(mixer.volumecap()),
' '.join(mixer.switchcap()))) ' '.join(mixer.switchcap())))
volumes = mixer.getvolume() volumes = mixer.getvolume()
for i in range(len(volumes)): for i, v in enumerate(volumes):
print("Channel %i volume: %i%%" % (i,volumes[i])) print("Channel %i volume: %.02f%%" % (i, v))
volumes = mixer.getvolume(unit=alsaaudio.dB)
for i, v in enumerate(volumes):
print("Channel %i volume: %.02fdB" % (i, v))
try: try:
mutes = mixer.getmute() mutes = mixer.getmute()
for i in range(len(mutes)): for i, m in enumerate(mutes):
if mutes[i]: if m:
print("Channel %i is muted" % i) print("Channel %i is muted" % i)
except alsaaudio.ALSAAudioError: except alsaaudio.ALSAAudioError:
# May not support muting # May not support muting
@@ -60,8 +64,8 @@ def show_mixer(name, kwargs):
try: try:
recs = mixer.getrec() recs = mixer.getrec()
for i in range(len(recs)): for i, r in enumerate(recs):
if recs[i]: if r:
print("Channel %i is recording" % i) print("Channel %i is recording" % i)
except alsaaudio.ALSAAudioError: except alsaaudio.ALSAAudioError:
# May not support recording # May not support recording
+1 -1
View File
@@ -30,7 +30,7 @@ def play(device, f):
else: else:
raise ValueError('Unsupported format') raise ValueError('Unsupported format')
periodsize = f.getframerate() // 8 periodsize = f.getframerate() / 8
device.setperiodsize(periodsize) device.setperiodsize(periodsize)
+1 -1
View File
@@ -8,7 +8,7 @@ from setuptools import setup
from setuptools.extension import Extension from setuptools.extension import Extension
from sys import version from sys import version
pyalsa_version = '0.8.6' pyalsa_version = '0.8.4'
if __name__ == '__main__': if __name__ == '__main__':
setup( setup(