diff options
Diffstat (limited to 'src/libmpg123/frame.h')
-rw-r--r-- | src/libmpg123/frame.h | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/src/libmpg123/frame.h b/src/libmpg123/frame.h new file mode 100644 index 0000000..a13c109 --- /dev/null +++ b/src/libmpg123/frame.h @@ -0,0 +1,355 @@ +/* + frame: Central data structures and opmitization hooks. + + copyright 2007 by the mpg123 project - free software under the terms of the LGPL 2.1 + see COPYING and AUTHORS files in distribution or http://mpg123.org + initially written by Thomas Orgis +*/ + +#ifndef MPG123_FRAME_H +#define MPG123_FRAME_H + +#include <stdio.h> +#include "config.h" +#include "mpg123.h" +#include "optimize.h" +#include "id3.h" +#include "icy.h" +#include "reader.h" +#ifdef FRAME_INDEX +#include "index.h" +#endif +#include "synths.h" + +/* max = 1728 */ +#define MAXFRAMESIZE 3456 + +struct al_table +{ + short bits; + short d; +}; + +/* the output buffer, used to be pcm_sample, pcm_point and audiobufsize */ +struct outbuffer +{ + unsigned char *data; + unsigned char *p; /* read pointer */ + size_t fill; /* fill from read pointer */ + size_t size; /* that's actually more like a safe size, after we have more than that, flush it */ +}; + +struct audioformat +{ + int encoding; + int encsize; /* Size of one sample in bytes, plain int should be fine here... */ + int channels; + long rate; +}; + +void invalidate_format(struct audioformat *af); + +struct mpg123_pars_struct +{ + int verbose; /* verbose level */ + long flags; /* combination of above */ +#ifndef NO_NTOM + long force_rate; +#endif + int down_sample; + int rva; /* (which) rva to do: 0: nothing, 1: radio/mix/track 2: album/audiophile */ + long halfspeed; + long doublespeed; +#ifndef WIN32 + long timeout; +#endif +#define NUM_CHANNELS 2 + char audio_caps[NUM_CHANNELS][MPG123_RATES+1][MPG123_ENCODINGS]; +/* long start_frame; */ /* frame offset to begin with */ +/* long frame_number;*/ /* number of frames to decode */ +#ifndef NO_ICY + long icy_interval; +#endif + double outscale; + long resync_limit; + long index_size; /* Long, because: negative values have a meaning. */ + long preframes; +}; + + + +/* There is a lot to condense here... many ints can be merged as flags; though the main space is still consumed by buffers. */ +struct mpg123_handle_struct +{ + int fresh; /* to be moved into flags */ + int new_format; + real hybrid_block[2][2][SBLIMIT*SSLIMIT]; + int hybrid_blc[2]; + /* the scratch vars for the decoders, sometimes real, sometimes short... sometimes int/long */ + short *short_buffs[2][2]; + real *real_buffs[2][2]; + unsigned char *rawbuffs; + int rawbuffss; +#ifdef OPT_I486 + int i486bo[2]; +#endif + int bo; /* Just have it always here. */ +#ifdef OPT_DITHER + int ditherindex; + float *dithernoise; +#endif + unsigned char* rawdecwin; /* the block with all decwins */ + int rawdecwins; /* size of rawdecwin memory */ + real *decwin; /* _the_ decode table */ +#ifdef OPT_MMXORSSE + /* I am not really sure that I need both of them... used in assembler */ + float *decwin_mmx; + float *decwins; +#endif + int have_eq_settings; + real equalizer[2][32]; + + /* for halfspeed mode */ + unsigned char ssave[34]; + int halfphase; +#ifndef NO_8BIT + /* a raw buffer and a pointer into the middle for signed short conversion, only allocated on demand */ + unsigned char *conv16to8_buf; + unsigned char *conv16to8; +#endif + /* There's some possible memory saving for stuff that is not _really_ dynamic. */ + + /* layer3 */ + int longLimit[9][23]; + int shortLimit[9][14]; + real gainpow2[256+118+4]; /* not really dynamic, just different for mmx */ + + /* layer2 */ + real muls[27][64]; /* also used by layer 1 */ + +#ifndef NO_NTOM + /* decode_ntom */ + unsigned long ntom_val[2]; + unsigned long ntom_step; +#endif + /* special i486 fun */ +#ifdef OPT_I486 + int *int_buffs[2][2]; +#endif + /* special altivec... */ +#ifdef OPT_ALTIVEC + real *areal_buffs[4][4]; +#endif + struct synth_s synths; + struct + { +#ifdef OPT_MULTI + +#ifndef NO_LAYER3 +#if (defined OPT_3DNOW || defined OPT_3DNOWEXT) + void (*dct36)(real *,real *,real *,real *,real *); +#endif +#endif + +#endif + enum optdec type; + enum optcla class; + } cpu_opts; + + int verbose; /* 0: nothing, 1: just print chosen decoder, 2: be verbose */ + + const struct al_table *alloc; + /* The runtime-chosen decoding, based on input and output format. */ + func_synth synth; + func_synth_stereo synth_stereo; + func_synth_mono synth_mono; + /* Yes, this function is runtime-switched, too. */ + void (*make_decode_tables)(mpg123_handle *fr); /* That is the volume control. */ + + int stereo; /* I _think_ 1 for mono and 2 for stereo */ + int jsbound; +#define SINGLE_STEREO -1 +#define SINGLE_LEFT 0 +#define SINGLE_RIGHT 1 +#define SINGLE_MIX 3 + int single; + int II_sblimit; + int down_sample_sblimit; + int lsf; /* 0: MPEG 1.0; 1: MPEG 2.0/2.5 -- both used as bool and array index! */ + /* Many flags in disguise as integers... wasting bytes. */ + int mpeg25; + int down_sample; + int header_change; + int lay; + int (*do_layer)(mpg123_handle *); + int error_protection; + int bitrate_index; + int sampling_frequency; + int padding; + int extension; + int mode; + int mode_ext; + int copyright; + int original; + int emphasis; + int framesize; /* computed framesize */ + int freesize; /* free format frame size */ + enum mpg123_vbr vbr; /* 1 if variable bitrate was detected */ + off_t num; /* frame offset ... */ + off_t playnum; /* playback offset... includes repetitions, reset at seeks */ + off_t audio_start; /* The byte offset in the file where audio data begins. */ + char accurate; /* Flag to see if we trust the frame number. */ + char silent_resync; /* Do not complain for the next n resyncs. */ + unsigned char* xing_toc; /* The seek TOC from Xing header. */ + + /* bitstream info; bsi */ + int bitindex; + unsigned char *wordpointer; + /* temporary storage for getbits stuff */ + unsigned long ultmp; + unsigned char uctmp; + + /* rva data, used in common.c, set in id3.c */ + + double maxoutburst; /* The maximum amplitude in current sample represenation. */ + double lastscale; + struct + { + int level[2]; + float gain[2]; + float peak[2]; + } rva; + + /* input data */ + off_t track_frames; + off_t track_samples; + double mean_framesize; + off_t mean_frames; + int fsizeold; + int ssize; + unsigned int bitreservoir; + unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */ + unsigned char *bsbuf; + unsigned char *bsbufold; + int bsnum; + unsigned long oldhead; + unsigned long firsthead; + int abr_rate; +#ifdef FRAME_INDEX + struct frame_index index; +#endif + + /* output data */ + struct outbuffer buffer; + struct audioformat af; + int own_buffer; + size_t outblock; /* number of bytes that this frame produces (upper bound) */ + int to_decode; /* this frame holds data to be decoded */ + int to_ignore; /* the same, somehow */ + off_t firstframe; /* start decoding from here */ + off_t lastframe; /* last frame to decode (for gapless or num_frames limit) */ + off_t ignoreframe; /* frames to decode but discard before firstframe */ +#ifdef GAPLESS + off_t firstoff; /* number of samples to ignore from firstframe */ + off_t lastoff; /* number of samples to use from lastframe */ + off_t begin_s; /* overall begin offset in samples */ + off_t begin_os; + off_t end_s; /* overall end offset in samples */ + off_t end_os; +#endif + unsigned int crc; /* Well, I need a safe 16bit type, actually. But wider doesn't hurt. */ + struct reader *rd; /* pointer to the reading functions */ + struct reader_data rdat; /* reader data and state info */ + struct mpg123_pars_struct p; + int err; + int decoder_change; + int delayed_change; + long clip; + /* the meta crap */ + int metaflags; + unsigned char id3buf[128]; +#ifndef NO_ID3V2 + mpg123_id3v2 id3v2; +#endif +#ifndef NO_ICY + struct icy_meta icy; +#endif +}; + +/* generic init, does not include dynamic buffers */ +void frame_init(mpg123_handle *fr); +void frame_init_par(mpg123_handle *fr, mpg123_pars *mp); +/* output buffer and format */ +int frame_outbuffer(mpg123_handle *fr); +int frame_output_format(mpg123_handle *fr); + +int frame_buffers(mpg123_handle *fr); /* various decoder buffers, needed once */ +int frame_reset(mpg123_handle* fr); /* reset for next track */ +int frame_buffers_reset(mpg123_handle *fr); +void frame_exit(mpg123_handle *fr); /* end, free all buffers */ + +/* Index functions... */ +/* Well... print it... */ +int mpg123_print_index(mpg123_handle *fr, FILE* out); +/* Find a seek position in index. */ +off_t frame_index_find(mpg123_handle *fr, off_t want_frame, off_t* get_frame); +/* Apply index_size setting. */ +int frame_index_setup(mpg123_handle *fr); + +void do_volume(mpg123_handle *fr, double factor); +void do_rva(mpg123_handle *fr); + +/* samples per frame ... +Layer I +Layer II +Layer III +MPEG-1 +384 +1152 +1152 +MPEG-2 LSF +384 +1152 +576 +MPEG 2.5 +384 +1152 +576 +*/ +#define spf(fr) ((fr)->lay == 1 ? 384 : ((fr)->lay==2 ? 1152 : ((fr)->lsf || (fr)->mpeg25 ? 576 : 1152))) + +#ifdef GAPLESS +/* well, I take that one for granted... at least layer3 */ +#define GAPLESS_DELAY 529 +/* still fine-tuning the "real music" window... see read_frame */ +void frame_gapless_init(mpg123_handle *fr, off_t b, off_t e); +void frame_gapless_realinit(mpg123_handle *fr); +/*void frame_gapless_position(mpg123_handle* fr); +void frame_gapless_bytify(mpg123_handle *fr); +void frame_gapless_ignore(mpg123_handle *fr, off_t frames);*/ +/* void frame_gapless_buffercheck(mpg123_handle *fr); */ +#endif + +/* Skip this frame... do some fake action to get away without actually decoding it. */ +void frame_skip(mpg123_handle *fr); + +/* + Seeking core functions: + - convert input sample offset to output sample offset + - convert frame offset to output sample offset + - get leading frame offset for output sample offset + The offsets are "unadjusted"/internal; resampling is being taken care of. +*/ +off_t frame_ins2outs(mpg123_handle *fr, off_t ins); +off_t frame_outs(mpg123_handle *fr, off_t num); +off_t frame_offset(mpg123_handle *fr, off_t outs); +void frame_set_frameseek(mpg123_handle *fr, off_t fe); +void frame_set_seek(mpg123_handle *fr, off_t sp); +off_t frame_tell_seek(mpg123_handle *fr); +/* Take a copy of the Xing VBR TOC for fuzzy seeking. */ +int frame_fill_toc(mpg123_handle *fr, unsigned char* in); + + +/* adjust volume to current outscale and rva values if wanted */ +void do_rva(mpg123_handle *fr); +#endif |