Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
Convert an audio file to WAV and different sample formats.
"""
import os
import array
import miniaudio
def samples_path(filename):
return os.path.join(os.path.abspath(os.path.dirname(__file__)), 'samples', filename)
src = miniaudio.decode_file(samples_path("music.ogg"), dither=miniaudio.DitherMode.TRIANGLE)
print("Source: ", src)
result = miniaudio.DecodedSoundFile("result", 1, 22050, miniaudio.SampleFormat.UNSIGNED8, array.array('b'))
converted_frames = miniaudio.convert_frames(src.sample_format, src.nchannels, src.sample_rate, src.samples.tobytes(),
result.sample_format, result.nchannels, result.sample_rate)
# note: currently it is not possible to provide a dithermode to convert_frames()
result.num_frames = int(len(converted_frames) / result.nchannels / result.sample_width)
result.samples.frombytes(converted_frames)
miniaudio.wav_write_file("converted.wav", result)
print("Converted sound written to ./converted.wav")
output_info = miniaudio.get_file_info("converted.wav")
print(output_info)
def __init__(self, samplerate: int = 0, samplewidth: int = 0, nchannels: int = 0, queue_size: int = 100) -> None:
super().__init__(samplerate, samplewidth, nchannels, queue_size=queue_size)
self.command_queue = queue.Queue(maxsize=queue_size) # type: queue.Queue[Dict[str, Any]]
output_format = {
1: miniaudio.SampleFormat.UNSIGNED8,
2: miniaudio.SampleFormat.SIGNED16,
3: miniaudio.SampleFormat.SIGNED24,
4: miniaudio.SampleFormat.SIGNED32
}[self.samplewidth]
self.device = miniaudio.PlaybackDevice(output_format, self.nchannels, self.samplerate)
stream = self.generator()
next(stream) # start generator
self.device.start(stream)
def _array_proto_from_format(sampleformat: SampleFormat) -> array.array:
arrays = {
SampleFormat.UNSIGNED8: _create_int_array(1),
SampleFormat.SIGNED16: _create_int_array(2),
SampleFormat.SIGNED32: _create_int_array(4),
SampleFormat.FLOAT32: array.array('f')
}
if sampleformat in arrays:
return arrays[sampleformat]
raise MiniaudioError("the requested sample format can not be used directly: "
+ sampleformat.name + " (convert it first)")
def _format_from_width(sample_width: int, is_float: bool = False) -> SampleFormat:
if is_float:
return SampleFormat.FLOAT32
elif sample_width == 1:
return SampleFormat.UNSIGNED8
elif sample_width == 2:
return SampleFormat.SIGNED16
elif sample_width == 3:
return SampleFormat.SIGNED24
elif sample_width == 4:
return SampleFormat.SIGNED32
else:
raise MiniaudioError("unsupported sample width", sample_width)
def produce_data(src: io.BytesIO, nchannels: int, samplewidth: int) -> miniaudio.PlaybackCallbackGeneratorType:
desired_frames = yield b"" # generator initialization
while True:
desired_bytes = desired_frames * nchannels * samplewidth
data = src.read(desired_bytes)
if not data:
break
print(".", end="", flush=True)
desired_frames = yield data
producer = produce_data(src, decoded.nchannels, decoded.sample_width)
next(producer) # start the generator
converter = miniaudio.StreamingConverter(decoded.sample_format, decoded.nchannels, decoded.sample_rate,
miniaudio.SampleFormat.UNSIGNED8, 1, 12000, producer,
miniaudio.DitherMode.TRIANGLE)
print("Stream format conversion of source:")
framechunks = []
while True:
framedata = converter.read(4000)
if not framedata:
break
print("got chunk of size", len(framedata))
framechunks.append(framedata)
print("\nGot", len(framechunks), "total frame chunks")
# convert the frames to bytes and write it to a file
samples = array.array('B')
for f in framechunks: