Skip to content

problems about the "load_frame" method and some suggestions #11

@newdive

Description

@newdive

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)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions