Coverage for src/audioio/audiomodules.py: 79%
405 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-01 19:42 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-01 19:42 +0000
1"""Query and control installation status and availability of audio modules.
3`list_modules()` and `installed_modules()` let you query which audio
4modules are currently installed on your system.
6Call `missing_modules()` for a list of module names that should be
7installed. The `missing_modules_instructions()` function prints
8installation instructions for packages you should install for better
9performance. For installation instructions on a specific module use
10`installation_instruction()`.
12By default all installed modules are used by the audioio functions.
13The `disable_module()`, `enable_module()` and `select_module()`
14functions allow to control which of the installed audio modules
15should be used by the audioio functions.
17`list_modules()`, `available_modules()` and `unavailable_modules()` let
18you query which audio modules are installed and available and which
19modules are not available on your system.
22## Functions
24- `installed_modules()`: installed audio modules.
25- `available_modules()`: installed and enabled audio modules.
26- `unavailable_modules()`: audio modules that are not installed and not enabled.
27- `disable_module()`: disable audio module.
28- `enable_module()`: enable audio modules provided they are installed.
29- `select_module()`: select (enable) a single audio module and disable all others.
30- `list_modules()`: print list of all supported modules and their installation status.
31- `missing_modules()`: missing audio modules that are recommended to be installed.
32- `missing_modules_instructions()`: print installation instructions for missing but useful audio modules.
33- `installation_instruction()`: instructions on how to install a specific audio module.
34- `main()`: command line program for listing installation status of audio modules.
37## Command line script
39Run this module as a script from within the audioio source tree
40```sh
41> python -m src.audioio.auidomodules
42```
43or, once the audioio package is installed on your system, simply run
44```sh
45> audiomodules
46```
47for an overview of audio packages, their installation status, and recommendations on
48how to install further audio packages. The output looks like this:
50```text
51Status of audio packages on this machine:
52-----------------------------------------
54wave is installed (F)
55ewave is installed (F)
56scipy.io.wavfile is installed (F)
57soundfile is installed (F)
58wavefile is installed (F)
59wavpack is installed (F)
60audioread is installed (F)
61pyaudio is installed (D)
62sounddevice not installed (D)
63simpleaudio is installed (D)
64soundcard is installed (D)
65ossaudiodev is installed (D)
66winsound not installed (D)
68F: file I/O, D: audio device
70There is no need to install additional audio packages.
71```
73For instructions on specific packages, run `audiomodules` with the name of
74the package supplied as argument:
76```sh
77> audiomodules soundfile
78```
79This produces something like this:
80```text
81...
82Installation instructions for the soundfile module:
83---------------------------------------------------
84The soundfile package is a wrapper of the sndfile library,
85that supports many different audio file formats.
86See http://python-soundfile.readthedocs.org for a documentation of the soundfile python wrapper
87and http://www.mega-nerd.com/libsndfile for details on the sndfile library.
89First, install the following packages:
91sudo apt install libsndfile1 libsndfile1-dev libffi-dev
93Install the soundfile module with pip:
95sudo pip install SoundFile
97or alternatively from your distribution's package:
99sudo apt install python3-soundfile
100```
102Running
103```sh
104audiomodules --help
105```
106prints
107```text
108usage: audiomodules [--version] [--help] [PACKAGE]
110Installation status and instructions of python audio packages.
112optional arguments:
113 --help show this help message and exit
114 --version show version number and exit
115 PACKAGE show installation instructions for PACKAGE
117version 2.2.0 by Benda-Lab (2015-2024)
118```
120## Links
122For an overview on python modules regarding file I/O see, for example,
123http://nbviewer.jupyter.org/github/mgeier/python-audio/blob/master/audio-files/index.ipynb
125For an overview on packages for playing and recording audio, see
126https://realpython.com/playing-and-recording-sound-python/
128"""
130import sys
131import os
133from .version import __version__, __year__
136audio_modules = {}
137""" Dictionary with availability of various audio modules.
138Keys are the module names, values are booleans.
139Based on this dictionary audioio employs functions of installed audio modules. """
141audio_installed = []
142""" List of installed audio modules. """
144audio_infos = {}
145""" Dictionary with information about all supported audio modules.
146Keys are the module names, values are the informations. """
148audio_instructions_linux = {}
149""" Dictionary with general installation instructions for linux that
150are needed in addition to installing some packages.
151Keys are the module names, values are the instructions. """
153audio_instructions_windows = {}
154""" Dictionary with general installation instructions for windows that
155are needed in addition to installing some packages.
156Keys are the module names, values are the instructions. """
158audio_pip_packages = {}
159""" Dictionary with pip package names of the audio modules.
160Keys are the module names, values are pip package names. """
162audio_conda_packages = {}
163""" Dictionary with conda package names of the audio modules.
164Keys are the module names, values are conda package names,
165optionally with a channel specification. """
167audio_deb_packages = {}
168""" Dictionary with Linux DEB packages of the audio modules.
169Keys are the module names, values are the package names. """
171audio_rpm_packages = {}
172""" Dictionary with Linux RPM packages of the audio modules.
173Keys are the module names, values are the package names. """
175audio_brew_packages = {}
176""" Dictionary with macOS homebrew packages of the audio modules.
177Keys are the module names, values are the package (formulae) names. """
179audio_required_deb_packages = {}
180""" Dictionary with Linux DEB packages required for the audio modules.
181Keys are the module names, values are lists of string with package names. """
183audio_required_rpm_packages = {}
184""" Dictionary with Linux RPM packages required for the audio modules.
185Keys are the module names, values are lists of string with package names. """
187audio_required_brew_packages = {}
188""" Dictionary with macOS homebrew packages required for the audio modules.
189Keys are the module names, values are lists of string with package (formulae) names. """
191audio_fileio = []
192""" List of audio modules used for reading and writing audio files. """
194audio_device = []
195""" List of audio modules used for playing and recording sounds on audio devices. """
198# probe for available audio modules:
200audio_fileio.append('wave')
201try:
202 import wave
203 audio_modules['wave'] = True
204 audio_installed.append('wave')
205except ImportError:
206 audio_modules['wave'] = False
207audio_infos['wave'] = """The wave module is part of the standard python library.
208For documentation see https://docs.python.org/3.8/library/wave.html"""
210audio_fileio.append('ewave')
211try:
212 import ewave
213 audio_modules['ewave'] = True
214 audio_installed.append('ewave')
215except ImportError:
216 audio_modules['ewave'] = False
217audio_pip_packages['ewave'] = 'ewave'
218audio_conda_packages['ewave'] = '-c auto ewave'
219audio_infos['ewave'] = """The ewave package supports more types of WAV-files than the standard wave module.
220For documentation see https://github.com/melizalab/py-ewave"""
222audio_fileio.append('scipy.io.wavfile')
223try:
224 from scipy.io import wavfile
225 audio_modules['scipy.io.wavfile'] = True
226 audio_installed.append('scipy.io.wavfile')
227except ImportError:
228 audio_modules['scipy.io.wavfile'] = False
229audio_pip_packages['scipy.io.wavfile'] = 'scipy'
230audio_conda_packages['scipy.io.wavfile'] = 'scipy'
231audio_deb_packages['scipy.io.wavfile'] = 'python3-scipy'
232audio_rpm_packages['scipy.io.wavfile'] = 'python3-scipy'
233audio_brew_packages['scipy.io.wavfile'] = 'scipy'
234audio_infos['scipy.io.wavfile'] = """The scipy package provides very basic functions for reading WAV files.
235For documentation see http://docs.scipy.org/doc/scipy/reference/io.html"""
237audio_fileio.append('soundfile')
238try:
239 import soundfile
240 audio_modules['soundfile'] = True
241 audio_installed.append('soundfile')
242except ImportError:
243 audio_modules['soundfile'] = False
244audio_pip_packages['soundfile'] = 'SoundFile'
245audio_conda_packages['soundfile'] = '-c conda-forge soundfile'
246audio_deb_packages['soundfile'] = 'python3-soundfile'
247audio_required_deb_packages['soundfile'] = ['libsndfile1', 'libsndfile1-dev', 'libffi-dev']
248audio_required_rpm_packages['soundfile'] = ['libsndfile', 'libsndfile-devel', 'libffi-devel']
249audio_infos['soundfile'] = """The soundfile package is a wrapper of the sndfile library,
250that supports many different audio file formats.
251See http://python-soundfile.readthedocs.org for a documentation of the soundfile python wrapper
252and http://www.mega-nerd.com/libsndfile for details on the sndfile library."""
254audio_fileio.append('wavefile')
255try:
256 import wavefile
257 audio_modules['wavefile'] = True
258 audio_installed.append('wavefile')
259except ImportError:
260 audio_modules['wavefile'] = False
261audio_pip_packages['wavefile'] = 'wavefile'
262audio_required_deb_packages['wavefile'] = ['libsndfile1', 'libsndfile1-dev', 'libffi-dev']
263audio_required_rpm_packages['wavefile'] = ['libsndfile', 'libsndfile-devel', 'libffi-devel']
264audio_required_brew_packages['wavefile'] = ['libsndfile', 'libffi']
265audio_infos['wavefile'] = """The wavefile package is a wrapper of the sndfile library,
266that supports many different audio file formats.
267See https://github.com/vokimon/python-wavefile for documentation of the wavefile python wrapper
268and http://www.mega-nerd.com/libsndfile for details on the sndfile library."""
270audio_fileio.append('wavpack')
271try:
272 import ctypes
273 wavpack = ctypes.CDLL('libwavpack.so.1')
274 wavpack.WavpackOpenFileInput.restype = ctypes.c_void_p
275 wavpack.WavpackGetNumSamples64.restype = ctypes.c_int64
276 wavpack.WavpackGetWrapperData.restype = ctypes.POINTER(ctypes.c_ubyte)
277 wavpack.WavpackSeekSample64.argtypes = [ctypes.c_void_p, ctypes.c_int64]
278 wavpack.WavpackUnpackSamples.argtypes = [ctypes.c_void_p,
279 ctypes.POINTER(ctypes.c_int32),
280 ctypes.c_uint32]
281 audio_modules['wavpack'] = True
282 audio_installed.append('wavpack')
283except (OSError, AttributeError): # no library or too old
284 audio_modules['wavpack'] = False
285audio_deb_packages['wavpack'] = 'libwavpack1'
286audio_rpm_packages['wavpack'] = 'wavpack-libs'
287audio_brew_packages['wavpack'] = 'wavpack'
288audio_infos['wavpack'] = """The wavpack library reads WavPack files, a lossless compression of audio data.
289It is called via ctypes, no python package is needed.
290For documentation see https://www.wavpack.com"""
292audio_fileio.append('audioread')
293try:
294 import audioread
295 audio_modules['audioread'] = True
296 audio_installed.append('audioread')
297except ImportError:
298 audio_modules['audioread'] = False
299audio_pip_packages['audioread'] = 'audioread'
300audio_conda_packages['audioread'] = '-c conda-forge audioread'
301audio_deb_packages['audioread'] = 'python3-audioread'
302audio_rpm_packages['audioread'] = 'python3-audioread'
303audio_required_deb_packages['audioread'] = ['ffmpeg', 'libavcodec-extra']
304audio_required_rpm_packages['audioread'] = ['ffmpeg', 'ffmpeg-devel', 'libavcodec-extra']
305audio_required_brew_packages['audioread'] = ['libav --with-libvorbis --with-sdl --with-theora', 'ffmpeg --with-libvorbis --with-sdl2 --with-theora']
306audio_infos['audioread'] = """The audioread package uses libav (https://libav.org/) or ffmpeg (https://ffmpeg.org/) to make mpeg files readable.
307Install this package for reading mpeg files.
308For documentation see https://github.com/beetbox/audioread"""
310audio_fileio.append('pydub')
311try:
312 import pydub
313 audio_modules['pydub'] = True
314 audio_installed.append('pydub')
315except ImportError:
316 audio_modules['pydub'] = False
317audio_pip_packages['pydub'] = 'pydub'
318audio_conda_packages['pydub'] = '-c conda-forge pydub'
319audio_deb_packages['pydub'] = 'python3-pydub'
320audio_rpm_packages['pydub'] = 'python3-pydub'
321audio_required_deb_packages['pydub'] = ['ffmpeg', 'libavcodec-extra']
322audio_required_rpm_packages['pydub'] = ['ffmpeg', 'ffmpeg-devel', 'libavcodec-extra']
323audio_required_brew_packages['pydub'] = ['libav --with-libvorbis --with-sdl --with-theora', 'ffmpeg --with-libvorbis --with-sdl2 --with-theora']
324audio_infos['pydub'] = """The pydub package uses libav (https://libav.org/) or ffmpeg (https://ffmpeg.org/) to make mpeg files readable and writeable.
325Install this package if you need to write mpeg files.
326For documentation see https://github.com/jiaaro/pydub"""
328audio_device.append('pyaudio')
329try:
330 import pyaudio
331 audio_modules['pyaudio'] = True
332 audio_installed.append('pyaudio')
333except ImportError:
334 audio_modules['pyaudio'] = False
335audio_pip_packages['pyaudio'] = 'PyAudio'
336audio_conda_packages['pyaudio'] = 'pyaudio'
337audio_deb_packages['pyaudio'] = 'python3-pyaudio # WARNING: broken on Ubuntu with python 3.10, use pip instead'
338audio_rpm_packages['pyaudio'] = 'python3-pyaudio'
339audio_required_deb_packages['pyaudio'] = ['libportaudio2']
340audio_required_rpm_packages['pyaudio'] = ['libportaudio', 'portaudio-devel']
341audio_required_brew_packages['pyaudio'] = ['portaudio']
342audio_infos['pyaudio'] = """The pyaudio package is a wrapper of the portaudio library (http://www.portaudio.com).
343This is an alternative to the sounddevice package with similar properties.
344For documentation see https://people.csail.mit.edu/hubert/pyaudio."""
345audio_instructions_windows['pyaudio'] = """Download an appropriate (latest version, 32 or 64 bit) wheel from
346<https://www.lfd.uci.edu/~gohlke/pythonlibs/#pyaudio>. Install this file with pip,
347that is go to the folder where the wheel file is downloaded and run
349pip install PyAudio-0.2.11-cp39-cp39-win_amd64.whl
351replace the wheel file name by the one you downloaded."""
353audio_device.append('sounddevice')
354try:
355 import sounddevice
356 audio_modules['sounddevice'] = True
357 audio_installed.append('sounddevice')
358except ImportError:
359 audio_modules['sounddevice'] = False
360audio_pip_packages['sounddevice'] = 'sounddevice'
361audio_conda_packages['sounddevice'] = '-c conda-forge python-sounddevice'
362audio_required_deb_packages['sounddevice'] = ['libportaudio2', 'python3-cffi']
363audio_required_rpm_packages['sounddevice'] = ['libportaudio', 'portaudio-devel', 'python3-cffi']
364audio_required_brew_packages['sounddevice'] = ['portaudio']
365audio_infos['sounddevice'] = """The sounddevice package is a wrapper of the portaudio library (http://www.portaudio.com).
366For documentation see https://python-sounddevice.readthedocs.io"""
368audio_device.append('simpleaudio')
369try:
370 import simpleaudio
371 audio_modules['simpleaudio'] = True
372 audio_installed.append('simpleaudio')
373except ImportError:
374 audio_modules['simpleaudio'] = False
375audio_pip_packages['simpleaudio'] = 'simpleaudio'
376audio_rpm_packages['simpleaudio'] = 'python3-simpleaudio'
377audio_required_deb_packages['simpleaudio'] = ['python3-dev', 'libasound2-dev']
378audio_required_rpm_packages['simpleaudio'] = ['python3-devel', 'alsa-lib', 'alsa-lib-devel']
379audio_infos['simpleaudio'] = """The simpleaudio package is a lightweight package
380for cross-platform audio playback.
381Unfortunately, this package is no longer maintained.
382For documentation see https://simpleaudio.readthedocs.io"""
384audio_device.append('soundcard')
385try:
386 import soundcard
387 audio_modules['soundcard'] = True
388 audio_installed.append('soundcard')
389except ImportError:
390 audio_modules['soundcard'] = False
391except AssertionError:
392 audio_modules['soundcard'] = False
393audio_pip_packages['soundcard'] = 'soundcard'
394audio_infos['soundcard'] = """SoundCard is a library for playing and recording audio without
395resorting to a CPython extension. Instead, it is implemented using the
396wonderful CFFI and the native audio libraries of Linux, Windows and
397macOS.
398For documentation see https://github.com/bastibe/SoundCard"""
400audio_device.append('ossaudiodev')
401try:
402 import ossaudiodev
403 audio_modules['ossaudiodev'] = True
404 audio_installed.append('ossaudiodev')
405except ImportError:
406 audio_modules['ossaudiodev'] = False
407audio_required_deb_packages['ossaudiodev'] = ['osspd']
408audio_infos['ossaudiodev'] = """The ossaudiodev module is part of the python standard library and
409provides simple support for sound playback under Linux based on the (outdated) OSS system.
410You most likely want to install the simpleaudio or the soundfile package for better performance.
411For documentation see https://docs.python.org/3.8/library/ossaudiodev.html"""
413audio_device.append('winsound')
414try:
415 import winsound
416 audio_modules['winsound'] = True
417 audio_installed.append('winsound')
418except ImportError:
419 audio_modules['winsound'] = False
420audio_infos['winsound'] = """The winsound module is part of the python standard library and
421provides simple support for sound playback under Windows. If possible,
422install the simpleaudio package in addition for better performance.
423For documentation see https://docs.python.org/3.6/library/winsound.html and
424https://mail.python.org/pipermail/tutor/2012-September/091529.html"""
427def installed_modules(func='all'):
428 """Installed audio modules.
430 By default all installed modules are available. With
431 `disable_module()`, `enable_module()` and `select_module()`
432 the availability of installed modules can be controlled.
434 Parameters
435 ----------
436 func: string
437 'all': all installed audio modules.
438 'fileio': installed audio modules used for file I/O.
439 'device': installed audio modules used for playing and recording sounds.
441 Returns
442 -------
443 mods: list of strings
444 List of installed audio modules of the requested function.
446 See Also
447 --------
448 available_modules()
449 """
450 if func == 'fileio':
451 return [module for module in audio_fileio if module in audio_installed]
452 elif func == 'device':
453 return [module for module in audio_device if module in audio_installed]
454 else:
455 return audio_installed
458def available_modules(func='all'):
459 """Installed and enabled audio modules.
461 By default all installed modules are available. With
462 `disable_module()`, `enable_module()` and `select_module()`
463 the availability of installed modules can be controlled.
465 Parameters
466 ----------
467 func: string
468 'all': all installed audio modules.
469 'fileio': installed audio modules used for file I/O.
470 'device': installed audio modules used for playing and recording sounds.
472 Returns
473 -------
474 mods: list of strings
475 List of available, i.e. installed and enabled, audio modules
476 of the requested function.
477 """
478 if func == 'fileio':
479 return [module for module in audio_fileio if audio_modules[module]]
480 elif func == 'device':
481 return [module for module in audio_device if audio_modules[module]]
482 else:
483 return [module for module in audio_installed if audio_modules[module]]
486def unavailable_modules(func='all'):
487 """Audio modules that are not installed and not enabled.
489 Parameters
490 ----------
491 func: string
492 'all': all installed audio modules.
493 'fileio': installed audio modules used for file I/O.
494 'device': installed audio modules used for playing and recording sounds.
496 Returns
497 -------
498 mods: list of strings
499 List of not available, i.e. not installed and not enabled, audio modules
500 of the requested function.
501 """
502 if func == 'fileio':
503 return [module for module in audio_fileio if not audio_modules[module]]
504 elif func == 'device':
505 return [module for module in audio_device if not audio_modules[module]]
506 else:
507 return [module for module in audio_modules.keys() if not audio_modules[module]]
510def disable_module(module=None):
511 """Disable an audio module.
513 A disabled module is not used by the audioio functions and classes.
514 To disable all modules except one, call `select_module()`.
516 Parameters
517 ----------
518 module: string or None
519 Name of the module to be disabled as it appears in `available_modules()`.
520 If None disable all installed audio modules.
522 See Also
523 --------
524 enable_module(), select_module(), available_modules(), list_modules()
525 """
526 if module is None:
527 for module in audio_installed:
528 audio_modules[module] = False
529 elif module in audio_modules:
530 audio_modules[module] = False
533def enable_module(module=None):
534 """Enable audio modules provided they are installed.
536 Parameters
537 ----------
538 module: string or None
539 Name of the module to be (re)enabled.
540 If None enable all installed audio modules.
542 See Also
543 --------
544 disable_module(), available_modules(), list_modules()
545 """
546 if module is None:
547 for module in audio_installed:
548 audio_modules[module] = True
549 elif module in audio_modules:
550 audio_modules[module] = (module in audio_installed)
553def select_module(module):
554 """Select (enable) a single audio module and disable all others.
556 Undo by calling `enable_module()` without arguments.
558 Parameters
559 ----------
560 module: string
561 Name of the module to be selected.
563 Returns
564 -------
565 selected: bool
566 False if the module can not be selected, because it is not installed.
567 In this case the other modules are not disabled.
569 See Also
570 --------
571 enable_module(), disable_module(), available_modules(), list_modules()
572 """
573 if module not in audio_installed:
574 return False
575 for mod in audio_installed:
576 audio_modules[mod] = (mod == module)
577 return True
580def list_modules(module='all', availability=True):
581 """Print list of all supported modules and their installation status.
583 Modules that are not installed but are recommended are marked
584 with an all uppercase "NOT installed".
586 Parameters
587 ----------
588 module: string
589 If 'all' list all modules.
590 If 'fileio' list all modules used for file I/O.
591 If 'device' list all modules used for playing and recording sounds.
592 Otherwise list only the specified module.
593 availability: bool
594 Mark availability of each module by an asterisk.
596 See Also
597 --------
598 installed_modules()
599 missing_modules()
600 missing_modules_instructions()
601 """
602 def print_module(module, missing, print_type):
603 audio_avail = ''
604 if availability:
605 audio_avail = '* ' if audio_modules[module] else ' '
606 audio_type = ''
607 if print_type:
608 if module in audio_fileio:
609 audio_type += 'F'
610 if module in audio_device:
611 audio_type += 'D'
612 if len(audio_type) > 0:
613 audio_type = f' ({audio_type})'
614 if module in audio_installed:
615 print(f'{audio_avail}{module:<17s} is installed{audio_type}')
616 elif module in missing:
617 print(f'{audio_avail}{module:<17s} NOT installed{audio_type}')
618 else:
619 print(f'{audio_avail}{module:<17s} not installed{audio_type}')
621 missing = missing_modules()
622 if module not in ['all', 'fileio', 'device']:
623 print_module(module, missing, True)
624 else:
625 print_type = (module == 'all')
626 modules = sorted(audio_modules.keys())
627 if module in ['all', 'fileio']:
628 for mod in audio_fileio:
629 print_module(mod, missing, print_type)
630 modules.remove(mod)
631 if module in ['all', 'device']:
632 for mod in audio_device:
633 if mod in modules:
634 print_module(mod, missing, print_type)
635 modules.remove(mod)
636 if module == 'all':
637 for mod in modules:
638 print_module(mod, missing, print_type)
641def missing_modules(func='all'):
642 """Missing audio modules that are recommended to be installed.
644 Parameters
645 ----------
646 func: string
647 'all': missing audio modules of all functions.
648 'fileio': missing audio modules for file I/O.
649 'device': missing audio modules for playing and recording sounds.
651 Returns
652 -------
653 mods: list of strings
654 List of missing audio modules of the requested function.
655 """
656 mods = []
657 if func in ['all', 'fileio']:
658 if 'soundfile' not in audio_installed and \
659 'wavefile' not in audio_installed:
660 mods.append('soundfile')
661 if 'audioread' not in audio_installed:
662 mods.append('audioread')
663 if 'pydub' not in audio_installed:
664 mods.append('pydub')
665 if func in ['all', 'device']:
666 if 'pyaudio' not in audio_installed and \
667 'sounddevice' not in audio_installed:
668 mods.append('sounddevice')
669 return mods
672def missing_modules_instructions(func='all'):
673 """Print installation instructions for missing but useful audio modules.
675 Parameters
676 ----------
677 func: string
678 'all': missing audio modules of all functions.
679 'fileio': missing audio modules for file I/O.
680 'device': missing audio modules for playing and recording sounds.
681 """
682 mods = missing_modules(func)
683 if len(mods) > 0 :
684 print('For better performance you should install the following modules:')
685 for mod in mods:
686 print()
687 print(f'{mod}:')
688 print('-'*(len(mod)+1))
689 print(installation_instruction(mod))
690 else:
691 print('There is no need to install additional audio packages.')
694def installation_instruction(module):
695 """Instructions on how to install a specific audio module.
697 Parameters
698 ----------
699 module: string
700 The name of the module for which an instruction should be printed.
702 Returns
703 -------
704 msg: multi-line string
705 Installation instruction for the requested module.
706 """
707 install_package_deb = "sudo apt install"
708 install_package_rpm = "dnf install"
709 install_package_brew = "brew install"
710 install_package = None
711 package = None
712 required_packages = None
713 multiline = False
714 instruction = None
716 install_pip_deb = "sudo pip install"
717 install_pip_rpm = "pip install"
718 install_pip_osx = "pip install"
719 install_pip_win = "pip install"
720 install_pip = install_pip_deb
722 install_conda = "conda install"
724 # check operating system:
725 if sys.platform[0:5] == "linux":
726 if os.path.exists('/etc/redhat-release') or os.path.exists('/etc/fedora-release'):
727 install_package = install_package_rpm
728 install_pip = install_pip_rpm
729 package = audio_rpm_packages.get(module, None)
730 required_packages = audio_required_rpm_packages.get(module, None)
731 else:
732 install_package = install_package_deb
733 package = audio_deb_packages.get(module, None)
734 required_packages = audio_required_deb_packages.get(module, None)
735 instruction = audio_instructions_linux.get(module, None)
736 elif sys.platform == "darwin":
737 install_package = install_package_brew
738 install_pip = install_pip_osx
739 package = audio_brew_packages.get(module, None)
740 required_packages = audio_required_brew_packages.get(module, None)
741 multiline = True
742 elif sys.platform[0:3] == "win":
743 install_package = ''
744 install_pip = install_pip_win
745 instruction = audio_instructions_windows.get(module, None)
746 # check conda:
747 conda = "CONDA_DEFAULT_ENV" in os.environ
748 conda_package = audio_conda_packages.get(module, None)
749 if conda:
750 install_pip = install_pip.replace('sudo ', '')
752 pip_package = audio_pip_packages.get(module, None)
754 req_inst = None
755 if required_packages is not None:
756 if multiline:
757 ps = '\n'.join([install_package + ' ' + p for p in required_packages])
758 else:
759 ps = install_package + ' ' + ' '.join(required_packages)
760 if pip_package is None and package is None:
761 req_inst = 'Install the following packages:\n\n' + ps
762 else:
763 req_inst = 'First, install the following packages:\n\n' + ps
765 pip_inst = None
766 if pip_package is not None:
767 pip_inst = f'Install the {module} module with pip:\n\n{install_pip} {pip_package}'
769 dist_inst = None
770 if package is not None:
771 if pip_inst is None:
772 dist_inst = f'Install module from your distribution\'s package:\n\n{install_package} {package}'
773 else:
774 dist_inst = f'or alternatively from your distribution\'s package:\n\n{install_package} {package}'
776 conda_inst = None
777 if conda and conda_package is not None:
778 conda_inst = f'Install the {module} module with conda:\n\n{install_package} {package}'
779 req_inst = pip_inst = dist_inst = instruction = None
781 info = audio_infos.get(module, None)
783 msg = ''
784 for s in [info, conda_inst, req_inst, pip_inst, dist_inst, instruction]:
785 if s is not None:
786 if len(msg) > 0:
787 msg += '\n\n'
788 msg += s
790 return msg
793def main(*args):
794 """ Command line program for listing installation status of audio modules.
796 Run this module as a script
797 ```
798 > python -m src.audioio.auidomodules
799 ```
800 or, when the audioio package is installed on your system, simply run
801 ```sh
802 > audiomodules
803 ```
804 for an overview of audio packages, their installation status, and recommendations on
805 how to install further audio packages.
807 The '--help' argument prints out a help message:
808 ```sh
809 > audiomodules --help
810 ```
812 Parameters
813 ----------
814 args: list of strings
815 Command line arguments as provided by sys.argv[1:]
816 """
817 if len(args) == 0:
818 args = sys.argv[1:]
819 if len(args) > 0:
820 if args[0] == '--version':
821 print(f'version {__version__} by Benda-Lab (2015-{__year__})')
822 sys.exit(0)
823 if args[0] == '--help' or args[0] == '-h':
824 print('usage: audiomodules [--version] [--help] [PACKAGE]')
825 print('')
826 print('Installation status and instructions of python audio packages.')
827 print('')
828 print('optional arguments:')
829 print(' --help show this help message and exit')
830 print(' --version show version number and exit')
831 print(' PACKAGE show installation instructions for PACKAGE')
832 print('')
833 print(f'version {__version__} by Benda-Lab (2015-{__year__})')
834 return
836 print('')
837 if len(args) > 0 :
838 mod = args[0]
839 if mod in audio_modules:
840 print(f'Installation instructions for the {mod} module:')
841 print('-'*(42+len(mod)))
842 print(installation_instruction(mod))
843 print('')
844 else:
845 print('Status of audio packages on this machine:')
846 print('-'*41)
847 print('')
848 list_modules('all', False)
849 print('')
850 print('F: file I/O, D: audio device')
851 print('')
852 missing_modules_instructions()
853 print('')
856if __name__ == "__main__":
857 main(*sys.argv[1:])