Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions build_ffi_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@
drflac_uint64 drflac_read_pcm_frames_f32(drflac* pFlac, drflac_uint64 framesToRead, float* pBufferOut);
drflac_bool32 drflac_seek_to_pcm_frame(drflac* pFlac, drflac_uint64 pcmFrameIndex);
drflac* drflac_open_file(const char* filename, const drflac_allocation_callbacks* pAllocationCallbacks);
drflac* drflac_open_file_w(const wchar_t* pFileName, const drflac_allocation_callbacks* pAllocationCallbacks);
drflac* drflac_open_memory(const void* data, size_t dataSize, const drflac_allocation_callbacks* pAllocationCallbacks);
drflac_int32* drflac_open_file_and_read_pcm_frames_s32(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
drflac_int16* drflac_open_file_and_read_pcm_frames_s16(const char* filename, unsigned int* channels, unsigned int* sampleRate, drflac_uint64* totalPCMFrameCount, const drflac_allocation_callbacks* pAllocationCallbacks);
Expand Down Expand Up @@ -723,6 +724,7 @@

drmp3_bool32 drmp3_init_memory(drmp3* pMP3, const void* pData, size_t dataSize, const drmp3_allocation_callbacks* pAllocationCallbacks);
drmp3_bool32 drmp3_init_file(drmp3* pMP3, const char* filePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
drmp3_bool32 drmp3_init_file_w(drmp3* pMP3, const wchar_t* pFilePath, const drmp3_allocation_callbacks* pAllocationCallbacks);
void drmp3_uninit(drmp3* pMP3);

drmp3_uint64 drmp3_read_pcm_frames_f32(drmp3* pMP3, drmp3_uint64 framesToRead, float* pBufferOut);
Expand Down Expand Up @@ -795,6 +797,7 @@
} drwav_allocation_callbacks;

drwav_bool32 drwav_init_file(drwav* pWav, const char* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
drwav_bool32 drwav_init_file_w(drwav* pWav, const wchar_t* filename, const drwav_allocation_callbacks* pAllocationCallbacks);
drwav_bool32 drwav_init_memory(drwav* pWav, const void* data, size_t dataSize, const drwav_allocation_callbacks* pAllocationCallbacks);
drwav_int32 drwav_uninit(drwav* pWav);
void drwav_free(void* p, const drwav_allocation_callbacks* pAllocationCallbacks);
Expand Down
67 changes: 53 additions & 14 deletions miniaudio.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,12 @@ def vorbis_stream_file(filename: str, seek_frame: int = 0) -> Generator[array.ar

def flac_get_file_info(filename: str) -> SoundFileInfo:
"""Fetch some information about the audio file (flac format)."""
filenamebytes = _get_filename_bytes(filename)
flac = lib.drflac_open_file(filenamebytes, ffi.NULL)
if sys.platform == "win32":
filenamebytesw = _get_filename_bytes_w(filename)
flac = lib.drflac_open_file_w(filenamebytesw, ffi.NULL)
else:
filenamebytes = _get_filename_bytes(filename)
flac = lib.drflac_open_file(filenamebytes, ffi.NULL)
if not flac:
raise DecodeError("could not open/decode file")
try:
Expand Down Expand Up @@ -476,8 +480,12 @@ def flac_stream_file(filename: str, frames_to_read: int = 1024,
"""Streams the flac audio file as interleaved 16 bit signed integer sample arrays segments.
This uses a fixed chunk size and cannot be used as a generic miniaudio decoder input stream.
Consider using stream_file() instead."""
filenamebytes = _get_filename_bytes(filename)
flac = lib.drflac_open_file(filenamebytes, ffi.NULL)
if sys.platform == "win32":
filenamebytesw = _get_filename_bytes_w(filename)
flac = lib.drflac_open_file_w(filenamebytesw, ffi.NULL)
else:
filenamebytes = _get_filename_bytes(filename)
flac = lib.drflac_open_file(filenamebytes, ffi.NULL)
if not flac:
raise DecodeError("could not open/decode file")
if seek_frame > 0:
Expand All @@ -501,9 +509,14 @@ def flac_stream_file(filename: str, frames_to_read: int = 1024,

def mp3_get_file_info(filename: str) -> SoundFileInfo:
"""Fetch some information about the audio file (mp3 format)."""
filenamebytes = _get_filename_bytes(filename)
with ffi.new("drmp3 *") as mp3:
if not lib.drmp3_init_file(mp3, filenamebytes, ffi.NULL):
if sys.platform == "win32":
filenamebytesw = _get_filename_bytes_w(filename)
result = lib.drmp3_init_file_w(mp3, filenamebytesw, ffi.NULL)
else:
filenamebytes = _get_filename_bytes(filename)
result = lib.drmp3_init_file(mp3, filenamebytes, ffi.NULL)
if not result:
raise DecodeError("could not open/decode file")
try:
num_frames = lib.drmp3_get_pcm_frame_count(mp3)
Expand Down Expand Up @@ -594,9 +607,14 @@ def mp3_stream_file(filename: str, frames_to_read: int = 1024, seek_frame: int =
"""Streams the mp3 audio file as interleaved 16 bit signed integer sample arrays segments.
This uses a fixed chunk size and cannot be used as a generic miniaudio decoder input stream.
Consider using stream_file() instead."""
filenamebytes = _get_filename_bytes(filename)
with ffi.new("drmp3 *") as mp3:
if not lib.drmp3_init_file(mp3, filenamebytes, ffi.NULL):
if sys.platform == "win32":
filenamebytesw = _get_filename_bytes_w(filename)
result = lib.drmp3_init_file_w(mp3, filenamebytesw, ffi.NULL)
else:
filenamebytes = _get_filename_bytes(filename)
result = lib.drmp3_init_file(mp3, filenamebytes, ffi.NULL)
if not result:
raise DecodeError("could not open/decode file")
if seek_frame > 0:
result = lib.drmp3_seek_to_pcm_frame(mp3, seek_frame)
Expand All @@ -619,9 +637,15 @@ def mp3_stream_file(filename: str, frames_to_read: int = 1024, seek_frame: int =

def wav_get_file_info(filename: str) -> SoundFileInfo:
"""Fetch some information about the audio file (wav format)."""
filenamebytes = _get_filename_bytes(filename)
with ffi.new("drwav*") as wav:
if not lib.drwav_init_file(wav, filenamebytes, ffi.NULL):
if sys.platform == "win32":
# Windows filepaths with non-ascii characters fail to open using fopen, cast filenames to wchar_t*
filenamebytesw = _get_filename_bytes_w(filename)
result = lib.drwav_init_file_w(wav, filenamebytesw, ffi.NULL)
else:
filenamebytes = _get_filename_bytes(filename)
result = lib.drwav_init_file(wav, filenamebytes, ffi.NULL)
if not result:
raise DecodeError("could not open/decode file")
try:
duration = wav.totalPCMFrameCount / wav.sampleRate
Expand Down Expand Up @@ -760,9 +784,14 @@ def wav_stream_file(filename: str, frames_to_read: int = 1024,
"""Streams the WAV audio file as interleaved 16 bit signed integer sample arrays segments.
This uses a fixed chunk size and cannot be used as a generic miniaudio decoder input stream.
Consider using stream_file() instead."""
filenamebytes = _get_filename_bytes(filename)
with ffi.new("drwav*") as wav:
if not lib.drwav_init_file(wav, filenamebytes, ffi.NULL):
if sys.platform == "win32":
filenamebytesw = _get_filename_bytes_w(filename)
result = lib.drwav_init_file_w(wav, filenamebytesw, ffi.NULL)
else:
filenamebytes = _get_filename_bytes(filename)
result = lib.drwav_init_file(wav, filenamebytes, ffi.NULL)
if not result:
raise DecodeError("could not open/decode file")
if seek_frame > 0:
result = lib.drwav_seek_to_pcm_frame(wav, seek_frame)
Expand Down Expand Up @@ -817,6 +846,12 @@ def _get_filename_bytes(filename: str) -> bytes:
return filename2.encode(sys.getfilesystemencoding())


def _get_filename_bytes_w(filename: str):
filename2 = os.path.expanduser(filename)
if not os.path.isfile(filename2):
raise FileNotFoundError(filename)
return ffi.new("wchar_t[]", filename2)

class Devices:
"""Query the audio playback and record devices that miniaudio provides"""
def __init__(self, backends: Optional[List[Backend]] = None) -> None:
Expand Down Expand Up @@ -1027,11 +1062,15 @@ def stream_file(filename: str, output_format: SampleFormat = SampleFormat.SIGNED
This is particularly useful to plug this stream into an audio device callback that
wants a variable number of frames per call.
"""
filenamebytes = _get_filename_bytes(filename)
decoder = ffi.new("ma_decoder *")
decoder_config = lib.ma_decoder_config_init(output_format.value, nchannels, sample_rate)
decoder_config.ditherMode = dither.value
result = lib.ma_decoder_init_file(filenamebytes, ffi.addressof(decoder_config), decoder)
if sys.platform == "win32":
filenamebytesw = _get_filename_bytes_w(filename)
result = lib.ma_decoder_init_file_w(filenamebytesw, ffi.addressof(decoder_config), decoder)
else:
filenamebytes = _get_filename_bytes(filename)
result = lib.ma_decoder_init_file(filenamebytes, ffi.addressof(decoder_config), decoder)
if result != lib.MA_SUCCESS:
raise DecodeError("failed to init decoder", result)
if seek_frame > 0:
Expand Down