i'm trying to get the best from madplay (0.2.12b), and my goal is to jump to certain milisecond in the song, when i get an interrupt (keyboard). i use mad_stream_skip within mad_header_dcode() to acheve this. while monitoring the latency between getting the interrupt and having the jump done, i noticed that both in assabet and intel PIII i acheve latency of between 2-50 miliseconds. by saying latency, i mean that while i wanted to jump to X position, i jumped de-facto to X+20ms, for example. can i make it better ? (i want to acheve <10ms or fixed latency up to 40ms) maybe my measure isnt right ? ( i take stream->current_frame time after the skip, when i get into mad_header_decode(), and the latency calculated by: latency=desired time-current time. maybe current time isnt calculated exctly ? mabe i need to use real-time linux kernel ?
Gad
Gad Hayisraeli gad@syete.co.il wrote:
i'm trying to get the best from madplay (0.2.12b), and my goal is to jump to certain milisecond in the song, when i get an interrupt (keyboard). i use mad_stream_skip within mad_header_dcode() to acheve this. while monitoring the latency between getting the interrupt and having the jump done, i noticed that both in assabet and intel PIII i acheve latency of between 2-50 miliseconds. by saying latency, i mean that while i wanted to jump to X position, i jumped de-facto to X+20ms, for example. can i make it better ? (i want to acheve <10ms or fixed latency up to 40ms) maybe my measure isnt right ? ( i take stream->current_frame time after the skip, when i get into mad_header_decode(), and the latency calculated by: latency=desired time-current time. maybe current time isnt calculated exctly ? mabe i need to use real-time linux kernel ?
Each Layer III frame holds about 26ms of audio data (at 44.1kHz) so you could see up to this much latency just to sync with the next frame.
If you are unlucky enough to jump past part of the bit reservoir holding bits for the next frame, the frame will not be able to be decoded and will be skipped, adding even more latency.
How do you calculate time from stream->current_frame?
Each Layer III frame holds about 26ms of audio data (at 44.1kHz) so you
could
see up to this much latency just to sync with the next frame.
If you are unlucky enough to jump past part of the bit reservoir holding
bits
for the next frame, the frame will not be able to be decoded and will be skipped, adding even more latency.
I know that this would require some work on the decoder, but I think that it should be possible to jump to a granule instead of a frame.
Bye,
--
Gabriel Bouvigne - France bouvigne@mp3-tech.org mobile phone: gsm@mp3-tech.org icq: 12138873
MP3' Tech: www.mp3-tech.org personal page: http://gabriel.mp3-tech.org
Each Layer III frame holds about 26ms of audio data (at 44.1kHz) so you could see up to this much latency just to sync with the next frame.
If you are unlucky enough to jump past part of the bit reservoir holding bits for the next frame, the frame will not be able to be decoded and will be skipped, adding even more latency.
I know that this would require some work on the decoder, but I think that it should be possible to jump to a granule instead of a frame.
Of course you can do better than that. You can jump to any PCM sample position you like; you just have to find the right frame containing the position you want to jump to.
There is a caveat. In order to properly decode samples in one frame, it is often necessary to decode the previous frame so that the Layer III IMDCT overlap outputs are correct and the synthesis filterbank is in phase, since both carry state across frames.
Cheers, -rob
Of course you can do better than that. You can jump to any PCM sample
position
you like; you just have to find the right frame containing the position
you
want to jump to.
There is a caveat. In order to properly decode samples in one frame, it is often necessary to decode the previous frame so that the Layer III IMDCT overlap outputs are correct and the synthesis filterbank is in phase,
since
both carry state across frames.
Do you mean that right now, mad only try decoding at the seek offset without trying to get teh previous data necessary for decoding (like previous frames when main_data_begin>0)?
I think that some people would perhaps need such a behaviour. (but most end-users like me don't care about it).
Regards,
--
Gabriel Bouvigne - France bouvigne@mp3-tech.org mobile phone: gsm@mp3-tech.org icq: 12138873
MP3' Tech: www.mp3-tech.org personal page: http://gabriel.mp3-tech.org
Gabriel Bouvigne bouvigne@mp3-tech.org wrote:
Do you mean that right now, mad only try decoding at the seek offset without trying to get teh previous data necessary for decoding (like previous frames when main_data_begin>0)?
Right now, madplay only supports seeking via the -s option, which works by reading headers (only) until the given time is reached. It does not fully decode any frames prior to this point, nor does it preload the main_data buffer with anything from the skipped frames.
The plug-in for Winamp works slightly differently; it supports full seeking to any arbitrary location during playback. Once the seek location is found, a few frames are read in order to sync with the new stream position, pre-load the main_data buffer, and prime the IMDCT overlap outputs. Then, subband synthesis is performed once on the latest frame to prime the filterbank; the PCM result from this is discarded. Normal decoding and playback then resumes.
More precise positioning would indeed need more effort to properly decode frames preceding the seek point.
Cheers, -rob
i hope not being rude, but i need some latency performance fixes:
i need to be able to jump to some position in song (after receiving interrupt), but not in pieces of 26 ms (1 frame), but within each frame also, in accuracy of less than 5 ms. also, the latency between getting the interrupt request and the jump itself will have to be even less than that. also, when trying to jump, i got distorted sound for a few ms, and you adviced to set mute the sync and a few frames before the desired position. but this adds more latency ! how can i jump directly to the desired position without making this artificial fix, and ths without any latnecy ?
can you make the latency performance better, in the next patches ?
thnaks alot
Gad
-----Original Message----- From: mad-dev-admin@lists.mars.org [mailto:mad-dev-admin@lists.mars.org]On Behalf Of Rob Leslie Sent: Saturday, February 03, 2001 7:28 PM To: mad-dev@lists.mars.org Subject: Re: [mad-dev] mad performance question
Gabriel Bouvigne bouvigne@mp3-tech.org wrote:
Do you mean that right now, mad only try decoding at the seek
offset without
trying to get teh previous data necessary for decoding (like
previous frames
when main_data_begin>0)?
Right now, madplay only supports seeking via the -s option, which works by reading headers (only) until the given time is reached. It does not fully decode any frames prior to this point, nor does it preload the main_data buffer with anything from the skipped frames.
The plug-in for Winamp works slightly differently; it supports full seeking to any arbitrary location during playback. Once the seek location is found, a few frames are read in order to sync with the new stream position, pre-load the main_data buffer, and prime the IMDCT overlap outputs. Then, subband synthesis is performed once on the latest frame to prime the filterbank; the PCM result from this is discarded. Normal decoding and playback then resumes.
More precise positioning would indeed need more effort to properly decode frames preceding the seek point.
Cheers, -rob
--- Gad Hayisraeli gad@syete.co.il wrote:
i need to be able to jump to some position in song (after receiving interrupt), but not in pieces of 26 ms (1 frame), but within each frame also, in accuracy of less than 5 ms. also, the latency between getting the interrupt request and the jump itself will have to be even less than that.
To achieve sub 5ms accuracy, you would have to decode the whole of the frame containing the desired seek destination (OK maybe just a granule - ie 1/2 of a frame - but this would require significant changes to the decoder internals) and then discard samples up to the desired start point. As you rightly say, this increases latency....
Unfortunately, there isn't much that can be done to improve latency (without significantly reducing quality in the first frame decoded) in terms of software tweaks to the decoder. The operation of the winamp plugin as already described by Rob in this thread should give an idea of the complexity of the steps involved in a seek - but this is imposed by the MP3 format itself rather than the decoder implementation.
The only possible way to improve latency is therefore to increase the amount of cpu power... For example, a 600MHz Pentium III can decode individual frames in approx 0.8 ms. Therefore even if 2 full frames must be decoded before any audio is available, the latency on this platform would be around 1.6 ms. A 1GHz x86 cpu would reduce it to under 1ms etc.
Unfortunately, if you have limited cpu bandwidth, this probably isn't good news :-(
What is your application ? Why do you have such tight seek accuracy/latency requirements ??
Andre --
____________________________________________________________ Do You Yahoo!? Get your free @yahoo.co.uk address at http://mail.yahoo.co.uk or your free @yahoo.ie address at http://mail.yahoo.ie
To achieve sub 5ms accuracy, you would have to decode the whole of the frame containing the desired seek destination (OK maybe just a granule - ie 1/2 of a frame - but this would require significant changes to the decoder internals) and then discard samples up to the desired start point. As you rightly say, this increases latency....
could it be possible to use smaller frames, for example: in 22050 hz mpeg file, the frame size is only 207 bytes, while in 44100 its 417 bytes. could it be acheived without lowering the quality ?
What is your application ? Why do you have such tight seek accuracy/latency requirements ??
my app is for medical-music purposes , and needs realtime performance. more i cannot say, sorry ...
Gad
Gad Hayisraeli wrote:
To achieve sub 5ms accuracy, you would have to decode the whole of the frame containing the desired seek destination (OK maybe just a granule - ie 1/2 of a frame - but this would require significant changes to the decoder internals) and then discard samples up to the desired start point. As you rightly say, this increases latency....
could it be possible to use smaller frames, for example: in 22050 hz mpeg file, the frame size is only 207 bytes, while in 44100 its 417 bytes. could it be acheived without lowering the quality ?
The frame size depends on the sampling frequency and the bit rate. Lower sampling frequencies will actually *increase* the frame size if the bit rate is held constant. That's because frames always hold the same number of samples.
The formula for the size of a frame in bytes is:
For Layer I: ((12000 * bitrate / samplerate) + pad_slot) * 4 For Layer II or Layer III (not LSF): (144000 * bitrate / samplerate) + pad_slot For Layer III LSF: (72000 * bitrate / samplerate) + pad_slot
where `bitrate' is the bit rate in kbps, `samplerate' is the sampling frequency in Hz, `pad_slot' is either 0 or 1 depending on the padding_bit from the frame's header, and `/' is integer division (discarding the remainder.)
Therefore, to reduce the frame size in bytes, you can either *increase* the sampling frequency or *decrease* the bit rate. Both basically require re-encoding the bitstream, and both will reduce the overall quality of the output (although how much depends entirely on the quality of your encoder.)
-rob