recently, i am studying mpeg codec and want to try some small and simple project( like miniaudio, minimp3)
I downloaded and installed this module yesterday , and discover some issues after i poked around a little bit. Somehow, i managed to make it work, but it is not easy for someone who is new to this codec stuff.
FYI, I am using Python 3.6.4rc1 , Windows 10
Problem 1
bufferData passed to decode_frame is always chopped at byte value \0.
I don't know if it is a problem with the python version or not
but i guess that the buffer.data.as_uchars is like converting to c-string which consider \0 as a termination
This lead to the failure of finding the correct audio frame header.
Suggesstion.
explicitly claim the exact number of chars like bufferData = buffer.data.as_uchars[0:mp3_size]
Problem 2
pcm passed to decode_frame is empty and will be treated as null inside the mp3dec_decode_frame method
Although the audio data is parsed, but nothing returns
Suggesstion
it seems like the author of minimp3 allocate an fixed-sized pcm before passing it to decode method .
try:
array.resize(pcm,MINIMP3_MAX_SAMPLES_PER_FRAME)
samples = decode_frame(bufferData, mp3_size,...)
except...
although, this would produce redundant trailing zeros in the pcm data, but it is the best we can get
Problem 3
load_frame can not decode other frame but the first and second frame no matter how many times you call it. This is because the every time the pos is set at zero , and after parsing the file will always seek to the frame_info.frame_bytes+0 , which is frame_bytes of the first frame when called the first time and frame_bytes of the second frame when called other times
Suggesstion
change the logic a little bit like the following
cdef size_t pos = mp3_fobj.tell()
...
while True:
try:
...
finally:
pos += frame_info.frame_bytes
...
mp3_fobj.seek(pos)
Finally
"Out of data" exception is raised when mp3_size == 0 , but i think a more appropriate way to handle this is just break the loop and return empty pcm data,
because mp3_size is zero only when it encounters eof , and we can just check if it returns empty pcm instead of using the try...catch bolierplate.
In that situtation , we can load all frames of a file like the following
pcmSamples = array('h')
with open(mp3File,'rb') as f:
while True:
pcms = load_frame(f)
if not pcms:
break
pcmSamples.extend(pcms)
recently, i am studying mpeg codec and want to try some small and simple project( like miniaudio, minimp3)
I downloaded and installed this module yesterday , and discover some issues after i poked around a little bit. Somehow, i managed to make it work, but it is not easy for someone who is new to this codec stuff.
FYI, I am using
Python 3.6.4rc1,Windows 10Problem 1
bufferDatapassed todecode_frameis always chopped at byte value\0.I don't know if it is a problem with the python version or not
but i guess that the
buffer.data.as_ucharsis like converting to c-string which consider\0as a terminationThis lead to the failure of finding the correct audio frame header.
Suggesstion.
explicitly claim the exact number of chars like
bufferData = buffer.data.as_uchars[0:mp3_size]Problem 2
pcmpassed todecode_frameis empty and will be treated as null inside themp3dec_decode_framemethodAlthough the audio data is parsed, but nothing returns
Suggesstion
it seems like the author of minimp3 allocate an fixed-sized
pcmbefore passing it to decode method .although, this would produce redundant trailing zeros in the
pcmdata, but it is the best we can getProblem 3
load_framecan not decode other frame but the first and second frame no matter how many times you call it. This is because the every time theposis set at zero , and after parsing the file will always seek to theframe_info.frame_bytes+0, which is frame_bytes of the first frame when called the first time and frame_bytes of the second frame when called other timesSuggesstion
change the logic a little bit like the following
Finally
"Out of data" exception is raised when
mp3_size == 0, but i think a more appropriate way to handle this is just break the loop and return emptypcmdata,because
mp3_sizeis zero only when it encounterseof, and we can just check if it returns empty pcm instead of using thetry...catchbolierplate.In that situtation , we can load all frames of a file like the following