Skip to content

Commit a63c02f

Browse files
committed
release 1.20 with miniaudio 0.10.4
1 parent b874309 commit a63c02f

File tree

2 files changed

+341
-7
lines changed

2 files changed

+341
-7
lines changed

README.md

Lines changed: 340 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,19 @@ This module provides:
1515
- python bindings for most of the functions offered in those libraries:
1616
- reading and decoding audio files
1717
- getting audio file properties (such as duration, number of channels, sample rate)
18-
- converting sample formats
18+
- converting sample formats and frequencies
1919
- streaming large audio files
2020
- audio playback
2121
- audio recording
22+
- TODO: filters
23+
- TODO: waveform generators
24+
2225

2326
This library aims to provide a Pythonic interface to the miniaudio C library.
2427
Some of the main aspects of this are:
2528
- Python enums instead of just some integers for special values,
2629
- several classes to represent the main functions of the library,
27-
- generators for the Audio playback, recording and conversion streaming
30+
- generators for the Audio playback and recording
2831
- sample data is usually in the form of a Python ``array`` with appropriately sized elements
2932
depending on the sample width (rather than a raw block of bytes)
3033

@@ -82,7 +85,7 @@ def stream_pcm(source):
8285
print(".", end="", flush=True)
8386
required_frames = yield sample_data
8487

85-
with miniaudio.PlaybackDevice(ma_output_format=miniaudio.ma_format_s16,
88+
with miniaudio.PlaybackDevice(output_format=miniaudio.SampleFormat.SIGNED16,
8689
nchannels=channels, sample_rate=sample_rate) as device:
8790
ffmpeg = subprocess.Popen(["ffmpeg", "-v", "fatal", "-hide_banner", "-nostdin",
8891
"-i", filename, "-f", "s16le", "-acodec", "pcm_s16le",
@@ -98,4 +101,337 @@ with miniaudio.PlaybackDevice(ma_output_format=miniaudio.ma_format_s16,
98101
## API
99102

100103

101-
TODO recreate this when the new wrapper cffi code has been tested and adapted to the new miniaudio 0.10 api
104+
*enum class* ``Backend``
105+
names: ``WASAPI`` ``DSOUND`` ``WINMM`` ``COREAUDIO`` ``SNDIO`` ``AUDIO4`` ``OSS`` ``PULSEAUDIO`` ``ALSA`` ``JACK`` ``AAUDIO`` ``OPENSL`` ``WEBAUDIO`` ``NULL``
106+
> Operating system audio backend to use (only a subset will be available)
107+
108+
109+
*enum class* ``ChannelMixMode``
110+
names: ``RECTANGULAR`` ``SIMPLE`` ``CUSTOMWEIGHTS``
111+
> How to mix channels when converting
112+
113+
114+
*enum class* ``DeviceType``
115+
names: ``PLAYBACK`` ``CAPTURE`` ``DUPLEX``
116+
> Type of audio device
117+
118+
119+
*enum class* ``DitherMode``
120+
names: ``NONE`` ``RECTANGLE`` ``TRIANGLE``
121+
> How to dither when converting
122+
123+
124+
*enum class* ``FileFormat``
125+
names: ``UNKNOWN`` ``WAV`` ``FLAC`` ``VORBIS`` ``MP3``
126+
> Audio file format
127+
128+
129+
*enum class* ``SampleFormat``
130+
names: ``UNKNOWN`` ``UNSIGNED8`` ``SIGNED16`` ``SIGNED24`` ``SIGNED32`` ``FLOAT32``
131+
> Sample format in memory
132+
133+
134+
*enum class* ``SeekOrigin``
135+
names: ``START`` ``CURRENT``
136+
> How to seek() in a source
137+
138+
139+
*enum class* ``ThreadPriority``
140+
names: ``IDLE`` ``LOWEST`` ``LOW`` ``NORMAL`` ``HIGH`` ``HIGHEST`` ``REALTIME``
141+
> The priority of the worker thread (default=HIGHEST)
142+
143+
144+
*function* ``convert_frames (from_fmt: miniaudio.SampleFormat, from_numchannels: int, from_samplerate: int, sourcedata: bytes, to_fmt: miniaudio.SampleFormat, to_numchannels: int, to_samplerate: int) -> bytearray``
145+
> Convert audio frames in source sample format with a certain number of channels, to another sample
146+
format and possibly down/upmixing the number of channels as well.
147+
148+
149+
*function* ``convert_sample_format (from_fmt: miniaudio.SampleFormat, sourcedata: bytes, to_fmt: miniaudio.SampleFormat, dither: miniaudio.DitherMode = <DitherMode.NONE: 0>) -> bytearray``
150+
> Convert a raw buffer of pcm samples to another sample format. The result is returned as another
151+
raw pcm sample buffer
152+
153+
154+
*function* ``decode (data: bytes, output_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, nchannels: int = 2, sample_rate: int = 44100, dither: miniaudio.DitherMode = <DitherMode.NONE: 0>) -> miniaudio.DecodedSoundFile``
155+
> Convenience function to decode any supported audio file in memory to raw PCM samples in your
156+
chosen format.
157+
158+
159+
*function* ``decode_file (filename: str, output_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, nchannels: int = 2, sample_rate: int = 44100, dither: miniaudio.DitherMode = <DitherMode.NONE: 0>) -> miniaudio.DecodedSoundFile``
160+
> Convenience function to decode any supported audio file to raw PCM samples in your chosen format.
161+
162+
163+
*function* ``flac_get_file_info (filename: str) -> miniaudio.SoundFileInfo``
164+
> Fetch some information about the audio file (flac format).
165+
166+
167+
*function* ``flac_get_info (data: bytes) -> miniaudio.SoundFileInfo``
168+
> Fetch some information about the audio data (flac format).
169+
170+
171+
*function* ``flac_read_f32 (data: bytes) -> miniaudio.DecodedSoundFile``
172+
> Reads and decodes the whole flac audio file. Resulting sample format is 32 bits float.
173+
174+
175+
*function* ``flac_read_file_f32 (filename: str) -> miniaudio.DecodedSoundFile``
176+
> Reads and decodes the whole flac audio file. Resulting sample format is 32 bits float.
177+
178+
179+
*function* ``flac_read_file_s16 (filename: str) -> miniaudio.DecodedSoundFile``
180+
> Reads and decodes the whole flac audio file. Resulting sample format is 16 bits signed integer.
181+
182+
183+
*function* ``flac_read_file_s32 (filename: str) -> miniaudio.DecodedSoundFile``
184+
> Reads and decodes the whole flac audio file. Resulting sample format is 32 bits signed integer.
185+
186+
187+
*function* ``flac_read_s16 (data: bytes) -> miniaudio.DecodedSoundFile``
188+
> Reads and decodes the whole flac audio data. Resulting sample format is 16 bits signed integer.
189+
190+
191+
*function* ``flac_read_s32 (data: bytes) -> miniaudio.DecodedSoundFile``
192+
> Reads and decodes the whole flac audio data. Resulting sample format is 32 bits signed integer.
193+
194+
195+
*function* ``flac_stream_file (filename: str, frames_to_read: int = 1024, seek_frame: int = 0) -> Generator[array.array, NoneType, NoneType]``
196+
> Streams the flac audio file as interleaved 16 bit signed integer sample arrays segments. This uses
197+
a fixed chunk size and cannot be used as a generic miniaudio decoder input stream. Consider using
198+
stream_file() instead.
199+
200+
201+
*function* ``get_file_info (filename: str) -> miniaudio.SoundFileInfo``
202+
> Fetch some information about the audio file.
203+
204+
205+
*function* ``mp3_get_file_info (filename: str) -> miniaudio.SoundFileInfo``
206+
> Fetch some information about the audio file (mp3 format).
207+
208+
209+
*function* ``mp3_get_info (data: bytes) -> miniaudio.SoundFileInfo``
210+
> Fetch some information about the audio data (mp3 format).
211+
212+
213+
*function* ``mp3_read_f32 (data: bytes, want_nchannels: int = 0, want_sample_rate: int = 0) -> miniaudio.DecodedSoundFile``
214+
> Reads and decodes the whole mp3 audio data. Resulting sample format is 32 bits float.
215+
216+
217+
*function* ``mp3_read_file_f32 (filename: str, want_nchannels: int = 0, want_sample_rate: int = 0) -> miniaudio.DecodedSoundFile``
218+
> Reads and decodes the whole mp3 audio file. Resulting sample format is 32 bits float.
219+
220+
221+
*function* ``mp3_read_file_s16 (filename: str, want_nchannels: int = 0, want_sample_rate: int = 0) -> miniaudio.DecodedSoundFile``
222+
> Reads and decodes the whole mp3 audio file. Resulting sample format is 16 bits signed integer.
223+
224+
225+
*function* ``mp3_read_s16 (data: bytes, want_nchannels: int = 0, want_sample_rate: int = 0) -> miniaudio.DecodedSoundFile``
226+
> Reads and decodes the whole mp3 audio data. Resulting sample format is 16 bits signed integer.
227+
228+
229+
*function* ``mp3_stream_file (filename: str, frames_to_read: int = 1024, seek_frame: int = 0) -> Generator[array.array, NoneType, NoneType]``
230+
> Streams the mp3 audio file as interleaved 16 bit signed integer sample arrays segments. This uses
231+
a fixed chunk size and cannot be used as a generic miniaudio decoder input stream. Consider using
232+
stream_file() instead.
233+
234+
235+
*function* ``read_file (filename: str, convert_to_16bit: bool = False) -> miniaudio.DecodedSoundFile``
236+
> Reads and decodes the whole audio file. Miniaudio will attempt to return the sound data in exactly
237+
the same format as in the file. Unless you set convert_convert_to_16bit to True, then the result is
238+
always a 16 bit sample format.
239+
240+
241+
*function* ``stream_any (source: miniaudio.StreamableSource, source_format: miniaudio.FileFormat = <FileFormat.UNKNOWN: 0>, output_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, nchannels: int = 2, sample_rate: int = 44100, frames_to_read: int = 1024, dither: miniaudio.DitherMode = <DitherMode.NONE: 0>, seek_frame: int = 0) -> Generator[array.array, int, NoneType]``
242+
> Convenience function that returns a generator to decode and stream any source of encoded audio
243+
data (such as a network stream). Stream result is chunks of raw PCM samples in the chosen format. If
244+
you send() a number into the generator rather than just using next() on it, you'll get that given
245+
number of frames, instead of the default configured amount. This is particularly useful to plug this
246+
stream into an audio device callback that wants a variable number of frames per call.
247+
248+
249+
*function* ``stream_file (filename: str, output_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, nchannels: int = 2, sample_rate: int = 44100, frames_to_read: int = 1024, dither: miniaudio.DitherMode = <DitherMode.NONE: 0>, seek_frame: int = 0) -> Generator[array.array, int, NoneType]``
250+
> Convenience generator function to decode and stream any supported audio file as chunks of raw PCM
251+
samples in the chosen format. If you send() a number into the generator rather than just using
252+
next() on it, you'll get that given number of frames, instead of the default configured amount. This
253+
is particularly useful to plug this stream into an audio device callback that wants a variable
254+
number of frames per call.
255+
256+
257+
*function* ``stream_memory (data: bytes, output_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, nchannels: int = 2, sample_rate: int = 44100, frames_to_read: int = 1024, dither: miniaudio.DitherMode = <DitherMode.NONE: 0>) -> Generator[array.array, int, NoneType]``
258+
> Convenience generator function to decode and stream any supported audio file in memory as chunks
259+
of raw PCM samples in the chosen format. If you send() a number into the generator rather than just
260+
using next() on it, you'll get that given number of frames, instead of the default configured
261+
amount. This is particularly useful to plug this stream into an audio device callback that wants a
262+
variable number of frames per call.
263+
264+
265+
*function* ``vorbis_get_file_info (filename: str) -> miniaudio.SoundFileInfo``
266+
> Fetch some information about the audio file (vorbis format).
267+
268+
269+
*function* ``vorbis_get_info (data: bytes) -> miniaudio.SoundFileInfo``
270+
> Fetch some information about the audio data (vorbis format).
271+
272+
273+
*function* ``vorbis_read (data: bytes) -> miniaudio.DecodedSoundFile``
274+
> Reads and decodes the whole vorbis audio data. Resulting sample format is 16 bits signed integer.
275+
276+
277+
*function* ``vorbis_read_file (filename: str) -> miniaudio.DecodedSoundFile``
278+
> Reads and decodes the whole vorbis audio file. Resulting sample format is 16 bits signed integer.
279+
280+
281+
*function* ``vorbis_stream_file (filename: str, seek_frame: int = 0) -> Generator[array.array, NoneType, NoneType]``
282+
> Streams the ogg vorbis audio file as interleaved 16 bit signed integer sample arrays segments.
283+
This uses a variable unconfigurable chunk size and cannot be used as a generic miniaudio decoder
284+
input stream. Consider using stream_file() instead.
285+
286+
287+
*function* ``wav_get_file_info (filename: str) -> miniaudio.SoundFileInfo``
288+
> Fetch some information about the audio file (wav format).
289+
290+
291+
*function* ``wav_get_info (data: bytes) -> miniaudio.SoundFileInfo``
292+
> Fetch some information about the audio data (wav format).
293+
294+
295+
*function* ``wav_read_f32 (data: bytes) -> miniaudio.DecodedSoundFile``
296+
> Reads and decodes the whole wav audio data. Resulting sample format is 32 bits float.
297+
298+
299+
*function* ``wav_read_file_f32 (filename: str) -> miniaudio.DecodedSoundFile``
300+
> Reads and decodes the whole wav audio file. Resulting sample format is 32 bits float.
301+
302+
303+
*function* ``wav_read_file_s16 (filename: str) -> miniaudio.DecodedSoundFile``
304+
> Reads and decodes the whole wav audio file. Resulting sample format is 16 bits signed integer.
305+
306+
307+
*function* ``wav_read_file_s32 (filename: str) -> miniaudio.DecodedSoundFile``
308+
> Reads and decodes the whole wav audio file. Resulting sample format is 32 bits signed integer.
309+
310+
311+
*function* ``wav_read_s16 (data: bytes) -> miniaudio.DecodedSoundFile``
312+
> Reads and decodes the whole wav audio data. Resulting sample format is 16 bits signed integer.
313+
314+
315+
*function* ``wav_read_s32 (data: bytes) -> miniaudio.DecodedSoundFile``
316+
> Reads and decodes the whole wav audio data. Resulting sample format is 32 bits signed integer.
317+
318+
319+
*function* ``wav_stream_file (filename: str, frames_to_read: int = 1024, seek_frame: int = 0) -> Generator[array.array, NoneType, NoneType]``
320+
> Streams the WAV audio file as interleaved 16 bit signed integer sample arrays segments. This uses
321+
a fixed chunk size and cannot be used as a generic miniaudio decoder input stream. Consider using
322+
stream_file() instead.
323+
324+
325+
*function* ``wav_write_file (filename: str, sound: miniaudio.DecodedSoundFile) ``
326+
> Writes the pcm sound to a WAV file
327+
328+
329+
*class* ``CaptureDevice``
330+
331+
``CaptureDevice (self, input_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, nchannels: int = 2, sample_rate: int = 44100, buffersize_msec: int = 200, device_id: Union[_cffi_backend.CData, NoneType] = None, callback_periods: int = 0, backends: Union[List[miniaudio.Backend], NoneType] = None, thread_prio: miniaudio.ThreadPriority = <ThreadPriority.HIGHEST: 0>, app_name: str = '') ``
332+
> An audio device provided by miniaudio, for audio capture (recording).
333+
334+
> *method* ``close (self) ``
335+
> > Halt playback or capture and close down the device. If you use the device as a context manager,
336+
it will be closed automatically.
337+
338+
> *method* ``start (self, callback_generator: Generator[NoneType, Union[bytes, array.array], NoneType], stop_callback: Union[Callable, NoneType] = None) ``
339+
> > Start the audio device: capture (recording) begins. The recorded audio data is sent to the given
340+
callback generator as raw bytes. (it should already be started before)
341+
342+
> *method* ``stop (self) ``
343+
> > Halt playback or capture.
344+
345+
346+
*class* ``DecodeError``
347+
348+
``DecodeError (self, /, *args, **kwargs)``
349+
> When something went wrong during decoding an audio file.
350+
351+
352+
*class* ``DecodedSoundFile``
353+
354+
``DecodedSoundFile (self, name: str, nchannels: int, sample_rate: int, sample_format: miniaudio.SampleFormat, samples: array.array) ``
355+
> Contains various properties and also the PCM frames of a fully decoded audio file.
356+
357+
358+
*class* ``Devices``
359+
360+
``Devices (self, backends: Union[List[miniaudio.Backend], NoneType] = None) ``
361+
> Query the audio playback and record devices that miniaudio provides
362+
363+
> *method* ``get_captures (self) -> List[Dict[str, Any]]``
364+
> > Get a list of capture devices and some details about them
365+
366+
> *method* ``get_playbacks (self) -> List[Dict[str, Any]]``
367+
> > Get a list of playback devices and some details about them
368+
369+
370+
*class* ``DuplexStream``
371+
372+
``DuplexStream (self, playback_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, playback_channels: int = 2, capture_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, capture_channels: int = 2, sample_rate: int = 44100, buffersize_msec: int = 200, playback_device_id: Union[_cffi_backend.CData, NoneType] = None, capture_device_id: Union[_cffi_backend.CData, NoneType] = None, callback_periods: int = 0, backends: Union[List[miniaudio.Backend], NoneType] = None, thread_prio: miniaudio.ThreadPriority = <ThreadPriority.HIGHEST: 0>, app_name: str = '') ``
373+
> Joins a capture device and a playback device.
374+
375+
> *method* ``close (self) ``
376+
> > Halt playback or capture and close down the device. If you use the device as a context manager,
377+
it will be closed automatically.
378+
379+
> *method* ``start (self, callback_generator: Generator[Union[bytes, array.array], Union[bytes, array.array], NoneType], stop_callback: Union[Callable, NoneType] = None) ``
380+
> > Start the audio device: playback and capture begin. The audio data for playback is provided by
381+
the given callback generator, which is sent the recorded audio data at the same time. (it should
382+
already be started before passing it in)
383+
384+
> *method* ``stop (self) ``
385+
> > Halt playback or capture.
386+
387+
388+
*class* ``MiniaudioError``
389+
390+
``MiniaudioError (self, /, *args, **kwargs)``
391+
> When a miniaudio specific error occurs.
392+
393+
394+
*class* ``PlaybackDevice``
395+
396+
``PlaybackDevice (self, output_format: miniaudio.SampleFormat = <SampleFormat.SIGNED16: 2>, nchannels: int = 2, sample_rate: int = 44100, buffersize_msec: int = 200, device_id: Union[_cffi_backend.CData, NoneType] = None, callback_periods: int = 0, backends: Union[List[miniaudio.Backend], NoneType] = None, thread_prio: miniaudio.ThreadPriority = <ThreadPriority.HIGHEST: 0>, app_name: str = '') ``
397+
> An audio device provided by miniaudio, for audio playback.
398+
399+
> *method* ``close (self) ``
400+
> > Halt playback or capture and close down the device. If you use the device as a context manager,
401+
it will be closed automatically.
402+
403+
> *method* ``start (self, callback_generator: Generator[Union[bytes, array.array], int, NoneType], stop_callback: Union[Callable, NoneType] = None) ``
404+
> > Start the audio device: playback begins. The audio data is provided by the given callback
405+
generator. The generator gets sent the required number of frames and should yield the sample data as
406+
raw bytes, a memoryview, an array.array, or as a numpy array with shape (numframes, numchannels).
407+
The generator should already be started before passing it in.
408+
409+
> *method* ``stop (self) ``
410+
> > Halt playback or capture.
411+
412+
413+
*class* ``SoundFileInfo``
414+
415+
``SoundFileInfo (self, name: str, file_format: miniaudio.FileFormat, nchannels: int, sample_rate: int, sample_format: miniaudio.SampleFormat, duration: float, num_frames: int) ``
416+
> Contains various properties of an audio file.
417+
418+
419+
*class* ``StreamableSource``
420+
421+
``StreamableSource (self, /, *args, **kwargs)``
422+
> Represents a source of data bytes.
423+
424+
425+
*class* ``WavFileReadStream``
426+
427+
``WavFileReadStream (self, pcm_sample_gen: Generator[Union[bytes, array.array], int, NoneType], sample_rate: int, nchannels: int, output_format: miniaudio.SampleFormat, max_frames: int = 0) ``
428+
> An IO stream that reads as a .wav file, and which gets its pcm samples from the provided producer
429+
430+
> *method* ``close (self) ``
431+
> > Close the file
432+
433+
> *method* ``read (self, amount: int = 9223372036854775807) -> Union[bytes, NoneType]``
434+
> > Read up to the given amount of bytes from the file.
435+
436+
437+

miniaudio.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@
55
Software license: "MIT software license". See http://opensource.org/licenses/MIT
66
"""
77

8-
# TODO: expose and support filter API, expose and support waveform and noise generation APIs.
9-
10-
__version__ = "1.20.dev0"
8+
__version__ = "1.20"
119

1210

1311
import abc

0 commit comments

Comments
 (0)