diff options
Diffstat (limited to 'setedit/mp3/libamp/position.c')
-rw-r--r-- | setedit/mp3/libamp/position.c | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/setedit/mp3/libamp/position.c b/setedit/mp3/libamp/position.c new file mode 100644 index 0000000..005f430 --- /dev/null +++ b/setedit/mp3/libamp/position.c @@ -0,0 +1,101 @@ +/* this file is a part of amp software, (C) tomislav uzelac 1996,1997 +*/ +/* position.c ffwd/rew within a stream + * + * Creted by: Tomislav Uzelac, May 10 1997 + */ +#include "amp.h" +#include "audio.h" +#include "getbits.h" + +#define POSITION +#include "position.h" + +/* Returns the number of frames actually skipped, -1 on error. + * + * Values in header are not changed if retval!=nframes. + * This is not necessary because gethdr() doesn't clobber + * the contents of header, but I don't want to rely on that. + */ +int ffwd(struct AUDIO_HEADER *header, int nframes) +{ +int cnt=0,g; +int hsize,bitrate,fs,mean_frame_size; +struct AUDIO_HEADER tmp; + memcpy(&tmp,header,sizeof(tmp)); + + while (cnt < nframes) { + if (tmp.ID) + if (tmp.mode==3) hsize=21; + else hsize=36; + else + if (tmp.mode==3) hsize=13; + else hsize=21; + if (tmp.protection_bit==0) hsize+=2; + if ((g=dummy_getinfo(hsize))) /* dummy_getinfo: reads hsize-4 bytes */ + switch (g) { + case GETHDR_EOF: return cnt; + case GETHDR_ERR: + default: return -1; + } + + bitrate=t_bitrate[tmp.ID][3-tmp.layer][tmp.bitrate_index]; + fs=t_sampling_frequency[tmp.ID][tmp.sampling_frequency]; + if (tmp.ID) mean_frame_size=144000*bitrate/fs; + else mean_frame_size=72000*bitrate/fs; + fillbfr(mean_frame_size + tmp.padding_bit - hsize); + + if ((g=gethdr(&tmp))) + switch (g) { + case GETHDR_EOF: return cnt; + case GETHDR_ERR: + default: return -1; + } + cnt++; + } + + memcpy(header,&tmp,sizeof(tmp)); + return cnt; +} + +/* Mostly the same as ffwd. Some streams might be 'tough', i.e. + * the ones switching bitrates. + */ +int rew(struct AUDIO_HEADER *header, int nframes) +{ +int cnt=0; +int bitrate,fs,mean_frame_size; +struct AUDIO_HEADER tmp; + memcpy(&tmp,header,sizeof(tmp)); + + while (cnt < nframes) { + /* ffwd/rew functions are to be called right after the header has been parsed + * so we have to go back one frame + 4 bytes + 1 byte (in case padding was used). + */ + bitrate=t_bitrate[tmp.ID][3-tmp.layer][tmp.bitrate_index]; + fs=t_sampling_frequency[tmp.ID][tmp.sampling_frequency]; + if (tmp.ID) mean_frame_size=144000*bitrate/fs; + else mean_frame_size=72000*bitrate/fs; + + if (rewind_stream(mean_frame_size) !=0) { + memcpy(header,&tmp,sizeof(tmp)); + return cnt; + } + if ((gethdr(&tmp))) return -1; + cnt++; + } + /* We have to make sure that the bit reservoir contains enough data. + * Hopefully, layer3_frame will take care of that. + */ + f_bdirty=TRUE; + bclean_bytes=0; + + memcpy(header,&tmp,sizeof(tmp)); + return cnt; +} + +/* TODO: after the gethdr function is enhanced with the counter to count + * the number of bytes to search for the next syncword, make the call to + * gethdr() from rew() have that counter something like (frame_size-1) so + * that we don't go back again and again to the same header. (not very important) + */ |