From c07d996ccf100c49b4da8b03c2f3382eaf2025d4 Mon Sep 17 00:00:00 2001 From: musil Date: Fri, 8 Jul 2005 02:27:24 +0000 Subject: dos-return svn path=/trunk/externals/iemlib/; revision=3302 --- src/iem_mp3/iem_mp3.c | 72 +- src/iem_mp3/sigmp3play.c | 7728 +++++++++++++++++++++---------------------- src/iem_t3_lib/iem_t3_lib.c | 132 +- src/iem_t3_lib/sigt3_line.c | 558 ++-- src/iem_t3_lib/sigt3_sig.c | 400 +-- src/iem_t3_lib/t3_bpe.c | 282 +- src/iem_t3_lib/t3_delay.c | 192 +- src/iem_t3_lib/t3_metro.c | 240 +- src/iem_t3_lib/t3_timer.c | 110 +- src/iemlib2/makefile_win | 1 - 10 files changed, 4857 insertions(+), 4858 deletions(-) diff --git a/src/iem_mp3/iem_mp3.c b/src/iem_mp3/iem_mp3.c index ada504a..ab1356a 100644 --- a/src/iem_mp3/iem_mp3.c +++ b/src/iem_mp3/iem_mp3.c @@ -1,36 +1,36 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_mp3 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" - -static t_class *iem_mp3_class; - -static void *iem_mp3_new(void) -{ - t_object *x = (t_object *)pd_new(iem_mp3_class); - - return (x); -} - -void sigmp3play_setup(void); - -/* ------------------------ setup routine ------------------------- */ - -void iem_mp3_setup(void) -{ - iem_mp3_class = class_new(gensym("iem_mp3"), iem_mp3_new, 0, - sizeof(t_object), CLASS_NOINLET, 0); - - sigmp3play_setup(); - - post("iem_mp3 (R-1.16) library loaded! (c) Thomas Musil 05.2005"); - post(" musil%ciem.at iem KUG Graz Austria", '@'); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_mp3 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" + +static t_class *iem_mp3_class; + +static void *iem_mp3_new(void) +{ + t_object *x = (t_object *)pd_new(iem_mp3_class); + + return (x); +} + +void sigmp3play_setup(void); + +/* ------------------------ setup routine ------------------------- */ + +void iem_mp3_setup(void) +{ + iem_mp3_class = class_new(gensym("iem_mp3"), iem_mp3_new, 0, + sizeof(t_object), CLASS_NOINLET, 0); + + sigmp3play_setup(); + + post("iem_mp3 (R-1.16) library loaded! (c) Thomas Musil 05.2005"); + post(" musil%ciem.at iem KUG Graz Austria", '@'); +} diff --git a/src/iem_mp3/sigmp3play.c b/src/iem_mp3/sigmp3play.c index 64304fc..81927a4 100644 --- a/src/iem_mp3/sigmp3play.c +++ b/src/iem_mp3/sigmp3play.c @@ -1,3864 +1,3864 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_mp3 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -/* - sigmp3play.c - Mpeg Layer III Player for PD - Version:0.1 - 05-18-2000 - written by Thomas Musil (musil_at_iem.kug.ac.at), Norbert Math (math_at_iem.kug.ac.at) - IEM Graz - - debugged for windows 013-03-2003 - - This MPEG Player is based on the mpglib 0.2 by Michael Hipp which comes with mpg123-0.59r - - please see the README file for copyright notices! - - */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifndef NT -#include -#include -#endif - - -#define IEM_MPEG1 - -#ifdef _WIN32 -# undef WIN32 -# define WIN32 - -# define M_PI 3.14159265358979323846 -# define M_SQRT2 1.41421356237309504880 -# define REAL_IS_FLOAT -# define NEW_DCT9 - -# define random rand -# define srandom srand - -#endif - -#ifdef REAL_IS_FLOAT -# define real float -#elif defined(REAL_IS_LONG_DOUBLE) -# define real long double -#else -# define real double -#endif - -#ifdef __GNUC__ -#define INLINE inline -#else -#define INLINE -#endif - -/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */ -#define AUDIOBUFSIZE 16384 - -#define FALSE 0 -#define TRUE 1 -#define SBLIMIT 32 -#define SSLIMIT 18 -#define MPG_MD_STEREO 0 -#define MPG_MD_JOINT_STEREO 1 -#define MPG_MD_DUAL_CHANNEL 2 -#define MPG_MD_MONO 3 - -#define MAXFRAMESIZE 1792 -/* Pre Shift fo 16 to 8 bit converter table */ -#define AUSHIFT (3) -#define BOOL int -#define MP3_EX -2 -#define MP3_ERR -1 -#define MP3_OK 0 -#define MP3_NEED_MORE 1 - -#define WRITE_SAMPLE(samples,sum,clip) \ - if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \ - else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \ - else { *(samples) = sum; } - - -#define HDRCMPMASK 0xfffffd00 - - -#define MY_MP3_MALLOC_IN_SIZE 16384 -#define MY_MP3_MALLOC_IN_SIZE2 8192 -#define MY_MP3_MALLOC_OUT_SIZE 65536 -#define MY_MP3_MALLOC_FN 400 -#define MY_MP3_CHSAMP_PER_FRAME 1152 - -struct iemmp3_frame -{ - int stereo; - int jsbound; - int single; - int lsf; - int mpeg25; - int header_change; - int lay; - 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 */ -}; - -struct iemmp3_gr_info_s -{ - int scfsi; - unsigned part2_3_length; - unsigned big_values; - unsigned scalefac_compress; - unsigned block_type; - unsigned mixed_block_flag; - unsigned table_select[3]; - unsigned subblock_gain[3]; - unsigned maxband[3]; - unsigned maxbandl; - unsigned maxb; - unsigned region1start; - unsigned region2start; - unsigned preflag; - unsigned scalefac_scale; - unsigned count1table_select; - real *full_gain[3]; - real *pow2gain; -}; - -struct iemmp3_III_sideinfo -{ - unsigned main_data_begin; - unsigned private_bits; - struct - { - struct iemmp3_gr_info_s gr[2]; - } ch[2]; -}; - -struct iemmp3_buf -{ - unsigned char *pnt; - long size; - long pos; - struct iemmp3_buf *next; - struct iemmp3_buf *prev; -}; - -struct iemmp3Struct -{ - struct iemmp3_buf *head,*tail; - int bsize; - int framesize; - int fsizeold; - struct iemmp3_frame fr; - unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */ - real hybrid_block[2][2][SBLIMIT*SSLIMIT]; - int hybrid_blc[2]; - unsigned long header; - int bsnum; - real synth_buffs[2][2][0x110]; - int synth_bo; -}; - -struct iemmp3_bandInfoStruct -{ - short longIdx[23]; - short longDiff[22]; - short shortIdx[14]; - short shortDiff[13]; -}; - -struct iemmp3_newHuff -{ - unsigned int linbits; - short *table; -}; - - -typedef struct _sigmp3play -{ - t_object x_obj; - float length_sec; - int samp_per_frame; - int frame_counter; - int time1_bang0_handle; - float time_factor; - int *begframeseek; - int curframeseek; - int maxframeseek; - char *filename; - float offset_sec; - int file_is_open; - int play_state; - int mp3_encode_size; - int mp3_out_index; - int file_size; - int file_block_num; - int file_remain; - int mp_is_init; - int mp3_ch; - int mp3_sr; - int mp3_byterate; - int obj_sr; - int obj_n; - int down; - float scale; - FILE *fh; - char *mp3inbuf; - char *mp3outbuf; - struct iemmp3Struct mp; - t_clock *x_clock; - t_outlet *x_bangout; - t_outlet *x_floatout; - t_canvas *x_canvas; -} t_sigmp3play; - - - -static BOOL InitMP3 (struct iemmp3Struct *mp); -static BOOL InitAgainMP3(struct iemmp3Struct *mp); -static void ExitMP3 (struct iemmp3Struct *mp); -static int decodeMP3 (struct iemmp3Struct *mp, char *in, int isize, char *out, int osize, int *done); -static void make_decode_tables (long scaleval); -static void init_layer3 (int down_sample_sblimit); -static int decode_header (struct iemmp3_frame *fr,unsigned long newhead); -static int do_layer3(struct iemmp3_frame *fr,unsigned char *pcm_sample,int *pcm_point,int *err); -static int set_pointer(long backstep); -static int synth_1to1_mono(real *bandPtr,unsigned char *samples,int *pnt); -static int synth_1to1(real *bandPtr,int channel,unsigned char *out,int *pnt); -static struct iemmp3_buf *addbuf(struct iemmp3Struct *mp,char *buf,int size); -static void remove_buf(struct iemmp3Struct *mp); -static int read_head(struct iemmp3Struct *mp); -static int read_buf_byte(struct iemmp3Struct *mp,int *err); -static int III_get_side_info_2(struct iemmp3_III_sideinfo *si,int stereo, int ms_stereo,long sfreq,int single); -#ifdef IEM_MPEG1 -static int III_get_side_info_1(struct iemmp3_III_sideinfo *si,int stereo,int ms_stereo,long sfreq,int single); -static int III_get_scale_factors_1(int *scf,struct iemmp3_gr_info_s *gr_info); -#endif -static int III_get_scale_factors_2(int *scf,struct iemmp3_gr_info_s *gr_info,int i_stereo); -static int III_dequantize_sample(real xr[SBLIMIT][SSLIMIT],int *scf,struct iemmp3_gr_info_s *gr_info,int sfreq,int part2bits); -static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac,struct iemmp3_gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf); -static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct iemmp3_gr_info_s *gr_info); -static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT],int ch,struct iemmp3_gr_info_s *gr_info); -static void dct64(real *a,real *b,real *c); -static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples); -static void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf); -static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts); -static unsigned int getbits(int number_of_bits); -static unsigned int getbits_fast(int number_of_bits); -static unsigned int get1bit(void); - -static void sigmp3play_tick(t_sigmp3play *x); - - -struct iemmp3Struct *iemmp3_gmp; - -int iemmp3_tabsel_123[2][3][16] = { - { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, - {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, - {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, - - { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, - {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, - {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } -}; - -long iemmp3_freqs[9] = { 44100, 48000, 32000, -22050, 24000, 16000 , -11025 , 12000 , 8000 }; - -int iemmp3_bitindex; -unsigned char *iemmp3_wordpointer; - -static real iemmp3_ispow[8207]; -static real iemmp3_aa_ca[8],iemmp3_aa_cs[8]; -static real iemmp3_COS1[12][6]; -static real iemmp3_win[4][36]; -static real iemmp3_win1[4][36]; -static real iemmp3_gainpow2[256+118+4]; -static real iemmp3_COS9[9]; -static real iemmp3_COS6_1,iemmp3_COS6_2; -static real iemmp3_tfcos36[9]; -static real iemmp3_tfcos12[3]; - -int iemmp3_longLimit[9][23]; -int iemmp3_shortLimit[9][14]; - -struct iemmp3_bandInfoStruct bandInfo[9] = { - - /* MPEG 1.0 */ - { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576}, - {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158}, - {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3}, - {4,4,4,4,6,8,10,12,14,18,22,30,56} } , - - { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576}, - {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192}, - {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3}, - {4,4,4,4,6,6,10,12,14,16,20,26,66} } , - - { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} , - {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} , - {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} , - {4,4,4,4,6,8,12,16,20,26,34,42,12} } , - - /* MPEG 2.0 */ - { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, - {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } , - {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} , - {4,4,4,6,6,8,10,14,18,26,32,42,18 } } , - - { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, - {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } , - {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} , - {4,4,4,6,8,10,12,14,18,24,32,44,12 } } , - - { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, - {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, - {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3}, - {4,4,4,6,8,10,12,14,18,24,30,40,18 } } , - /* MPEG 2.5 */ - { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , - {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, - {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, - {4,4,4,6,8,10,12,14,18,24,30,40,18} }, - { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , - {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, - {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, - {4,4,4,6,8,10,12,14,18,24,30,40,18} }, - { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, - {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2}, - {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576}, - {8,8,8,12,16,20,24,28,36,2,2,2,26} } , -}; - -static int iemmp3_mapbuf0[9][152]; -static int iemmp3_mapbuf1[9][156]; -static int iemmp3_mapbuf2[9][44]; -static int *iemmp3_map[9][3]; -static int *iemmp3_mapend[9][3]; - -static unsigned int iemmp3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */ -static unsigned int iemmp3_slen2[256]; /* MPEG 2.0 slen for intensity stereo */ - -static real iemmp3_tan1_1[16],iemmp3_tan2_1[16],iemmp3_tan1_2[16],iemmp3_tan2_2[16]; -static real iemmp3_pow1_1[2][16],iemmp3_pow2_1[2][16],iemmp3_pow1_2[2][16],iemmp3_pow2_2[2][16]; - -static int iemmp3_pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0}; -static int iemmp3_pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - -real iemmp3_decwin[512+32]; -static real iemmp3_cos64[16],iemmp3_cos32[8],iemmp3_cos16[4],iemmp3_cos8[2],iemmp3_cos4[1]; -real *iemmp3_pnts[] = { iemmp3_cos64,iemmp3_cos32,iemmp3_cos16,iemmp3_cos8,iemmp3_cos4 }; - -static long iemmp3_intwinbase[] = { - 0, -1, -1, -1, -1, -1, -1, -2, -2, -2, - -2, -3, -3, -4, -4, -5, -5, -6, -7, -7, - -8, -9, -10, -11, -13, -14, -16, -17, -19, -21, - -24, -26, -29, -31, -35, -38, -41, -45, -49, -53, - -58, -63, -68, -73, -79, -85, -91, -97, -104, -111, - -117, -125, -132, -139, -147, -154, -161, -169, -176, -183, - -190, -196, -202, -208, -213, -218, -222, -225, -227, -228, - -228, -227, -224, -221, -215, -208, -200, -189, -177, -163, - -146, -127, -106, -83, -57, -29, 2, 36, 72, 111, - 153, 197, 244, 294, 347, 401, 459, 519, 581, 645, - 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356, - 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962, - 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000, - 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970, - 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388, - -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, - -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209, - -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959, - -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092, - -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082, - -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455, - 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289, - 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617, - 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684, - 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835, - 73415, 73908, 74313, 74630, 74856, 74992, 75038 }; - -static short iemmp3_tab0[] = -{ - 0 -}; - -static short iemmp3_tab1[] = -{ - -5, -3, -1, 17, 1, 16, 0 -}; - -static short iemmp3_tab2[] = -{ - -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1, - 16, 0 -}; - -static short iemmp3_tab3[] = -{ - -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1, - 1, 0 -}; - -static short iemmp3_tab5[] = -{ - -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19, - 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16, - 0 -}; - -static short iemmp3_tab6[] = -{ - -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19, - 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16, - 0 -}; - -static short iemmp3_tab7[] = -{ - -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83, - -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1, - 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7, - -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18, - -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0 -}; - -static short iemmp3_tab8[] = -{ - -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83, - -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52, - 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4, - 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1, - 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0 -}; - -static short iemmp3_tab9[] = -{ - -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1, - 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67, - -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5, - -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2, - 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0 -}; - -static short iemmp3_tab10[] = -{ - -125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118, - 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3, - -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1, - 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23, - -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81, - -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7, - -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1, - 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1, - 2, 32, 17, -1, 1, 16, 0 -}; - -static short iemmp3_tab11[] = -{ - -121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117, - -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55, - -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114, - -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96, - -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38, - 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1, - 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50, - -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2, - 32, 17, -3, -1, 1, 16, 0 -}; - -static short iemmp3_tab12[] = -{ - -115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87, - 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115, - 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7, - 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5, - -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37, - 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4, - 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3, - -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1, - 2, 32, 0, 17, -1, 1, 16 -}; - -static short iemmp3_tab13[] = -{ - -509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9, - -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238, - 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1, - 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249, - 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158, - -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1, - 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245, - 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1, - 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15, - -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1, - 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1, - 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1, - 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3, - -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1, - 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5, - -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167, - 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76, - 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137, - 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106, - -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43, - -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178, - -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1, - 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161, - -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88, - -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1, - 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25, - 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100, - 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113, - -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38, - -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6, - 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81, - -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11, - -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3, - -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, - 0 -}; - -static short iemmp3_tab15[] = -{ - -495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239, - -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237, - 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3, - -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219, - -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173, - -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246, - -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9, - -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243, - 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1, - 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1, - 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3, - -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5, - -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124, - 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1, - 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183, - -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76, - -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1, - 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15, - -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106, - -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5, - -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74, - -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1, - 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134, - 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29, - -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7, - -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7, - -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86, - -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100, - 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69, - -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9, - -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1, - 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20, - 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48, - 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16, - 0 -}; - -static short iemmp3_tab16[] = -{ - -509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223, - 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3, - -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5, - -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19, - -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1, - 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5, - -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125, - 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13, - -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3, - -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186, - -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1, - 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169, - -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213, - -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154, - 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1, - 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1, - 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45, - -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107, - -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12, - -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1, - 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74, - 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33, - -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3, - -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147, - -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1, - 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3, - -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1, - 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3, - -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1, - 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9, - -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33, - -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, - -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1, - 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, - 0 -}; - -static short iemmp3_tab24[] = -{ - -451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1, - 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9, - -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79, - 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31, - 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1, - 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3, - -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3, - -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235, - -143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3, - -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9, - -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1, - 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185, - 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199, - 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3, - -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3, - -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196, - -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1, - 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1, - 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10, - 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9, - 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165, - 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135, - -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104, - -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3, - -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3, - -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7, - -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86, - 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15, - -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84, - -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1, - 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5, - 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5, - -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1, - 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16, - 0 -}; - -static short iemmp3_tab_c0[] = -{ - -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5, - 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8, - 0 -}; - -static short iemmp3_tab_c1[] = -{ - -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9, - 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1, - 0 -}; - - - -static struct iemmp3_newHuff iemmp3_ht[] = -{ - { /* 0 */ 0 , iemmp3_tab0 } , - { /* 2 */ 0 , iemmp3_tab1 } , - { /* 3 */ 0 , iemmp3_tab2 } , - { /* 3 */ 0 , iemmp3_tab3 } , - { /* 0 */ 0 , iemmp3_tab0 } , - { /* 4 */ 0 , iemmp3_tab5 } , - { /* 4 */ 0 , iemmp3_tab6 } , - { /* 6 */ 0 , iemmp3_tab7 } , - { /* 6 */ 0 , iemmp3_tab8 } , - { /* 6 */ 0 , iemmp3_tab9 } , - { /* 8 */ 0 , iemmp3_tab10 } , - { /* 8 */ 0 , iemmp3_tab11 } , - { /* 8 */ 0 , iemmp3_tab12 } , - { /* 16 */ 0 , iemmp3_tab13 } , - { /* 0 */ 0 , iemmp3_tab0 } , - { /* 16 */ 0 , iemmp3_tab15 } , - - { /* 16 */ 1 , iemmp3_tab16 } , - { /* 16 */ 2 , iemmp3_tab16 } , - { /* 16 */ 3 , iemmp3_tab16 } , - { /* 16 */ 4 , iemmp3_tab16 } , - { /* 16 */ 6 , iemmp3_tab16 } , - { /* 16 */ 8 , iemmp3_tab16 } , - { /* 16 */ 10, iemmp3_tab16 } , - { /* 16 */ 13, iemmp3_tab16 } , - { /* 16 */ 4 , iemmp3_tab24 } , - { /* 16 */ 5 , iemmp3_tab24 } , - { /* 16 */ 6 , iemmp3_tab24 } , - { /* 16 */ 7 , iemmp3_tab24 } , - { /* 16 */ 8 , iemmp3_tab24 } , - { /* 16 */ 9 , iemmp3_tab24 } , - { /* 16 */ 11, iemmp3_tab24 } , - { /* 16 */ 13, iemmp3_tab24 } -}; - -static struct iemmp3_newHuff iemmp3_htc[] = -{ - { /* 1 , 1 , */ 0 , iemmp3_tab_c0 } , - { /* 1 , 1 , */ 0 , iemmp3_tab_c1 } -}; - - -static t_class *sigmp3play_class; - - - -static BOOL InitMP3(struct iemmp3Struct *mp) -{ - memset(mp,0,sizeof(struct iemmp3Struct)); - - mp->framesize = 0; - mp->fsizeold = -1; - mp->bsize = 0; - mp->head = mp->tail = NULL; - mp->fr.single = -1; - mp->bsnum = 0; - mp->synth_bo = 1; - - make_decode_tables(32767); - init_layer3(SBLIMIT); - - return !0; -} - -static BOOL InitAgainMP3(struct iemmp3Struct *mp) -{ - memset(mp,0,sizeof(struct iemmp3Struct)); - - mp->framesize = 0; - mp->fsizeold = -1; - mp->bsize = 0; - mp->head = mp->tail = NULL; - mp->fr.single = -1; - mp->bsnum = 0; - mp->synth_bo = 1; - - return !0; -} - -static void ExitMP3(struct iemmp3Struct *mp) -{ - struct iemmp3_buf *b,*bn; - - b = mp->tail; - while(b) - { - free(b->pnt); - bn = b->next; - free(b); - b = bn; - } -} - -static int decodeMP3(struct iemmp3Struct *mp, char *in, int isize, char *out, int osize, int *done) -{ - int len,error=1; - - iemmp3_gmp = mp; - - if(osize < 4608) - { - post("To less out space\n"); - return MP3_ERR; - } - - if(in) - { - if(addbuf(mp,in,isize) == NULL) - { - return MP3_ERR; - } - } - - /* First decode header */ - if(mp->framesize == 0) - { - if(mp->bsize < 4) - { - return MP3_NEED_MORE; - } - if(!read_head(mp)) - return MP3_EX; - if(decode_header(&mp->fr,mp->header) == MP3_EX) - return MP3_EX; - mp->framesize = mp->fr.framesize; - } - - if(mp->fr.framesize > mp->bsize) - return MP3_NEED_MORE; - - iemmp3_wordpointer = mp->bsspace[mp->bsnum] + 512; - mp->bsnum = (mp->bsnum + 1) & 0x1; - iemmp3_bitindex = 0; - - len = 0; - while(len < mp->framesize) - { - int nlen; - int blen = mp->tail->size - mp->tail->pos; - if( (mp->framesize - len) <= blen) - { - nlen = mp->framesize-len; - } - else - { - nlen = blen; - } - memcpy(iemmp3_wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen); - len += nlen; - mp->tail->pos += nlen; - mp->bsize -= nlen; - if(mp->tail->pos == mp->tail->size) - { - remove_buf(mp); - } - } - - *done = 0; - if(mp->fr.error_protection) - getbits(16); - do_layer3(&mp->fr,(unsigned char *) out,done,&error); - if(!error) - return MP3_EX; - - mp->fsizeold = mp->framesize; - mp->framesize = 0; - - return MP3_OK; -} - -static void make_decode_tables(long scaleval) -{ - int i,j,k,kr,divv; - real *table,*costab; - - for(i=0;i<5;i++) - { - kr=0x10>>i; divv=0x40>>i; - costab = iemmp3_pnts[i]; - for(k=0;k 0) - { - if( i & 1 ) - p1 = pow(base,(i+1.0)*0.5); - else - p2 = pow(base,i*0.5); - } - iemmp3_pow1_1[j][i] = p1; - iemmp3_pow2_1[j][i] = p2; - iemmp3_pow1_2[j][i] = M_SQRT2 * p1; - iemmp3_pow2_2[j][i] = M_SQRT2 * p2; - } - } - - for(j=0;j<9;j++) - { - struct iemmp3_bandInfoStruct *bi = &bandInfo[j]; - int *mp; - int cb,lwin; - short *bdf; - - mp = iemmp3_map[j][0] = iemmp3_mapbuf0[j]; - bdf = bi->longDiff; - for(i=0,cb = 0; cb < 8 ; cb++,i+=*bdf++) - { - *mp++ = (*bdf) >> 1; - *mp++ = i; - *mp++ = 3; - *mp++ = cb; - } - bdf = bi->shortDiff+3; - for(cb=3;cb<13;cb++) - { - int l = (*bdf++) >> 1; - for(lwin=0;lwin<3;lwin++) - { - *mp++ = l; - *mp++ = i + lwin; - *mp++ = lwin; - *mp++ = cb; - } - i += 6*l; - } - iemmp3_mapend[j][0] = mp; - - mp = iemmp3_map[j][1] = iemmp3_mapbuf1[j]; - bdf = bi->shortDiff+0; - for(i=0,cb=0;cb<13;cb++) - { - int l = (*bdf++) >> 1; - for(lwin=0;lwin<3;lwin++) - { - *mp++ = l; - *mp++ = i + lwin; - *mp++ = lwin; - *mp++ = cb; - } - i += 6*l; - } - iemmp3_mapend[j][1] = mp; - - mp = iemmp3_map[j][2] = iemmp3_mapbuf2[j]; - bdf = bi->longDiff; - for(cb = 0; cb < 22 ; cb++) - { - *mp++ = (*bdf++) >> 1; - *mp++ = cb; - } - iemmp3_mapend[j][2] = mp; - } - - for(j=0;j<9;j++) - { - for(i=0;i<23;i++) - { - iemmp3_longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1; - if(iemmp3_longLimit[j][i] > (down_sample_sblimit) ) - iemmp3_longLimit[j][i] = down_sample_sblimit; - } - for(i=0;i<14;i++) - { - iemmp3_shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1; - if(iemmp3_shortLimit[j][i] > (down_sample_sblimit) ) - iemmp3_shortLimit[j][i] = down_sample_sblimit; - } - } - - for(i=0;i<5;i++) - { - for(j=0;j<6;j++) - { - for(k=0;k<6;k++) - { - int n = k + j * 6 + i * 36; - iemmp3_slen2[n] = i|(j<<3)|(k<<6)|(3<<12); - } - } - } - for(i=0;i<4;i++) - { - for(j=0;j<4;j++) - { - for(k=0;k<4;k++) - { - int n = k + j * 4 + i * 16; - iemmp3_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12); - } - } - } - for(i=0;i<4;i++) - { - for(j=0;j<3;j++) - { - int n = j + i * 3; - iemmp3_slen2[n+244] = i|(j<<3) | (5<<12); - iemmp3_n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15); - } - } - - for(i=0;i<5;i++) - { - for(j=0;j<5;j++) - { - for(k=0;k<4;k++) - { - for(l=0;l<4;l++) - { - int n = l + k * 4 + j * 16 + i * 80; - iemmp3_n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12); - } - } - } - } - for(i=0;i<5;i++) - { - for(j=0;j<5;j++) - { - for(k=0;k<4;k++) - { - int n = k + j * 4 + i * 20; - iemmp3_n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12); - } - } - } -} - -static void remove_buf(struct iemmp3Struct *mp) -{ - struct iemmp3_buf *buf = mp->tail; - - mp->tail = buf->next; - if(mp->tail) - mp->tail->prev = NULL; - else - { - mp->tail = mp->head = NULL; - } - free(buf->pnt); - free(buf); -} - -static struct iemmp3_buf *addbuf(struct iemmp3Struct *mp,char *buf,int size) -{ - struct iemmp3_buf *nbuf; - - nbuf = malloc( sizeof(struct iemmp3_buf) ); - if(!nbuf) - { - post("Out of memory!\n"); - return NULL; - } - nbuf->pnt = malloc(size); - if(!nbuf->pnt) - { - free(nbuf); - return NULL; - } - nbuf->size = size; - memcpy(nbuf->pnt,buf,size); - nbuf->next = NULL; - nbuf->prev = mp->head; - nbuf->pos = 0; - if(!mp->tail) - { - mp->tail = nbuf; - } - else - { - mp->head->next = nbuf; - } - mp->head = nbuf; - mp->bsize += size; - return nbuf; -} - -static int read_buf_byte(struct iemmp3Struct *mp,int *err) -{ - unsigned int b; - int pos; - - pos = mp->tail->pos; - while(pos >= mp->tail->size) - { - remove_buf(mp); - pos = mp->tail->pos; - if(!mp->tail) - { - post("Fatal error!\n"); - *err = 0; - return(0); - } - } - b = mp->tail->pnt[pos]; - mp->bsize--; - mp->tail->pos++; - return(b); -} - -static int read_head(struct iemmp3Struct *mp) -{ - unsigned long head; - int error=1; - - head = read_buf_byte(mp,&error); - head <<= 8; - head |= read_buf_byte(mp,&error); - head <<= 8; - head |= read_buf_byte(mp,&error); - head <<= 8; - head |= read_buf_byte(mp,&error); - mp->header = head; - return(error); -} - -static int decode_header(struct iemmp3_frame *fr,unsigned long newhead) -{ - if( newhead & (1<<20) ) - { - fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1; - fr->mpeg25 = 0; - } - else - { - fr->lsf = 1; - fr->mpeg25 = 1; - } - fr->lay = 4-((newhead>>17)&3); - if( ((newhead>>10)&0x3) == 0x3) - { - post("Stream error"); - return(MP3_EX); - } - if(fr->mpeg25) - { - fr->sampling_frequency = 6 + ((newhead>>10)&0x3); - } - else - fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3); - fr->error_protection = ((newhead>>16)&0x1)^0x1; - if(fr->mpeg25) /* allow Bitrate change for 2.5 ... */ - fr->bitrate_index = ((newhead>>12)&0xf); - fr->bitrate_index = ((newhead>>12)&0xf); - fr->padding = ((newhead>>9)&0x1); - fr->extension = ((newhead>>8)&0x1); - fr->mode = ((newhead>>6)&0x3); - fr->mode_ext = ((newhead>>4)&0x3); - fr->copyright = ((newhead>>3)&0x1); - fr->original = ((newhead>>2)&0x1); - fr->emphasis = newhead & 0x3; - fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; - if(!fr->bitrate_index) - { - post("Free format not supported.\n"); - return(0); - } - switch(fr->lay) - { - case 1: - post("Layer I not supported!\n"); - break; - case 2: - post("Layer II not supported!\n"); - break; - case 3: - fr->framesize = (long) iemmp3_tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; - fr->framesize /= iemmp3_freqs[fr->sampling_frequency]<<(fr->lsf); - fr->framesize = fr->framesize + fr->padding - 4; - //post("Framesize: %d",fr->framesize); - break; - default: - post("Sorry, unknown layer type.\n"); - return (0); - } - return(1); -} - -static unsigned int getbits(int number_of_bits) -{ - unsigned long rval; - - if(!number_of_bits) - return 0; - { - rval = iemmp3_wordpointer[0]; - rval <<= 8; - rval |= iemmp3_wordpointer[1]; - rval <<= 8; - rval |= iemmp3_wordpointer[2]; - rval <<= iemmp3_bitindex; - rval &= 0xffffff; - iemmp3_bitindex += number_of_bits; - rval >>= (24-number_of_bits); - iemmp3_wordpointer += (iemmp3_bitindex>>3); - iemmp3_bitindex &= 7; - } - return rval; -} - -static unsigned int getbits_fast(int number_of_bits) -{ - unsigned long rval; - - { - rval = iemmp3_wordpointer[0]; - rval <<= 8; - rval |= iemmp3_wordpointer[1]; - rval <<= iemmp3_bitindex; - rval &= 0xffff; - iemmp3_bitindex += number_of_bits; - rval >>= (16-number_of_bits); - iemmp3_wordpointer += (iemmp3_bitindex>>3); - iemmp3_bitindex &= 7; - } - return rval; -} - -static unsigned int get1bit(void) -{ - unsigned char rval; - rval = *iemmp3_wordpointer << iemmp3_bitindex; - - iemmp3_bitindex++; - iemmp3_wordpointer += (iemmp3_bitindex>>3); - iemmp3_bitindex &= 7; - - return rval>>7; -} - -static int do_layer3(struct iemmp3_frame *fr,unsigned char *pcm_sample,int *pcm_point,int *err) -{ - int gr, ch, ss,clip=0; - int scalefacs[39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */ - struct iemmp3_III_sideinfo sideinfo; - int stereo = fr->stereo; - int single = fr->single; - int ms_stereo,i_stereo; - int sfreq = fr->sampling_frequency; - int stereo1,granules; - - if(stereo == 1) - { /* stream is mono */ - stereo1 = 1; - single = 0; - } - else if(single >= 0) /* stream is stereo, but force to mono */ - stereo1 = 1; - else - stereo1 = 2; - - if(fr->mode == MPG_MD_JOINT_STEREO) - { - ms_stereo = fr->mode_ext & 0x2; - i_stereo = fr->mode_ext & 0x1; - } - else - ms_stereo = i_stereo = 0; - - if(fr->lsf) - { - granules = 1; - if(!III_get_side_info_2(&sideinfo,stereo,ms_stereo,sfreq,single)) - { - *err = 0; - return 0; - } - } - else - { - granules = 2; -#ifdef IEM_MPEG1 - if(!III_get_side_info_1(&sideinfo,stereo,ms_stereo,sfreq,single)) - { - *err = 0; - return 0; - } -#else - post("Not supported\n"); -#endif - } - - if(set_pointer(sideinfo.main_data_begin) == MP3_ERR) - return 0; - - for (gr=0;grlsf) - part2bits = III_get_scale_factors_2(scalefacs,gr_info,0); - else - { -#ifdef IEM_MPEG1 - part2bits = III_get_scale_factors_1(scalefacs,gr_info); -#else - post("Not supported\n"); -#endif - } - if(III_dequantize_sample(hybridIn[0], scalefacs,gr_info,sfreq,part2bits)) - return clip; - } - if(stereo == 2) - { - struct iemmp3_gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]); - long part2bits; - if(fr->lsf) - part2bits = III_get_scale_factors_2(scalefacs,gr_info,i_stereo); - else - { -#ifdef IEM_MPEG1 - part2bits = III_get_scale_factors_1(scalefacs,gr_info); -#else - post("Not supported\n"); -#endif - } - - if(III_dequantize_sample(hybridIn[1],scalefacs,gr_info,sfreq,part2bits)) - return clip; - - if(ms_stereo) - { - int i; - for(i=0;ilsf); - - if(ms_stereo || i_stereo || (single == 3) ) - { - if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb) - sideinfo.ch[0].gr[gr].maxb = gr_info->maxb; - else - gr_info->maxb = sideinfo.ch[0].gr[gr].maxb; - } - - switch(single) - { - case 3: - { - register unsigned int i; - register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1]; - for(i=0;imaxb;i++,in0++) - *in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */ - } - break; - case 1: - { - register unsigned int i; - register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1]; - for(i=0;imaxb;i++) - *in0++ = *in1++; - } - break; - } - } - - for(ch=0;ch= 0) - { - clip += synth_1to1_mono(hybridOut[0][ss],pcm_sample,pcm_point); - } - else - { - int p1 = *pcm_point; - clip += synth_1to1(hybridOut[0][ss],0,pcm_sample,&p1); - clip += synth_1to1(hybridOut[1][ss],1,pcm_sample,pcm_point); - } - } - } - - return clip; -} - -static int III_get_side_info_2(struct iemmp3_III_sideinfo *si,int stereo, - int ms_stereo,long sfreq,int single) -{ - int ch; - int powdiff = (single == 3) ? 4 : 0; - - si->main_data_begin = getbits(8); - if (stereo == 1) - si->private_bits = get1bit(); - else - si->private_bits = getbits_fast(2); - - for (ch=0; chch[ch].gr[0]); - - gr_info->part2_3_length = getbits(12); - gr_info->big_values = getbits_fast(9); - if(gr_info->big_values > 288) - { - post("big_values too large!\n"); - gr_info->big_values = 288; - } - gr_info->pow2gain = iemmp3_gainpow2+256 - getbits_fast(8) + powdiff; - if(ms_stereo) - gr_info->pow2gain += 2; - gr_info->scalefac_compress = getbits(9); - /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */ - if(get1bit()) - { - int i; - gr_info->block_type = getbits_fast(2); - gr_info->mixed_block_flag = get1bit(); - gr_info->table_select[0] = getbits_fast(5); - gr_info->table_select[1] = getbits_fast(5); - /* - * table_select[2] not needed, because there is no region2, - * but to satisfy some verifications tools we set it either. - */ - gr_info->table_select[2] = 0; - for(i=0;i<3;i++) - gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3); - if(gr_info->block_type == 0) - { - post("Blocktype == 0 and window-switching == 1 not allowed.\n"); - return(0); - } - /* region_count/start parameters are implicit in this case. */ - /* check this again! */ - if(gr_info->block_type == 2) - gr_info->region1start = 36>>1; - else if(sfreq == 8) - /* check this for 2.5 and sfreq=8 */ - gr_info->region1start = 108>>1; - else - gr_info->region1start = 54>>1; - gr_info->region2start = 576>>1; - } - else - { - int i,r0c,r1c; - for (i=0; i<3; i++) - gr_info->table_select[i] = getbits_fast(5); - r0c = getbits_fast(4); - r1c = getbits_fast(3); - gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ; - gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1; - gr_info->block_type = 0; - gr_info->mixed_block_flag = 0; - } - gr_info->scalefac_scale = get1bit(); - gr_info->count1table_select = get1bit(); - } - return(1); -} - - -#ifdef IEM_MPEG1 -static int III_get_side_info_1(struct iemmp3_III_sideinfo *si,int stereo, - int ms_stereo,long sfreq,int single) -{ - int ch, gr; - int powdiff = (single == 3) ? 4 : 0; - - si->main_data_begin = getbits(9); - if (stereo == 1) - si->private_bits = getbits_fast(5); - else - si->private_bits = getbits_fast(3); - - for (ch=0; chch[ch].gr[0].scfsi = -1; - si->ch[ch].gr[1].scfsi = getbits_fast(4); - } - - for (gr=0; gr<2; gr++) - { - for (ch=0; chch[ch].gr[gr]); - - gr_info->part2_3_length = getbits(12); - gr_info->big_values = getbits_fast(9); - if(gr_info->big_values > 288) - { - post("big_values too large!\n"); - gr_info->big_values = 288; - } - gr_info->pow2gain = iemmp3_gainpow2+256 - getbits_fast(8) + powdiff; - if(ms_stereo) - gr_info->pow2gain += 2; - gr_info->scalefac_compress = getbits_fast(4); - /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */ - if(get1bit()) - { - int i; - - gr_info->block_type = getbits_fast(2); - gr_info->mixed_block_flag = get1bit(); - gr_info->table_select[0] = getbits_fast(5); - gr_info->table_select[1] = getbits_fast(5); - /* - * table_select[2] not needed, because there is no region2, - * but to satisfy some verifications tools we set it either. - */ - gr_info->table_select[2] = 0; - for(i=0;i<3;i++) - gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3); - - if(gr_info->block_type == 0) - { - post("Blocktype == 0 and window-switching == 1 not allowed.\n"); - return(0); - } - /* region_count/start parameters are implicit in this case. */ - gr_info->region1start = 36>>1; - gr_info->region2start = 576>>1; - } - else - { - int i,r0c,r1c; - for (i=0; i<3; i++) - gr_info->table_select[i] = getbits_fast(5); - r0c = getbits_fast(4); - r1c = getbits_fast(3); - gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ; - gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1; - gr_info->block_type = 0; - gr_info->mixed_block_flag = 0; - } - gr_info->preflag = get1bit(); - gr_info->scalefac_scale = get1bit(); - gr_info->count1table_select = get1bit(); - } - } - return(1); -} -#endif - -static int set_pointer(long backstep) -{ - unsigned char *bsbufold; - if(iemmp3_gmp->fsizeold < 0 && backstep > 0) - { - post("Can't step back %ld!\n",backstep); - return MP3_ERR; - } - bsbufold = iemmp3_gmp->bsspace[iemmp3_gmp->bsnum] + 512; - iemmp3_wordpointer -= backstep; - if (backstep) - memcpy(iemmp3_wordpointer,bsbufold+iemmp3_gmp->fsizeold-backstep,backstep); - iemmp3_bitindex = 0; - return MP3_OK; -} - -#ifdef IEM_MPEG1 -static int III_get_scale_factors_1(int *scf,struct iemmp3_gr_info_s *gr_info) -{ - static unsigned char slen[2][16] = { - {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, - {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3} - }; - int numbits; - int num0 = slen[0][gr_info->scalefac_compress]; - int num1 = slen[1][gr_info->scalefac_compress]; - - if (gr_info->block_type == 2) - { - int i=18; - - numbits = (num0 + num1) * 18; - if (gr_info->mixed_block_flag) - { - for (i=8;i;i--) - *scf++ = getbits_fast(num0); - i = 9; - numbits -= num0; /* num0 * 17 + num1 * 18 */ - } - - for (;i;i--) - *scf++ = getbits_fast(num0); - for (i = 18; i; i--) - *scf++ = getbits_fast(num1); - *scf++ = 0; *scf++ = 0; *scf++ = 0; /* short[13][0..2] = 0 */ - } - else - { - int i; - int scfsi = gr_info->scfsi; - - if(scfsi < 0) - { /* scfsi < 0 => granule == 0 */ - for(i=11;i;i--) - *scf++ = getbits_fast(num0); - for(i=10;i;i--) - *scf++ = getbits_fast(num1); - numbits = (num0 + num1) * 10 + num0; - } - else - { - numbits = 0; - if(!(scfsi & 0x8)) - { - for (i=6;i;i--) - *scf++ = getbits_fast(num0); - numbits += num0 * 6; - } - else - { - *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ - *scf++ = 0; *scf++ = 0; *scf++ = 0; - } - - if(!(scfsi & 0x4)) - { - for (i=5;i;i--) - *scf++ = getbits_fast(num0); - numbits += num0 * 5; - } - else - { - *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ - *scf++ = 0; *scf++ = 0; - } - - if(!(scfsi & 0x2)) - { - for(i=5;i;i--) - *scf++ = getbits_fast(num1); - numbits += num1 * 5; - } - else - { - *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ - *scf++ = 0; *scf++ = 0; - } - - if(!(scfsi & 0x1)) - { - for (i=5;i;i--) - *scf++ = getbits_fast(num1); - numbits += num1 * 5; - } - else - { - *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ - *scf++ = 0; *scf++ = 0; - } - } - - *scf++ = 0; /* no l[21] in original sources */ - } - return numbits; -} -#endif - -static int III_get_scale_factors_2(int *scf,struct iemmp3_gr_info_s *gr_info,int i_stereo) -{ - unsigned char *pnt; - int i,j; - unsigned int slen; - int n = 0; - int numbits = 0; - - static unsigned char stab[3][6][4] = { - { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} , - { 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0} } , - { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} , - {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } , - { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} , - { 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0} } }; - - if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */ - slen = iemmp3_slen2[gr_info->scalefac_compress>>1]; - else - slen = iemmp3_n_slen2[gr_info->scalefac_compress]; - - gr_info->preflag = (slen>>15) & 0x1; - - n = 0; - if( gr_info->block_type == 2 ) - { - n++; - if(gr_info->mixed_block_flag) - n++; - } - - pnt = stab[n][(slen>>12)&0x7]; - - for(i=0;i<4;i++) - { - int num = slen & 0x7; - slen >>= 3; - if(num) - { - for(j=0;j<(int)(pnt[i]);j++) - *scf++ = getbits_fast(num); - numbits += pnt[i] * num; - } - else - { - for(j=0;j<(int)(pnt[i]);j++) - *scf++ = 0; - } - } - - n = (n << 1) + 1; - for(i=0;iscalefac_scale; - real *xrpnt = (real *) xr; - int l[3],l3; - int part2remain = gr_info->part2_3_length - part2bits; - int *me; - - { - int bv = gr_info->big_values; - int region1 = gr_info->region1start; - int region2 = gr_info->region2start; - - l3 = ((576>>1)-bv)>>1; - /* - * we may lose the 'odd' bit here !! - * check this later again - */ - if(bv <= region1) - { - l[0] = bv; l[1] = 0; l[2] = 0; - } - else - { - l[0] = region1; - if(bv <= region2) - { - l[1] = bv - l[0]; l[2] = 0; - } - else - { - l[1] = region2 - l[0]; l[2] = bv - region2; - } - } - } - - if(gr_info->block_type == 2) - { - /* - * decoding with short or mixed mode BandIndex table - */ - int i,max[4]; - int step=0,lwin=0,cb=0; - register real v = 0.0; - register int *m,mc; - - if(gr_info->mixed_block_flag) - { - max[3] = -1; - max[0] = max[1] = max[2] = 2; - m = iemmp3_map[sfreq][0]; - me = iemmp3_mapend[sfreq][0]; - } - else - { - max[0] = max[1] = max[2] = max[3] = -1; - /* max[3] not really needed in this case */ - m = iemmp3_map[sfreq][1]; - me = iemmp3_mapend[sfreq][1]; - } - - mc = 0; - for(i=0;i<2;i++) - { - int lp = l[i]; - struct iemmp3_newHuff *h = iemmp3_ht+gr_info->table_select[i]; - for(;lp;lp--,mc--) - { - register int x,y; - if( (!mc) ) - { - mc = *m++; - xrpnt = ((real *) xr) + (*m++); - lwin = *m++; - cb = *m++; - if(lwin == 3) - { - v = gr_info->pow2gain[(*scf++) << shift]; - step = 1; - } - else - { - v = gr_info->full_gain[lwin][(*scf++) << shift]; - step = 3; - } - } - { - register short *val = h->table; - while((y=*val++)<0) - { - if (get1bit()) - val -= y; - part2remain--; - } - x = y >> 4; - y &= 0xf; - } - if(x == 15) - { - max[lwin] = cb; - part2remain -= h->linbits+1; - x += getbits(h->linbits); - if(get1bit()) - *xrpnt = -iemmp3_ispow[x] * v; - else - *xrpnt = iemmp3_ispow[x] * v; - } - else if(x) - { - max[lwin] = cb; - if(get1bit()) - *xrpnt = -iemmp3_ispow[x] * v; - else - *xrpnt = iemmp3_ispow[x] * v; - part2remain--; - } - else - *xrpnt = 0.0; - xrpnt += step; - if(y == 15) - { - max[lwin] = cb; - part2remain -= h->linbits+1; - y += getbits(h->linbits); - if(get1bit()) - *xrpnt = -iemmp3_ispow[y] * v; - else - *xrpnt = iemmp3_ispow[y] * v; - } - else if(y) - { - max[lwin] = cb; - if(get1bit()) - *xrpnt = -iemmp3_ispow[y] * v; - else - *xrpnt = iemmp3_ispow[y] * v; - part2remain--; - } - else - *xrpnt = 0.0; - xrpnt += step; - } - } - for(;l3 && (part2remain > 0);l3--) - { - struct iemmp3_newHuff *h = iemmp3_htc+gr_info->count1table_select; - register short *val = h->table,a; - - while((a=*val++)<0) - { - part2remain--; - if(part2remain < 0) - { - part2remain++; - a = 0; - break; - } - if (get1bit()) - val -= a; - } - - for(i=0;i<4;i++) - { - if(!(i & 1)) - { - if(!mc) - { - mc = *m++; - xrpnt = ((real *) xr) + (*m++); - lwin = *m++; - cb = *m++; - if(lwin == 3) - { - v = gr_info->pow2gain[(*scf++) << shift]; - step = 1; - } - else - { - v = gr_info->full_gain[lwin][(*scf++) << shift]; - step = 3; - } - } - mc--; - } - if( (a & (0x8>>i)) ) - { - max[lwin] = cb; - part2remain--; - if(part2remain < 0) - { - part2remain++; - break; - } - if(get1bit()) - *xrpnt = -v; - else - *xrpnt = v; - } - else - *xrpnt = 0.0; - xrpnt += step; - } - } - - while( m < me ) - { - if(!mc) - { - mc = *m++; - xrpnt = ((real *) xr) + *m++; - if( (*m++) == 3) - step = 1; - else - step = 3; - m++; /* cb */ - } - mc--; - *xrpnt = 0.0; - xrpnt += step; - *xrpnt = 0.0; - xrpnt += step; - /* we could add a little opt. here: - * if we finished a band for window 3 or a long band - * further bands could copied in a simple loop without a - * special 'map' decoding - */ - } - - gr_info->maxband[0] = max[0]+1; - gr_info->maxband[1] = max[1]+1; - gr_info->maxband[2] = max[2]+1; - gr_info->maxbandl = max[3]+1; - - { - int rmax = max[0] > max[1] ? max[0] : max[1]; - rmax = (rmax > max[2] ? rmax : max[2]) + 1; - gr_info->maxb = rmax ? iemmp3_shortLimit[sfreq][rmax] : iemmp3_longLimit[sfreq][max[3]+1]; - } - - } - else - { - /* - * decoding with 'long' BandIndex table (block_type != 2) - */ - int *pretab = gr_info->preflag ? iemmp3_pretab1 : iemmp3_pretab2; - int i,max = -1; - int cb = 0; - register int *m = iemmp3_map[sfreq][2]; - register real v = 0.0; - register int mc = 0; - - /* - * long hash table values - */ - for(i=0;i<3;i++) - { - int lp = l[i]; - struct iemmp3_newHuff *h = iemmp3_ht+gr_info->table_select[i]; - - for(;lp;lp--,mc--) - { - int x,y; - - if(!mc) - { - mc = *m++; - v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; - cb = *m++; - } - { - register short *val = h->table; - while((y=*val++)<0) - { - if (get1bit()) - val -= y; - part2remain--; - } - x = y >> 4; - y &= 0xf; - } - if (x == 15) - { - max = cb; - part2remain -= h->linbits+1; - x += getbits(h->linbits); - if(get1bit()) - *xrpnt++ = -iemmp3_ispow[x] * v; - else - *xrpnt++ = iemmp3_ispow[x] * v; - } - else if(x) - { - max = cb; - if(get1bit()) - *xrpnt++ = -iemmp3_ispow[x] * v; - else - *xrpnt++ = iemmp3_ispow[x] * v; - part2remain--; - } - else - *xrpnt++ = 0.0; - - if (y == 15) - { - max = cb; - part2remain -= h->linbits+1; - y += getbits(h->linbits); - if(get1bit()) - *xrpnt++ = -iemmp3_ispow[y] * v; - else - *xrpnt++ = iemmp3_ispow[y] * v; - } - else if(y) - { - max = cb; - if(get1bit()) - *xrpnt++ = -iemmp3_ispow[y] * v; - else - *xrpnt++ = iemmp3_ispow[y] * v; - part2remain--; - } - else - *xrpnt++ = 0.0; - } - } - - /* - * short (count1table) values - */ - for(;l3 && (part2remain > 0);l3--) - { - struct iemmp3_newHuff *h = iemmp3_htc+gr_info->count1table_select; - register short *val = h->table,a; - - while((a=*val++)<0) - { - part2remain--; - if(part2remain < 0) - { - part2remain++; - a = 0; - break; - } - if (get1bit()) - val -= a; - } - - for(i=0;i<4;i++) - { - if(!(i & 1)) - { - if(!mc) - { - mc = *m++; - cb = *m++; - v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; - } - mc--; - } - if ( (a & (0x8>>i)) ) - { - max = cb; - part2remain--; - if(part2remain < 0) - { - part2remain++; - break; - } - if(get1bit()) - *xrpnt++ = -v; - else - *xrpnt++ = v; - } - else - *xrpnt++ = 0.0; - } - } - - /* - * zero part - */ - for(i=(&xr[SBLIMIT][0]-xrpnt)>>1;i;i--) - { - *xrpnt++ = 0.0; - *xrpnt++ = 0.0; - } - - gr_info->maxbandl = max+1; - gr_info->maxb = iemmp3_longLimit[sfreq][gr_info->maxbandl]; - } - - while( part2remain > 16 ) - { - getbits(16); /* Dismiss stuffing Bits */ - part2remain -= 16; - } - if(part2remain > 0) - getbits(part2remain); - else if(part2remain < 0) - { - post("mpg123: Can't rewind stream by %d bits!\n",-part2remain); - return 1; /* -> error */ - } - return 0; -} - -static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac, - struct iemmp3_gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf) -{ - real (*xr)[SBLIMIT*SSLIMIT] = (real (*)[SBLIMIT*SSLIMIT] ) xr_buf; - struct iemmp3_bandInfoStruct *bi = &bandInfo[sfreq]; - real *tab1,*tab2; - - if(lsf) - { - int p = gr_info->scalefac_compress & 0x1; - if(ms_stereo) - { - tab1 = iemmp3_pow1_2[p]; tab2 = iemmp3_pow2_2[p]; - } - else - { - tab1 = iemmp3_pow1_1[p]; tab2 = iemmp3_pow2_1[p]; - } - } - else - { - if(ms_stereo) - { - tab1 = iemmp3_tan1_2; tab2 = iemmp3_tan2_2; - } - else - { - tab1 = iemmp3_tan1_1; tab2 = iemmp3_tan2_1; - } - } - - if (gr_info->block_type == 2) - { - int lwin,do_l = 0; - if( gr_info->mixed_block_flag ) - do_l = 1; - - for (lwin=0;lwin<3;lwin++) /* process each window */ - { - /* get first band with zero values */ - int is_p,sb,idx,sfb = gr_info->maxband[lwin]; /* sfb is minimal 3 for mixed mode */ - if(sfb > 3) - do_l = 0; - - for(;sfb<12;sfb++) - { - is_p = scalefac[sfb*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ - if(is_p != 7) { - real t1,t2; - sb = bi->shortDiff[sfb]; - idx = bi->shortIdx[sfb] + lwin; - t1 = tab1[is_p]; t2 = tab2[is_p]; - for (; sb > 0; sb--,idx+=3) - { - real v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - } - -#if 1 - /* in the original: copy 10 to 11 , here: copy 11 to 12 - maybe still wrong??? (copy 12 to 13?) */ - is_p = scalefac[11*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ - sb = bi->shortDiff[12]; - idx = bi->shortIdx[12] + lwin; -#else - is_p = scalefac[10*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ - sb = bi->shortDiff[11]; - idx = bi->shortIdx[11] + lwin; -#endif - if(is_p != 7) - { - real t1,t2; - t1 = tab1[is_p]; t2 = tab2[is_p]; - for ( ; sb > 0; sb--,idx+=3 ) - { - real v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - } /* end for(lwin; .. ; . ) */ - - if (do_l) - { - /* also check l-part, if ALL bands in the three windows are 'empty' - * and mode = mixed_mode - */ - int sfb = gr_info->maxbandl; - int idx = bi->longIdx[sfb]; - - for ( ; sfb<8; sfb++ ) - { - int sb = bi->longDiff[sfb]; - int is_p = scalefac[sfb]; /* scale: 0-15 */ - if(is_p != 7) { - real t1,t2; - t1 = tab1[is_p]; t2 = tab2[is_p]; - for ( ; sb > 0; sb--,idx++) - { - real v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - else - idx += sb; - } - } - } - else /* ((gr_info->block_type != 2)) */ - { - int sfb = gr_info->maxbandl; - int is_p,idx = bi->longIdx[sfb]; - for ( ; sfb<21; sfb++) - { - int sb = bi->longDiff[sfb]; - is_p = scalefac[sfb]; /* scale: 0-15 */ - if(is_p != 7) { - real t1,t2; - t1 = tab1[is_p]; t2 = tab2[is_p]; - for ( ; sb > 0; sb--,idx++) - { - real v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - else - idx += sb; - } - - is_p = scalefac[20]; /* copy l-band 20 to l-band 21 */ - if(is_p != 7) - { - int sb; - real t1 = tab1[is_p],t2 = tab2[is_p]; - - for ( sb = bi->longDiff[21]; sb > 0; sb--,idx++ ) - { - real v = xr[0][idx]; - xr[0][idx] = v * t1; - xr[1][idx] = v * t2; - } - } - } /* ... */ -} - - -static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct iemmp3_gr_info_s *gr_info) -{ - int sblim; - - if(gr_info->block_type == 2) - { - if(!gr_info->mixed_block_flag) - return; - sblim = 1; - } - else { - sblim = gr_info->maxb-1; - } - - /* 31 alias-reduction operations between each pair of sub-bands */ - /* with 8 butterflies between each pair */ - - { - int sb; - real *xr1=(real *) xr[1]; - - for(sb=sblim;sb;sb--,xr1+=10) - { - int ss; - real *cs=iemmp3_aa_cs,*ca=iemmp3_aa_ca; - real *xr2 = xr1; - - for(ss=7;ss>=0;ss--) - { /* upper and lower butterfly inputs */ - register real bu = *--xr2,bd = *xr1; - *xr2 = (bu * (*cs) ) - (bd * (*ca) ); - *xr1++ = (bd * (*cs++) ) + (bu * (*ca++) ); - } - } - } -} - -static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT], - int ch,struct iemmp3_gr_info_s *gr_info) -{ - real *tspnt = (real *) tsOut; - real (*block)[2][SBLIMIT*SSLIMIT] = iemmp3_gmp->hybrid_block; - int *blc = iemmp3_gmp->hybrid_blc; - real *rawout1,*rawout2; - int bt; - unsigned int sb = 0; - - { - int b = blc[ch]; - rawout1=block[b][ch]; - b=-b+1; - rawout2=block[b][ch]; - blc[ch] = b; - } - - - if(gr_info->mixed_block_flag) { - sb = 2; - dct36(fsIn[0],rawout1,rawout2,iemmp3_win[0],tspnt); - dct36(fsIn[1],rawout1+18,rawout2+18,iemmp3_win1[0],tspnt+1); - rawout1 += 36; rawout2 += 36; tspnt += 2; - } - - bt = gr_info->block_type; - if(bt == 2) { - for (; sbmaxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) { - dct12(fsIn[sb],rawout1,rawout2,iemmp3_win[2],tspnt); - dct12(fsIn[sb+1],rawout1+18,rawout2+18,iemmp3_win1[2],tspnt+1); - } - } - else { - for (; sbmaxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) { - dct36(fsIn[sb],rawout1,rawout2,iemmp3_win[bt],tspnt); - dct36(fsIn[sb+1],rawout1+18,rawout2+18,iemmp3_win1[bt],tspnt+1); - } - } - - for(;sbsynth_bo; - - if(!channel) - { - bo--; - bo &= 0xf; - buf = iemmp3_gmp->synth_buffs[0]; - } - else - { - samples++; - buf = iemmp3_gmp->synth_buffs[1]; - } - - if(bo & 0x1) - { - b0 = buf[0]; - bo1 = bo; - dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr); - } - else - { - b0 = buf[1]; - bo1 = bo+1; - dct64(buf[0]+bo,buf[1]+bo+1,bandPtr); - } - - iemmp3_gmp->synth_bo = bo; - - { - register int j; - real *window = iemmp3_decwin + 16 - bo1; - - for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step) - { - real sum; - sum = window[0x0] * b0[0x0]; - sum -= window[0x1] * b0[0x1]; - sum += window[0x2] * b0[0x2]; - sum -= window[0x3] * b0[0x3]; - sum += window[0x4] * b0[0x4]; - sum -= window[0x5] * b0[0x5]; - sum += window[0x6] * b0[0x6]; - sum -= window[0x7] * b0[0x7]; - sum += window[0x8] * b0[0x8]; - sum -= window[0x9] * b0[0x9]; - sum += window[0xA] * b0[0xA]; - sum -= window[0xB] * b0[0xB]; - sum += window[0xC] * b0[0xC]; - sum -= window[0xD] * b0[0xD]; - sum += window[0xE] * b0[0xE]; - sum -= window[0xF] * b0[0xF]; - WRITE_SAMPLE(samples,sum,clip); - } - - { - real sum; - sum = window[0x0] * b0[0x0]; - sum += window[0x2] * b0[0x2]; - sum += window[0x4] * b0[0x4]; - sum += window[0x6] * b0[0x6]; - sum += window[0x8] * b0[0x8]; - sum += window[0xA] * b0[0xA]; - sum += window[0xC] * b0[0xC]; - sum += window[0xE] * b0[0xE]; - WRITE_SAMPLE(samples,sum,clip); - b0-=0x10,window-=0x20,samples+=step; - } - window += bo1<<1; - - for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step) - { - real sum; - sum = -window[-0x1] * b0[0x0]; - sum -= window[-0x2] * b0[0x1]; - sum -= window[-0x3] * b0[0x2]; - sum -= window[-0x4] * b0[0x3]; - sum -= window[-0x5] * b0[0x4]; - sum -= window[-0x6] * b0[0x5]; - sum -= window[-0x7] * b0[0x6]; - sum -= window[-0x8] * b0[0x7]; - sum -= window[-0x9] * b0[0x8]; - sum -= window[-0xA] * b0[0x9]; - sum -= window[-0xB] * b0[0xA]; - sum -= window[-0xC] * b0[0xB]; - sum -= window[-0xD] * b0[0xC]; - sum -= window[-0xE] * b0[0xD]; - sum -= window[-0xF] * b0[0xE]; - sum -= window[-0x0] * b0[0xF]; - WRITE_SAMPLE(samples,sum,clip); - } - } - *pnt += 128; - - return clip; -} - - - -static void *sigmp3play_new(void) -{ - char *vec; - t_sigmp3play *x = (t_sigmp3play *)pd_new(sigmp3play_class); - - x->file_is_open = 0; - x->play_state = 0; - x->mp3_encode_size = 0; - x->mp3_out_index = 0; - x->file_block_num = 0; - x->file_remain = 0; - x->file_size = 0; - x->mp3_ch = 1; - x->mp3_sr = 44100; - x->obj_sr = 44100; - x->obj_n = 1; - x->samp_per_frame = 1152; - x->mp3_byterate = 11; - x->down = 0; - x->scale = 1.0/32768.0; - x->offset_sec = 0.0; - x->fh = (FILE *)0L; - x->mp3inbuf = (char *)getzbytes(MY_MP3_MALLOC_IN_SIZE); - x->mp3outbuf = (char *)getzbytes(MY_MP3_MALLOC_OUT_SIZE); - x->filename = (char *)getzbytes(MY_MP3_MALLOC_FN); - x->begframeseek = (int *)0; - x->curframeseek = 0; - x->maxframeseek = 0; - x->frame_counter = 0; - x->time1_bang0_handle = 0; - x->time_factor = 0.0; - vec = x->filename; - *vec = 0; - InitMP3(&(x->mp)); - x->mp_is_init = 1; - x->x_clock = clock_new(x, (t_method)sigmp3play_tick); - outlet_new(&x->x_obj, &s_signal); - outlet_new(&x->x_obj, &s_signal); - x->x_floatout = outlet_new(&x->x_obj, &s_float); - x->x_bangout = outlet_new(&x->x_obj, &s_bang); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); - x->x_canvas = canvas_getcurrent(); - return (x); -} - -static void sigmp3play_cleanup(t_sigmp3play *x) -{ - x->file_is_open = 0; - fclose(x->fh); - x->play_state = 0; - x->mp3_out_index = 0; - x->mp_is_init = 0; - ExitMP3(&(x->mp)); - x->time1_bang0_handle = 0; - clock_delay(x->x_clock, 0); -} - -static int sigmp3play_read_frame_length_first(t_sigmp3play *x, int *frsz) -{ - int framesize, lsf, bitrate_index, sampling_frequency, padding, mpeg25, lay, ret=MP3_EX; - int version, syncword; - unsigned long head; - unsigned char chead; - - *frsz = 0; - if((x->file_size) >= 4) - { - fread(&chead, 1, sizeof(char), x->fh); - head = (unsigned int)chead; - fread(&chead, 1, sizeof(char), x->fh); - head <<= 8; - head |= (unsigned int)chead; - fread(&chead, 1, sizeof(char), x->fh); - head <<= 8; - head |= (unsigned int)chead; - fread(&chead, 1, sizeof(char), x->fh); - head <<= 8; - head |= (unsigned int)chead; - syncword = (head >> 20) & 0x0fff; - version = ((head >> 19) & 0x01) ? 0 : 1; - if((syncword & 0x01) == 0) - version = 2; - if(version == 0) - x->samp_per_frame = 1152; - else - x->samp_per_frame = 576; - - if(head & (1<<20)) - { - lsf = (head & (1<<19)) ? 0x0 : 0x1; - mpeg25 = 0; - } - else - { - lsf = 1; - mpeg25 = 1; - } - lay = 4-((head>>17)&3); - if(((head>>10)&0x3) == 0x3) - { - post("Stream error"); - return(MP3_EX); - } - if(mpeg25) - sampling_frequency = 6 + ((head>>10)&0x3); - else - sampling_frequency = ((head>>10)&0x3) + (lsf*3); - x->mp3_sr = (int)iemmp3_freqs[sampling_frequency]; - if(mpeg25) - bitrate_index = ((head>>12)&0xf); - bitrate_index = ((head>>12)&0xf); - padding = ((head>>9)&0x1); - if(!bitrate_index) - { - post("Free format not supported.\n"); - return(MP3_EX); - } - switch(lay) - { - case 1: - post("Layer I not supported!\n"); - break; - case 2: - post("Layer II not supported!\n"); - break; - case 3: - framesize = iemmp3_tabsel_123[lsf][2][bitrate_index]*144000; - framesize /= (iemmp3_freqs[sampling_frequency] << lsf); - framesize += padding; - *frsz = framesize; - ret = 0; - break; - default: - post("Sorry, unknown layer type.\n"); - break; - } - return(ret); - } - else - { - return(1); - } -} - -static int sigmp3play_read_frame_length_next(t_sigmp3play *x, int *frsz, int frame_counter) -{ - int framesize, lsf, bitrate_index, sampling_frequency, *begframeseek=x->begframeseek; - unsigned long head; - unsigned char chead; - - *frsz = 0; - if(begframeseek[frame_counter] < ((x->file_size) - 4)) - { - fread(&chead, 1, sizeof(char), x->fh); - head = (unsigned int)chead; - fread(&chead, 1, sizeof(char), x->fh); - head <<= 8; - head |= (unsigned int)chead; - fread(&chead, 1, sizeof(char), x->fh); - head <<= 8; - head |= (unsigned int)chead; - fread(&chead, 1, sizeof(char), x->fh); - head <<= 8; - head |= (unsigned int)chead; - if(head & (1<<20)) - { - lsf = (head & (1<<19)) ? 0x0 : 0x1; - sampling_frequency = ((head>>10)&0x3) + (lsf*3); - } - else - { - lsf = 1; - sampling_frequency = 6 + ((head>>10)&0x3); - } - bitrate_index = ((head>>12)&0xf); - framesize = iemmp3_tabsel_123[lsf][2][bitrate_index]*144000; - framesize /= (iemmp3_freqs[sampling_frequency] << lsf); - framesize += ((head>>9)&0x1); - *frsz = framesize; - return(0); - } - else - return(1); -} - -static int sigmp3play_calc_frames(t_sigmp3play *x) -{ - int *begframeseek=x->begframeseek, i, maxframeseek, framesize, frame_counter; - float length; - - fseek(x->fh,0,SEEK_SET); - if(!sigmp3play_read_frame_length_first(x, &framesize)) - { - if(framesize <= 0) - { - return(MP3_EX); - } - i = framesize - 6; - maxframeseek = (x->file_size) / i; - if(!begframeseek) - { - x->begframeseek = (int *)getzbytes((maxframeseek)*sizeof(int)); - x->maxframeseek = maxframeseek; - } - else - { - if(maxframeseek > (x->maxframeseek)) - { - freebytes(x->begframeseek, (x->maxframeseek)*sizeof(int)); - x->begframeseek = (int *)getzbytes((maxframeseek)*sizeof(int)); - x->maxframeseek = maxframeseek; - } - } - begframeseek = x->begframeseek; - begframeseek[0] = 0; - begframeseek[1] = framesize; - frame_counter = 1; - /*x->curframeseek = maxframeseek;*/ - fseek(x->fh, begframeseek[1], SEEK_SET); - while(!sigmp3play_read_frame_length_next(x, &framesize, frame_counter)) - { - begframeseek[frame_counter+1] = begframeseek[frame_counter] + framesize; - frame_counter++; - fseek(x->fh, begframeseek[frame_counter], SEEK_SET); - }; - frame_counter--; - length = (float)(frame_counter)*(float)(x->samp_per_frame) / (float)(x->mp3_sr); - x->length_sec = length; - x->time_factor = length / (float)(frame_counter); - x->curframeseek = frame_counter; - fseek(x->fh,0,SEEK_SET); - return(MP3_OK); - } - else - return(MP3_EX); -} - -static void sigmp3play_do_open(t_sigmp3play *x, char *str, int calc_it) -{ - int mp3_sr, obj_sr; - int file_size, size, mp3_encode_return=MP3_OK, mp3_read_length, i, j, *begframeseek; - static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" }; - static char *layers[4] = { "Unknown" , "I", "II", "III" }; - char completefilename[400]; - - if(x->file_is_open) - { - post("mp3play-ERROR: file is already open, please stop it first!"); - } - else if(*str == 0) - { - post("mp3play-ERROR: there is no filename to open"); - } - else - { - if(str[0] == '/') - { - strcpy(completefilename, str); - } - else if(((str[0] >= 'A')&&(str[0] <= 'Z')|| - (str[0] >= 'a')&&(str[0] <= 'z'))&& - (str[1] == ':')&&(str[2] == '/')) - { - strcpy(completefilename, str); - } - else - { - strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name); - strcat(completefilename, "/"); - strcat(completefilename, str); - } - - if((x->fh = fopen(completefilename, "rb")) == NULL) - { - post("mp3play-ERROR: cannot open %s", completefilename); - } - else - { - strcpy(x->filename, completefilename); - fseek(x->fh,0,SEEK_END); - file_size = (int)ftell(x->fh); - x->file_size = file_size; - if(!x->mp_is_init) - { - InitAgainMP3(&(x->mp)); - x->mp_is_init = 1; - } - if(calc_it) - mp3_encode_return = sigmp3play_calc_frames(x); - if(mp3_encode_return == MP3_EX) - { - sigmp3play_cleanup(x); - return; - } - if(x->frame_counter) - x->frame_counter = (int)(x->offset_sec / x->time_factor); - i = x->frame_counter; - if(i > (x->curframeseek - 1)) - i = x->curframeseek - 1; - begframeseek = x->begframeseek; - j = begframeseek[i]; - fseek(x->fh,j,SEEK_SET); - x->file_block_num = (file_size-j) / MY_MP3_MALLOC_IN_SIZE; - x->file_remain = (file_size-j) - (x->file_block_num)*MY_MP3_MALLOC_IN_SIZE; - if(x->file_block_num) - { - mp3_read_length = MY_MP3_MALLOC_IN_SIZE; - x->file_block_num--; - } - else - { - mp3_read_length = x->file_remain; - x->file_remain = 0; - } - if(mp3_read_length > 0) - { - fread(x->mp3inbuf, mp3_read_length, sizeof(char), x->fh); - mp3_encode_return = decodeMP3(&(x->mp), x->mp3inbuf, mp3_read_length, x->mp3outbuf, - MY_MP3_MALLOC_IN_SIZE2, &size); - if(mp3_encode_return == MP3_EX) - { - sigmp3play_cleanup(x); - return; - } - post ("MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d", - x->mp.fr.mpeg25 ? "2.5" : (x->mp.fr.lsf ? "2.0" : "1.0"), - layers[x->mp.fr.lay],iemmp3_freqs[x->mp.fr.sampling_frequency], - modes[x->mp.fr.mode],x->mp.fr.mode_ext,x->mp.fr.framesize+4); - post ("Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.", - x->mp.fr.stereo,x->mp.fr.copyright?"Yes":"No", - x->mp.fr.original?"Yes":"No",x->mp.fr.error_protection?"Yes":"No", - x->mp.fr.emphasis); - post ("Bitrate: %d Kbits/s, Extension value: %d", - iemmp3_tabsel_123[x->mp.fr.lsf][x->mp.fr.lay-1] - [x->mp.fr.bitrate_index],x->mp.fr.extension); - post ("Original Soundfile-Length : %.3f sec.\n",x->length_sec); - - x->mp3_byterate = 128*iemmp3_tabsel_123[x->mp.fr.lsf][x->mp.fr.lay-1][x->mp.fr.bitrate_index]; - /* 1024/8 */ - - if(x->mp.fr.stereo == 2) - x->mp3_ch = 2; - else if(x->mp.fr.stereo == 1) - x->mp3_ch = 1; - else - { - x->mp3_ch = 1; - post("mp3_play~ WARNING: unknown number of channels : %d channels", - x->mp.fr.stereo); - } - mp3_sr = (int)(iemmp3_freqs[x->mp.fr.sampling_frequency]); - obj_sr = x->obj_sr; - x->mp3_sr = mp3_sr; - if(mp3_sr == obj_sr) - { - x->down = 0; - } - else if(2*mp3_sr == obj_sr) - { - x->down = 1; - } - else if(4*mp3_sr == obj_sr) - { - x->down = 2; - } - else if(mp3_sr == 2*obj_sr) - { - x->down = -1; - } - else if(mp3_sr == 4*obj_sr) - { - x->down = -2; - } - else - { - post("mp3_play~ WARNING: playing the filesamplerate of %d Hz at %d Hz", mp3_sr,obj_sr); - x->down = 0; - } - - if(mp3_encode_return == MP3_OK) - { - x->file_is_open = 1; - x->mp3_encode_size = size * sizeof(char) / sizeof(short); - } - else - { - x->file_is_open = 0; - x->mp3_out_index = 0; - fclose(x->fh); - } - } - else - { - x->file_is_open = 0; - fclose(x->fh); - } - } - x->play_state = 2; - x->mp3_out_index = 0; - } -} - -static t_int *sigmp3play_perform(t_int *w) -{ - t_sigmp3play *x = (t_sigmp3play *)(w[1]); - t_float *out1 = (t_float *)(w[2]); - t_float *out2 = (t_float *)(w[3]); - int n = (int)(w[4]); - short *ivec = (short *)(x->mp3outbuf); - int size, mp3_encode_return, mp3_read_length, mp3_ch, down; - float scale = x->scale, outa, outb; - int mp3_out_index = x->mp3_out_index; - - if (!x->file_is_open) - goto sigmp3play_labelzero; - if (x->play_state != 1) - goto sigmp3play_labelzero; - - if(mp3_out_index >= x->mp3_encode_size) - { - x->frame_counter++; - x->time1_bang0_handle = 1; - clock_delay(x->x_clock, 0); - mp3_out_index = 0; - mp3_encode_return = decodeMP3(&(x->mp), NULL, 0, x->mp3outbuf, - MY_MP3_MALLOC_IN_SIZE2, &size); - if(mp3_encode_return == MP3_OK) - x->mp3_encode_size = size * sizeof(char) / sizeof(short); - else if(mp3_encode_return == MP3_EX) - { - sigmp3play_cleanup(x); - goto sigmp3play_labelzero; - } - else - { - if(x->file_block_num > 0) - { - mp3_read_length = MY_MP3_MALLOC_IN_SIZE; - x->file_block_num--; - } - else if(x->file_remain > 0) - { - mp3_read_length = x->file_remain; - x->file_remain = 0; - } - else - { - sigmp3play_cleanup(x); - goto sigmp3play_labelzero; - } - - fread(x->mp3inbuf, mp3_read_length, sizeof(char), x->fh); - mp3_encode_return = decodeMP3(&(x->mp), x->mp3inbuf, mp3_read_length, - x->mp3outbuf, MY_MP3_MALLOC_IN_SIZE2, &size); - x->mp3_encode_size = size * sizeof(char) / sizeof(short); - if(mp3_encode_return == MP3_EX) - { - sigmp3play_cleanup(x); - goto sigmp3play_labelzero; - } - } - } - - mp3_ch = x->mp3_ch; - down = x->down; - if(mp3_ch == 2) - { - if(down == 0) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + 2*n; - while (n--) - { - *out1++ = scale * (float)(*ivec++); - *out2++ = scale * (float)(*ivec++); - } - } - else if(down == 1) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + n; - n /= 2; - while (n--) - { - outa = scale * (float)(*ivec++); - outb = scale * (float)(*ivec++); - *out1++ = outa; - *out2++ = outb; - *out1++ = outa; - *out2++ = outb; - } - } - else if(down == 2) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + n/2; - n /= 4; - while (n--) - { - outa = scale * (float)(*ivec++); - outb = scale * (float)(*ivec++); - *out1++ = outa; - *out2++ = outb; - *out1++ = outa; - *out2++ = outb; - *out1++ = outa; - *out2++ = outb; - *out1++ = outa; - *out2++ = outb; - } - } - else if(down == -1) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + 4*n; - while (n--) - { - outa = scale * (float)(*ivec++); - outb = scale * (float)(*ivec); - ivec += 3; - *out1++ = outa; - *out2++ = outa; - } - } - else if(down == -2) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + 8*n; - while (n--) - { - outa = scale * (float)(*ivec++); - outb = scale * (float)(*ivec); - ivec += 7; - *out1++ = outa; - *out2++ = outa; - } - } - } - else - { - if(down == 0) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + n; - while (n--) - { - outa = scale * (float)(*ivec++); - *out1++ = outa; - *out2++ = outa; - } - } - else if(down == 1) - { - ivec += mp3_out_index; - n /= 2; - x->mp3_out_index = mp3_out_index + n; - while (n--) - { - outa = scale * (float)(*ivec++); - *out1++ = outa; - *out2++ = outa; - *out1++ = outa; - *out2++ = outa; - } - } - else if(down == 2) - { - ivec += mp3_out_index; - n /= 4; - x->mp3_out_index = mp3_out_index + n; - while (n--) - { - outa = scale * (float)(*ivec++); - *out1++ = outa; - *out2++ = outa; - *out1++ = outa; - *out2++ = outa; - *out1++ = outa; - *out2++ = outa; - *out1++ = outa; - *out2++ = outa; - } - } - else if(down == -1) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + 2*n; - while (n--) - { - outa = scale * (float)(*ivec); - ivec += 2; - *out1++ = outa; - *out2++ = outa; - } - } - else if(down == -2) - { - ivec += mp3_out_index; - x->mp3_out_index = mp3_out_index + 4*n; - while (n--) - { - outa = scale * (float)(*ivec); - ivec += 4; - *out1++ = outa; - *out2++ = outa; - } - } - } - return (w+5); - -sigmp3play_labelzero: - - while (n--) - { - *out1++ = 0; - *out2++ = 0; - } - return (w+5); -} - -static void sigmp3play_dsp(t_sigmp3play *x, t_signal **sp) -{ - x->obj_sr = (int)(sp[0]->s_sr); - x->obj_n = (int)(sp[0]->s_n); - dsp_add(sigmp3play_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); -} - - - -static void sigmp3play_stop(t_sigmp3play *x) -{ - if(x->file_is_open) - { - x->file_block_num = 0; - x->file_remain = 0; - } -} - -static void sigmp3play_start(t_sigmp3play *x) -{ - if(x->file_is_open) - { - x->play_state = 1; - } -} - -static void sigmp3play_ft1(t_sigmp3play *x, t_floatarg offset) -{ - if(offset < 0.0) - offset = 0.0; - x->offset_sec = (float)offset; -} - -static void sigmp3play_pause(t_sigmp3play *x) -{ - if(x->file_is_open) - { - if(x->play_state == 0) - x->play_state = 1; - else if(x->play_state == 1) - x->play_state = 0; - } -} - -static void sigmp3play_open(t_sigmp3play *x, t_symbol *s) -{ - x->frame_counter = 0; - sigmp3play_do_open(x, (char *)s->s_name, 1); -} - -static void sigmp3play_open_again(t_sigmp3play *x) -{ - x->frame_counter = 0; - sigmp3play_do_open(x, x->filename, 0); -} - -static void sigmp3play_open_at(t_sigmp3play *x, t_symbol *s) -{ - x->frame_counter = 1; - sigmp3play_do_open(x, (char *)s->s_name, 1); -} - -static void sigmp3play_open_again_at(t_sigmp3play *x) -{ - x->frame_counter = 1; - sigmp3play_do_open(x, x->filename, 0); -} - - -static void sigmp3play_tick(t_sigmp3play *x) -{ - if(x->time1_bang0_handle) - { - outlet_float(x->x_floatout, (float)(x->frame_counter)*(x->time_factor)); - } - else - { - outlet_bang(x->x_bangout); - } -} - -static void sigmp3play_free(t_sigmp3play *x) -{ - if(x->mp_is_init) - ExitMP3(&(x->mp)); - if(x->begframeseek) - freebytes(x->begframeseek, (x->maxframeseek)*sizeof(int)); - freebytes(x->filename, MY_MP3_MALLOC_FN); - freebytes(x->mp3outbuf, MY_MP3_MALLOC_OUT_SIZE); - freebytes(x->mp3inbuf, MY_MP3_MALLOC_IN_SIZE); - clock_free(x->x_clock); -} - -void sigmp3play_setup(void) -{ - sigmp3play_class = class_new(gensym("mp3play~"), (t_newmethod)sigmp3play_new, - (t_method)sigmp3play_free, sizeof(t_sigmp3play), 0, 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_dsp, gensym("dsp"), 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_start, gensym("start"), 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_ft1, - gensym("ft1"), A_FLOAT, 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_stop, gensym("stop"), 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_pause, gensym("pause"), 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_again_at, gensym("open_again_at"), 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_open, gensym("open"), A_DEFSYM, 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_again, gensym("open_again"), 0); - class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_at, gensym("open_at"), A_DEFSYM, 0); - class_sethelpsymbol(sigmp3play_class, gensym("iemhelp/help-mp3play~")); - /*post("\nmp3play~ written by thomas musil & norbert math\nV 0.1 iem graz - austria 05 2000\n");*/ -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_mp3 written by Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +/* + sigmp3play.c - Mpeg Layer III Player for PD + Version:0.1 + 05-18-2000 + written by Thomas Musil (musil_at_iem.kug.ac.at), Norbert Math (math_at_iem.kug.ac.at) + IEM Graz + + debugged for windows 013-03-2003 + + This MPEG Player is based on the mpglib 0.2 by Michael Hipp which comes with mpg123-0.59r + + please see the README file for copyright notices! + + */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifndef NT +#include +#include +#endif + + +#define IEM_MPEG1 + +#ifdef _WIN32 +# undef WIN32 +# define WIN32 + +# define M_PI 3.14159265358979323846 +# define M_SQRT2 1.41421356237309504880 +# define REAL_IS_FLOAT +# define NEW_DCT9 + +# define random rand +# define srandom srand + +#endif + +#ifdef REAL_IS_FLOAT +# define real float +#elif defined(REAL_IS_LONG_DOUBLE) +# define real long double +#else +# define real double +#endif + +#ifdef __GNUC__ +#define INLINE inline +#else +#define INLINE +#endif + +/* AUDIOBUFSIZE = n*64 with n=1,2,3 ... */ +#define AUDIOBUFSIZE 16384 + +#define FALSE 0 +#define TRUE 1 +#define SBLIMIT 32 +#define SSLIMIT 18 +#define MPG_MD_STEREO 0 +#define MPG_MD_JOINT_STEREO 1 +#define MPG_MD_DUAL_CHANNEL 2 +#define MPG_MD_MONO 3 + +#define MAXFRAMESIZE 1792 +/* Pre Shift fo 16 to 8 bit converter table */ +#define AUSHIFT (3) +#define BOOL int +#define MP3_EX -2 +#define MP3_ERR -1 +#define MP3_OK 0 +#define MP3_NEED_MORE 1 + +#define WRITE_SAMPLE(samples,sum,clip) \ + if( (sum) > 32767.0) { *(samples) = 0x7fff; (clip)++; } \ + else if( (sum) < -32768.0) { *(samples) = -0x8000; (clip)++; } \ + else { *(samples) = sum; } + + +#define HDRCMPMASK 0xfffffd00 + + +#define MY_MP3_MALLOC_IN_SIZE 16384 +#define MY_MP3_MALLOC_IN_SIZE2 8192 +#define MY_MP3_MALLOC_OUT_SIZE 65536 +#define MY_MP3_MALLOC_FN 400 +#define MY_MP3_CHSAMP_PER_FRAME 1152 + +struct iemmp3_frame +{ + int stereo; + int jsbound; + int single; + int lsf; + int mpeg25; + int header_change; + int lay; + 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 */ +}; + +struct iemmp3_gr_info_s +{ + int scfsi; + unsigned part2_3_length; + unsigned big_values; + unsigned scalefac_compress; + unsigned block_type; + unsigned mixed_block_flag; + unsigned table_select[3]; + unsigned subblock_gain[3]; + unsigned maxband[3]; + unsigned maxbandl; + unsigned maxb; + unsigned region1start; + unsigned region2start; + unsigned preflag; + unsigned scalefac_scale; + unsigned count1table_select; + real *full_gain[3]; + real *pow2gain; +}; + +struct iemmp3_III_sideinfo +{ + unsigned main_data_begin; + unsigned private_bits; + struct + { + struct iemmp3_gr_info_s gr[2]; + } ch[2]; +}; + +struct iemmp3_buf +{ + unsigned char *pnt; + long size; + long pos; + struct iemmp3_buf *next; + struct iemmp3_buf *prev; +}; + +struct iemmp3Struct +{ + struct iemmp3_buf *head,*tail; + int bsize; + int framesize; + int fsizeold; + struct iemmp3_frame fr; + unsigned char bsspace[2][MAXFRAMESIZE+512]; /* MAXFRAMESIZE */ + real hybrid_block[2][2][SBLIMIT*SSLIMIT]; + int hybrid_blc[2]; + unsigned long header; + int bsnum; + real synth_buffs[2][2][0x110]; + int synth_bo; +}; + +struct iemmp3_bandInfoStruct +{ + short longIdx[23]; + short longDiff[22]; + short shortIdx[14]; + short shortDiff[13]; +}; + +struct iemmp3_newHuff +{ + unsigned int linbits; + short *table; +}; + + +typedef struct _sigmp3play +{ + t_object x_obj; + float length_sec; + int samp_per_frame; + int frame_counter; + int time1_bang0_handle; + float time_factor; + int *begframeseek; + int curframeseek; + int maxframeseek; + char *filename; + float offset_sec; + int file_is_open; + int play_state; + int mp3_encode_size; + int mp3_out_index; + int file_size; + int file_block_num; + int file_remain; + int mp_is_init; + int mp3_ch; + int mp3_sr; + int mp3_byterate; + int obj_sr; + int obj_n; + int down; + float scale; + FILE *fh; + char *mp3inbuf; + char *mp3outbuf; + struct iemmp3Struct mp; + t_clock *x_clock; + t_outlet *x_bangout; + t_outlet *x_floatout; + t_canvas *x_canvas; +} t_sigmp3play; + + + +static BOOL InitMP3 (struct iemmp3Struct *mp); +static BOOL InitAgainMP3(struct iemmp3Struct *mp); +static void ExitMP3 (struct iemmp3Struct *mp); +static int decodeMP3 (struct iemmp3Struct *mp, char *in, int isize, char *out, int osize, int *done); +static void make_decode_tables (long scaleval); +static void init_layer3 (int down_sample_sblimit); +static int decode_header (struct iemmp3_frame *fr,unsigned long newhead); +static int do_layer3(struct iemmp3_frame *fr,unsigned char *pcm_sample,int *pcm_point,int *err); +static int set_pointer(long backstep); +static int synth_1to1_mono(real *bandPtr,unsigned char *samples,int *pnt); +static int synth_1to1(real *bandPtr,int channel,unsigned char *out,int *pnt); +static struct iemmp3_buf *addbuf(struct iemmp3Struct *mp,char *buf,int size); +static void remove_buf(struct iemmp3Struct *mp); +static int read_head(struct iemmp3Struct *mp); +static int read_buf_byte(struct iemmp3Struct *mp,int *err); +static int III_get_side_info_2(struct iemmp3_III_sideinfo *si,int stereo, int ms_stereo,long sfreq,int single); +#ifdef IEM_MPEG1 +static int III_get_side_info_1(struct iemmp3_III_sideinfo *si,int stereo,int ms_stereo,long sfreq,int single); +static int III_get_scale_factors_1(int *scf,struct iemmp3_gr_info_s *gr_info); +#endif +static int III_get_scale_factors_2(int *scf,struct iemmp3_gr_info_s *gr_info,int i_stereo); +static int III_dequantize_sample(real xr[SBLIMIT][SSLIMIT],int *scf,struct iemmp3_gr_info_s *gr_info,int sfreq,int part2bits); +static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac,struct iemmp3_gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf); +static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct iemmp3_gr_info_s *gr_info); +static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT],int ch,struct iemmp3_gr_info_s *gr_info); +static void dct64(real *a,real *b,real *c); +static void dct64_1(real *out0,real *out1,real *b1,real *b2,real *samples); +static void dct36(real *inbuf,real *o1,real *o2,real *wintab,real *tsbuf); +static void dct12(real *in,real *rawout1,real *rawout2,register real *wi,register real *ts); +static unsigned int getbits(int number_of_bits); +static unsigned int getbits_fast(int number_of_bits); +static unsigned int get1bit(void); + +static void sigmp3play_tick(t_sigmp3play *x); + + +struct iemmp3Struct *iemmp3_gmp; + +int iemmp3_tabsel_123[2][3][16] = { + { {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,}, + {0,32,48,56, 64, 80, 96,112,128,160,192,224,256,320,384,}, + {0,32,40,48, 56, 64, 80, 96,112,128,160,192,224,256,320,} }, + + { {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,}, + {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,} } +}; + +long iemmp3_freqs[9] = { 44100, 48000, 32000, +22050, 24000, 16000 , +11025 , 12000 , 8000 }; + +int iemmp3_bitindex; +unsigned char *iemmp3_wordpointer; + +static real iemmp3_ispow[8207]; +static real iemmp3_aa_ca[8],iemmp3_aa_cs[8]; +static real iemmp3_COS1[12][6]; +static real iemmp3_win[4][36]; +static real iemmp3_win1[4][36]; +static real iemmp3_gainpow2[256+118+4]; +static real iemmp3_COS9[9]; +static real iemmp3_COS6_1,iemmp3_COS6_2; +static real iemmp3_tfcos36[9]; +static real iemmp3_tfcos12[3]; + +int iemmp3_longLimit[9][23]; +int iemmp3_shortLimit[9][14]; + +struct iemmp3_bandInfoStruct bandInfo[9] = { + + /* MPEG 1.0 */ + { {0,4,8,12,16,20,24,30,36,44,52,62,74, 90,110,134,162,196,238,288,342,418,576}, + {4,4,4,4,4,4,6,6,8, 8,10,12,16,20,24,28,34,42,50,54, 76,158}, + {0,4*3,8*3,12*3,16*3,22*3,30*3,40*3,52*3,66*3, 84*3,106*3,136*3,192*3}, + {4,4,4,4,6,8,10,12,14,18,22,30,56} } , + + { {0,4,8,12,16,20,24,30,36,42,50,60,72, 88,106,128,156,190,230,276,330,384,576}, + {4,4,4,4,4,4,6,6,6, 8,10,12,16,18,22,28,34,40,46,54, 54,192}, + {0,4*3,8*3,12*3,16*3,22*3,28*3,38*3,50*3,64*3, 80*3,100*3,126*3,192*3}, + {4,4,4,4,6,6,10,12,14,16,20,26,66} } , + + { {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576} , + {4,4,4,4,4,4,6,6,8,10,12,16,20,24,30,38,46,56,68,84,102, 26} , + {0,4*3,8*3,12*3,16*3,22*3,30*3,42*3,58*3,78*3,104*3,138*3,180*3,192*3} , + {4,4,4,4,6,8,12,16,20,26,34,42,12} } , + + /* MPEG 2.0 */ + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 } , + {0,4*3,8*3,12*3,18*3,24*3,32*3,42*3,56*3,74*3,100*3,132*3,174*3,192*3} , + {4,4,4,6,6,8,10,14,18,26,32,42,18 } } , + + { {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, + {6,6,6,6,6,6,8,10,12,14,16,18,22,26,32,38,46,52,64,70,76,36 } , + {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,136*3,180*3,192*3} , + {4,4,4,6,8,10,12,14,18,24,32,44,12 } } , + + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54 }, + {0,4*3,8*3,12*3,18*3,26*3,36*3,48*3,62*3,80*3,104*3,134*3,174*3,192*3}, + {4,4,4,6,8,10,12,14,18,24,30,40,18 } } , + /* MPEG 2.5 */ + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, + {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, + {4,4,4,6,8,10,12,14,18,24,30,40,18} }, + { {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576} , + {6,6,6,6,6,6,8,10,12,14,16,20,24,28,32,38,46,52,60,68,58,54}, + {0,12,24,36,54,78,108,144,186,240,312,402,522,576}, + {4,4,4,6,8,10,12,14,18,24,30,40,18} }, + { {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, + {12,12,12,12,12,12,16,20,24,28,32,40,48,56,64,76,90,2,2,2,2,2}, + {0, 24, 48, 72,108,156,216,288,372,480,486,492,498,576}, + {8,8,8,12,16,20,24,28,36,2,2,2,26} } , +}; + +static int iemmp3_mapbuf0[9][152]; +static int iemmp3_mapbuf1[9][156]; +static int iemmp3_mapbuf2[9][44]; +static int *iemmp3_map[9][3]; +static int *iemmp3_mapend[9][3]; + +static unsigned int iemmp3_n_slen2[512]; /* MPEG 2.0 slen for 'normal' mode */ +static unsigned int iemmp3_slen2[256]; /* MPEG 2.0 slen for intensity stereo */ + +static real iemmp3_tan1_1[16],iemmp3_tan2_1[16],iemmp3_tan1_2[16],iemmp3_tan2_2[16]; +static real iemmp3_pow1_1[2][16],iemmp3_pow2_1[2][16],iemmp3_pow1_2[2][16],iemmp3_pow2_2[2][16]; + +static int iemmp3_pretab1[22] = {0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,2,2,3,3,3,2,0}; +static int iemmp3_pretab2[22] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + +real iemmp3_decwin[512+32]; +static real iemmp3_cos64[16],iemmp3_cos32[8],iemmp3_cos16[4],iemmp3_cos8[2],iemmp3_cos4[1]; +real *iemmp3_pnts[] = { iemmp3_cos64,iemmp3_cos32,iemmp3_cos16,iemmp3_cos8,iemmp3_cos4 }; + +static long iemmp3_intwinbase[] = { + 0, -1, -1, -1, -1, -1, -1, -2, -2, -2, + -2, -3, -3, -4, -4, -5, -5, -6, -7, -7, + -8, -9, -10, -11, -13, -14, -16, -17, -19, -21, + -24, -26, -29, -31, -35, -38, -41, -45, -49, -53, + -58, -63, -68, -73, -79, -85, -91, -97, -104, -111, + -117, -125, -132, -139, -147, -154, -161, -169, -176, -183, + -190, -196, -202, -208, -213, -218, -222, -225, -227, -228, + -228, -227, -224, -221, -215, -208, -200, -189, -177, -163, + -146, -127, -106, -83, -57, -29, 2, 36, 72, 111, + 153, 197, 244, 294, 347, 401, 459, 519, 581, 645, + 711, 779, 848, 919, 991, 1064, 1137, 1210, 1283, 1356, + 1428, 1498, 1567, 1634, 1698, 1759, 1817, 1870, 1919, 1962, + 2001, 2032, 2057, 2075, 2085, 2087, 2080, 2063, 2037, 2000, + 1952, 1893, 1822, 1739, 1644, 1535, 1414, 1280, 1131, 970, + 794, 605, 402, 185, -45, -288, -545, -814, -1095, -1388, + -1692, -2006, -2330, -2663, -3004, -3351, -3705, -4063, -4425, -4788, + -5153, -5517, -5879, -6237, -6589, -6935, -7271, -7597, -7910, -8209, + -8491, -8755, -8998, -9219, -9416, -9585, -9727, -9838, -9916, -9959, + -9966, -9935, -9863, -9750, -9592, -9389, -9139, -8840, -8492, -8092, + -7640, -7134, -6574, -5959, -5288, -4561, -3776, -2935, -2037, -1082, + -70, 998, 2122, 3300, 4533, 5818, 7154, 8540, 9975, 11455, + 12980, 14548, 16155, 17799, 19478, 21189, 22929, 24694, 26482, 28289, + 30112, 31947, 33791, 35640, 37489, 39336, 41176, 43006, 44821, 46617, + 48390, 50137, 51853, 53534, 55178, 56778, 58333, 59838, 61289, 62684, + 64019, 65290, 66494, 67629, 68692, 69679, 70590, 71420, 72169, 72835, + 73415, 73908, 74313, 74630, 74856, 74992, 75038 }; + +static short iemmp3_tab0[] = +{ + 0 +}; + +static short iemmp3_tab1[] = +{ + -5, -3, -1, 17, 1, 16, 0 +}; + +static short iemmp3_tab2[] = +{ + -15, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 17, -1, 1, + 16, 0 +}; + +static short iemmp3_tab3[] = +{ + -13, -11, -9, -5, -3, -1, 34, 2, 18, -1, 33, 32, 16, 17, -1, + 1, 0 +}; + +static short iemmp3_tab5[] = +{ + -29, -25, -23, -15, -7, -5, -3, -1, 51, 35, 50, 49, -3, -1, 19, + 3, -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, 17, -1, 1, 16, + 0 +}; + +static short iemmp3_tab6[] = +{ + -25, -19, -13, -9, -5, -3, -1, 51, 3, 35, -1, 50, 48, -1, 19, + 49, -3, -1, 34, 2, 18, -3, -1, 33, 32, 1, -1, 17, -1, 16, + 0 +}; + +static short iemmp3_tab7[] = +{ + -69, -65, -57, -39, -29, -17, -11, -7, -3, -1, 85, 69, -1, 84, 83, + -1, 53, 68, -3, -1, 37, 82, 21, -5, -1, 81, -1, 5, 52, -1, + 80, -1, 67, 51, -5, -3, -1, 36, 66, 20, -1, 65, 64, -11, -7, + -3, -1, 4, 35, -1, 50, 3, -1, 19, 49, -3, -1, 48, 34, 18, + -5, -1, 33, -1, 2, 32, 17, -1, 1, 16, 0 +}; + +static short iemmp3_tab8[] = +{ + -65, -63, -59, -45, -31, -19, -13, -7, -5, -3, -1, 85, 84, 69, 83, + -3, -1, 53, 68, 37, -3, -1, 82, 5, 21, -5, -1, 81, -1, 52, + 67, -3, -1, 80, 51, 36, -5, -3, -1, 66, 20, 65, -3, -1, 4, + 64, -1, 35, 50, -9, -7, -3, -1, 19, 49, -1, 3, 48, 34, -1, + 2, 32, -1, 18, 33, 17, -3, -1, 1, 16, 0 +}; + +static short iemmp3_tab9[] = +{ + -63, -53, -41, -29, -19, -11, -5, -3, -1, 85, 69, 53, -1, 83, -1, + 84, 5, -3, -1, 68, 37, -1, 82, 21, -3, -1, 81, 52, -1, 67, + -1, 80, 4, -7, -3, -1, 36, 66, -1, 51, 64, -1, 20, 65, -5, + -3, -1, 35, 50, 19, -1, 49, -1, 3, 48, -5, -3, -1, 34, 2, + 18, -1, 33, 32, -3, -1, 17, 1, -1, 16, 0 +}; + +static short iemmp3_tab10[] = +{ + -125,-121,-111, -83, -55, -35, -21, -13, -7, -3, -1, 119, 103, -1, 118, + 87, -3, -1, 117, 102, 71, -3, -1, 116, 86, -1, 101, 55, -9, -3, + -1, 115, 70, -3, -1, 85, 84, 99, -1, 39, 114, -11, -5, -3, -1, + 100, 7, 112, -1, 98, -1, 69, 53, -5, -1, 6, -1, 83, 68, 23, + -17, -5, -1, 113, -1, 54, 38, -5, -3, -1, 37, 82, 21, -1, 81, + -1, 52, 67, -3, -1, 22, 97, -1, 96, -1, 5, 80, -19, -11, -7, + -3, -1, 36, 66, -1, 51, 4, -1, 20, 65, -3, -1, 64, 35, -1, + 50, 3, -3, -1, 19, 49, -1, 48, 34, -7, -3, -1, 18, 33, -1, + 2, 32, 17, -1, 1, 16, 0 +}; + +static short iemmp3_tab11[] = +{ + -121,-113, -89, -59, -43, -27, -17, -7, -3, -1, 119, 103, -1, 118, 117, + -3, -1, 102, 71, -1, 116, -1, 87, 85, -5, -3, -1, 86, 101, 55, + -1, 115, 70, -9, -7, -3, -1, 69, 84, -1, 53, 83, 39, -1, 114, + -1, 100, 7, -5, -1, 113, -1, 23, 112, -3, -1, 54, 99, -1, 96, + -1, 68, 37, -13, -7, -5, -3, -1, 82, 5, 21, 98, -3, -1, 38, + 6, 22, -5, -1, 97, -1, 81, 52, -5, -1, 80, -1, 67, 51, -1, + 36, 66, -15, -11, -7, -3, -1, 20, 65, -1, 4, 64, -1, 35, 50, + -1, 19, 49, -5, -3, -1, 3, 48, 34, 33, -5, -1, 18, -1, 2, + 32, 17, -3, -1, 1, 16, 0 +}; + +static short iemmp3_tab12[] = +{ + -115, -99, -73, -45, -27, -17, -9, -5, -3, -1, 119, 103, 118, -1, 87, + 117, -3, -1, 102, 71, -1, 116, 101, -3, -1, 86, 55, -3, -1, 115, + 85, 39, -7, -3, -1, 114, 70, -1, 100, 23, -5, -1, 113, -1, 7, + 112, -1, 54, 99, -13, -9, -3, -1, 69, 84, -1, 68, -1, 6, 5, + -1, 38, 98, -5, -1, 97, -1, 22, 96, -3, -1, 53, 83, -1, 37, + 82, -17, -7, -3, -1, 21, 81, -1, 52, 67, -5, -3, -1, 80, 4, + 36, -1, 66, 20, -3, -1, 51, 65, -1, 35, 50, -11, -7, -5, -3, + -1, 64, 3, 48, 19, -1, 49, 34, -1, 18, 33, -7, -5, -3, -1, + 2, 32, 0, 17, -1, 1, 16 +}; + +static short iemmp3_tab13[] = +{ + -509,-503,-475,-405,-333,-265,-205,-153,-115, -83, -53, -35, -21, -13, -9, + -7, -5, -3, -1, 254, 252, 253, 237, 255, -1, 239, 223, -3, -1, 238, + 207, -1, 222, 191, -9, -3, -1, 251, 206, -1, 220, -1, 175, 233, -1, + 236, 221, -9, -5, -3, -1, 250, 205, 190, -1, 235, 159, -3, -1, 249, + 234, -1, 189, 219, -17, -9, -3, -1, 143, 248, -1, 204, -1, 174, 158, + -5, -1, 142, -1, 127, 126, 247, -5, -1, 218, -1, 173, 188, -3, -1, + 203, 246, 111, -15, -7, -3, -1, 232, 95, -1, 157, 217, -3, -1, 245, + 231, -1, 172, 187, -9, -3, -1, 79, 244, -3, -1, 202, 230, 243, -1, + 63, -1, 141, 216, -21, -9, -3, -1, 47, 242, -3, -1, 110, 156, 15, + -5, -3, -1, 201, 94, 171, -3, -1, 125, 215, 78, -11, -5, -3, -1, + 200, 214, 62, -1, 185, -1, 155, 170, -1, 31, 241, -23, -13, -5, -1, + 240, -1, 186, 229, -3, -1, 228, 140, -1, 109, 227, -5, -1, 226, -1, + 46, 14, -1, 30, 225, -15, -7, -3, -1, 224, 93, -1, 213, 124, -3, + -1, 199, 77, -1, 139, 184, -7, -3, -1, 212, 154, -1, 169, 108, -1, + 198, 61, -37, -21, -9, -5, -3, -1, 211, 123, 45, -1, 210, 29, -5, + -1, 183, -1, 92, 197, -3, -1, 153, 122, 195, -7, -5, -3, -1, 167, + 151, 75, 209, -3, -1, 13, 208, -1, 138, 168, -11, -7, -3, -1, 76, + 196, -1, 107, 182, -1, 60, 44, -3, -1, 194, 91, -3, -1, 181, 137, + 28, -43, -23, -11, -5, -1, 193, -1, 152, 12, -1, 192, -1, 180, 106, + -5, -3, -1, 166, 121, 59, -1, 179, -1, 136, 90, -11, -5, -1, 43, + -1, 165, 105, -1, 164, -1, 120, 135, -5, -1, 148, -1, 119, 118, 178, + -11, -3, -1, 27, 177, -3, -1, 11, 176, -1, 150, 74, -7, -3, -1, + 58, 163, -1, 89, 149, -1, 42, 162, -47, -23, -9, -3, -1, 26, 161, + -3, -1, 10, 104, 160, -5, -3, -1, 134, 73, 147, -3, -1, 57, 88, + -1, 133, 103, -9, -3, -1, 41, 146, -3, -1, 87, 117, 56, -5, -1, + 131, -1, 102, 71, -3, -1, 116, 86, -1, 101, 115, -11, -3, -1, 25, + 145, -3, -1, 9, 144, -1, 72, 132, -7, -5, -1, 114, -1, 70, 100, + 40, -1, 130, 24, -41, -27, -11, -5, -3, -1, 55, 39, 23, -1, 113, + -1, 85, 7, -7, -3, -1, 112, 54, -1, 99, 69, -3, -1, 84, 38, + -1, 98, 53, -5, -1, 129, -1, 8, 128, -3, -1, 22, 97, -1, 6, + 96, -13, -9, -5, -3, -1, 83, 68, 37, -1, 82, 5, -1, 21, 81, + -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, -19, -11, + -5, -1, 65, -1, 4, 64, -3, -1, 35, 50, 19, -3, -1, 49, 3, + -1, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, + 0 +}; + +static short iemmp3_tab15[] = +{ + -495,-445,-355,-263,-183,-115, -77, -43, -27, -13, -7, -3, -1, 255, 239, + -1, 254, 223, -1, 238, -1, 253, 207, -7, -3, -1, 252, 222, -1, 237, + 191, -1, 251, -1, 206, 236, -7, -3, -1, 221, 175, -1, 250, 190, -3, + -1, 235, 205, -1, 220, 159, -15, -7, -3, -1, 249, 234, -1, 189, 219, + -3, -1, 143, 248, -1, 204, 158, -7, -3, -1, 233, 127, -1, 247, 173, + -3, -1, 218, 188, -1, 111, -1, 174, 15, -19, -11, -3, -1, 203, 246, + -3, -1, 142, 232, -1, 95, 157, -3, -1, 245, 126, -1, 231, 172, -9, + -3, -1, 202, 187, -3, -1, 217, 141, 79, -3, -1, 244, 63, -1, 243, + 216, -33, -17, -9, -3, -1, 230, 47, -1, 242, -1, 110, 240, -3, -1, + 31, 241, -1, 156, 201, -7, -3, -1, 94, 171, -1, 186, 229, -3, -1, + 125, 215, -1, 78, 228, -15, -7, -3, -1, 140, 200, -1, 62, 109, -3, + -1, 214, 227, -1, 155, 185, -7, -3, -1, 46, 170, -1, 226, 30, -5, + -1, 225, -1, 14, 224, -1, 93, 213, -45, -25, -13, -7, -3, -1, 124, + 199, -1, 77, 139, -1, 212, -1, 184, 154, -7, -3, -1, 169, 108, -1, + 198, 61, -1, 211, 210, -9, -5, -3, -1, 45, 13, 29, -1, 123, 183, + -5, -1, 209, -1, 92, 208, -1, 197, 138, -17, -7, -3, -1, 168, 76, + -1, 196, 107, -5, -1, 182, -1, 153, 12, -1, 60, 195, -9, -3, -1, + 122, 167, -1, 166, -1, 192, 11, -1, 194, -1, 44, 91, -55, -29, -15, + -7, -3, -1, 181, 28, -1, 137, 152, -3, -1, 193, 75, -1, 180, 106, + -5, -3, -1, 59, 121, 179, -3, -1, 151, 136, -1, 43, 90, -11, -5, + -1, 178, -1, 165, 27, -1, 177, -1, 176, 105, -7, -3, -1, 150, 74, + -1, 164, 120, -3, -1, 135, 58, 163, -17, -7, -3, -1, 89, 149, -1, + 42, 162, -3, -1, 26, 161, -3, -1, 10, 160, 104, -7, -3, -1, 134, + 73, -1, 148, 57, -5, -1, 147, -1, 119, 9, -1, 88, 133, -53, -29, + -13, -7, -3, -1, 41, 103, -1, 118, 146, -1, 145, -1, 25, 144, -7, + -3, -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 71, -7, + -3, -1, 40, 130, -1, 24, 129, -7, -3, -1, 116, 8, -1, 128, 86, + -3, -1, 101, 55, -1, 115, 70, -17, -7, -3, -1, 39, 114, -1, 100, + 23, -3, -1, 85, 113, -3, -1, 7, 112, 54, -7, -3, -1, 99, 69, + -1, 84, 38, -3, -1, 98, 22, -3, -1, 6, 96, 53, -33, -19, -9, + -5, -1, 97, -1, 83, 68, -1, 37, 82, -3, -1, 21, 81, -3, -1, + 5, 80, 52, -7, -3, -1, 67, 36, -1, 66, 51, -1, 65, -1, 20, + 4, -9, -3, -1, 35, 50, -3, -1, 64, 3, 19, -3, -1, 49, 48, + 34, -9, -7, -3, -1, 18, 33, -1, 2, 32, 17, -3, -1, 1, 16, + 0 +}; + +static short iemmp3_tab16[] = +{ + -509,-503,-461,-323,-103, -37, -27, -15, -7, -3, -1, 239, 254, -1, 223, + 253, -3, -1, 207, 252, -1, 191, 251, -5, -1, 175, -1, 250, 159, -3, + -1, 249, 248, 143, -7, -3, -1, 127, 247, -1, 111, 246, 255, -9, -5, + -3, -1, 95, 245, 79, -1, 244, 243, -53, -1, 240, -1, 63, -29, -19, + -13, -7, -5, -1, 206, -1, 236, 221, 222, -1, 233, -1, 234, 217, -1, + 238, -1, 237, 235, -3, -1, 190, 205, -3, -1, 220, 219, 174, -11, -5, + -1, 204, -1, 173, 218, -3, -1, 126, 172, 202, -5, -3, -1, 201, 125, + 94, 189, 242, -93, -5, -3, -1, 47, 15, 31, -1, 241, -49, -25, -13, + -5, -1, 158, -1, 188, 203, -3, -1, 142, 232, -1, 157, 231, -7, -3, + -1, 187, 141, -1, 216, 110, -1, 230, 156, -13, -7, -3, -1, 171, 186, + -1, 229, 215, -1, 78, -1, 228, 140, -3, -1, 200, 62, -1, 109, -1, + 214, 155, -19, -11, -5, -3, -1, 185, 170, 225, -1, 212, -1, 184, 169, + -5, -1, 123, -1, 183, 208, 227, -7, -3, -1, 14, 224, -1, 93, 213, + -3, -1, 124, 199, -1, 77, 139, -75, -45, -27, -13, -7, -3, -1, 154, + 108, -1, 198, 61, -3, -1, 92, 197, 13, -7, -3, -1, 138, 168, -1, + 153, 76, -3, -1, 182, 122, 60, -11, -5, -3, -1, 91, 137, 28, -1, + 192, -1, 152, 121, -1, 226, -1, 46, 30, -15, -7, -3, -1, 211, 45, + -1, 210, 209, -5, -1, 59, -1, 151, 136, 29, -7, -3, -1, 196, 107, + -1, 195, 167, -1, 44, -1, 194, 181, -23, -13, -7, -3, -1, 193, 12, + -1, 75, 180, -3, -1, 106, 166, 179, -5, -3, -1, 90, 165, 43, -1, + 178, 27, -13, -5, -1, 177, -1, 11, 176, -3, -1, 105, 150, -1, 74, + 164, -5, -3, -1, 120, 135, 163, -3, -1, 58, 89, 42, -97, -57, -33, + -19, -11, -5, -3, -1, 149, 104, 161, -3, -1, 134, 119, 148, -5, -3, + -1, 73, 87, 103, 162, -5, -1, 26, -1, 10, 160, -3, -1, 57, 147, + -1, 88, 133, -9, -3, -1, 41, 146, -3, -1, 118, 9, 25, -5, -1, + 145, -1, 144, 72, -3, -1, 132, 117, -1, 56, 131, -21, -11, -5, -3, + -1, 102, 40, 130, -3, -1, 71, 116, 24, -3, -1, 129, 128, -3, -1, + 8, 86, 55, -9, -5, -1, 115, -1, 101, 70, -1, 39, 114, -5, -3, + -1, 100, 85, 7, 23, -23, -13, -5, -1, 113, -1, 112, 54, -3, -1, + 99, 69, -1, 84, 38, -3, -1, 98, 22, -1, 97, -1, 6, 96, -9, + -5, -1, 83, -1, 53, 68, -1, 37, 82, -1, 81, -1, 21, 5, -33, + -23, -13, -7, -3, -1, 52, 67, -1, 80, 36, -3, -1, 66, 51, 20, + -5, -1, 65, -1, 4, 64, -1, 35, 50, -3, -1, 19, 49, -3, -1, + 3, 48, 34, -3, -1, 18, 33, -1, 2, 32, -3, -1, 17, 1, 16, + 0 +}; + +static short iemmp3_tab24[] = +{ + -451,-117, -43, -25, -15, -7, -3, -1, 239, 254, -1, 223, 253, -3, -1, + 207, 252, -1, 191, 251, -5, -1, 250, -1, 175, 159, -1, 249, 248, -9, + -5, -3, -1, 143, 127, 247, -1, 111, 246, -3, -1, 95, 245, -1, 79, + 244, -71, -7, -3, -1, 63, 243, -1, 47, 242, -5, -1, 241, -1, 31, + 240, -25, -9, -1, 15, -3, -1, 238, 222, -1, 237, 206, -7, -3, -1, + 236, 221, -1, 190, 235, -3, -1, 205, 220, -1, 174, 234, -15, -7, -3, + -1, 189, 219, -1, 204, 158, -3, -1, 233, 173, -1, 218, 188, -7, -3, + -1, 203, 142, -1, 232, 157, -3, -1, 217, 126, -1, 231, 172, 255,-235, + -143, -77, -45, -25, -15, -7, -3, -1, 202, 187, -1, 141, 216, -5, -3, + -1, 14, 224, 13, 230, -5, -3, -1, 110, 156, 201, -1, 94, 186, -9, + -5, -1, 229, -1, 171, 125, -1, 215, 228, -3, -1, 140, 200, -3, -1, + 78, 46, 62, -15, -7, -3, -1, 109, 214, -1, 227, 155, -3, -1, 185, + 170, -1, 226, 30, -7, -3, -1, 225, 93, -1, 213, 124, -3, -1, 199, + 77, -1, 139, 184, -31, -15, -7, -3, -1, 212, 154, -1, 169, 108, -3, + -1, 198, 61, -1, 211, 45, -7, -3, -1, 210, 29, -1, 123, 183, -3, + -1, 209, 92, -1, 197, 138, -17, -7, -3, -1, 168, 153, -1, 76, 196, + -3, -1, 107, 182, -3, -1, 208, 12, 60, -7, -3, -1, 195, 122, -1, + 167, 44, -3, -1, 194, 91, -1, 181, 28, -57, -35, -19, -7, -3, -1, + 137, 152, -1, 193, 75, -5, -3, -1, 192, 11, 59, -3, -1, 176, 10, + 26, -5, -1, 180, -1, 106, 166, -3, -1, 121, 151, -3, -1, 160, 9, + 144, -9, -3, -1, 179, 136, -3, -1, 43, 90, 178, -7, -3, -1, 165, + 27, -1, 177, 105, -1, 150, 164, -17, -9, -5, -3, -1, 74, 120, 135, + -1, 58, 163, -3, -1, 89, 149, -1, 42, 162, -7, -3, -1, 161, 104, + -1, 134, 119, -3, -1, 73, 148, -1, 57, 147, -63, -31, -15, -7, -3, + -1, 88, 133, -1, 41, 103, -3, -1, 118, 146, -1, 25, 145, -7, -3, + -1, 72, 132, -1, 87, 117, -3, -1, 56, 131, -1, 102, 40, -17, -7, + -3, -1, 130, 24, -1, 71, 116, -5, -1, 129, -1, 8, 128, -1, 86, + 101, -7, -5, -1, 23, -1, 7, 112, 115, -3, -1, 55, 39, 114, -15, + -7, -3, -1, 70, 100, -1, 85, 113, -3, -1, 54, 99, -1, 69, 84, + -7, -3, -1, 38, 98, -1, 22, 97, -5, -3, -1, 6, 96, 53, -1, + 83, 68, -51, -37, -23, -15, -9, -3, -1, 37, 82, -1, 21, -1, 5, + 80, -1, 81, -1, 52, 67, -3, -1, 36, 66, -1, 51, 20, -9, -5, + -1, 65, -1, 4, 64, -1, 35, 50, -1, 19, 49, -7, -5, -3, -1, + 3, 48, 34, 18, -1, 33, -1, 2, 32, -3, -1, 17, 1, -1, 16, + 0 +}; + +static short iemmp3_tab_c0[] = +{ + -29, -21, -13, -7, -3, -1, 11, 15, -1, 13, 14, -3, -1, 7, 5, + 9, -3, -1, 6, 3, -1, 10, 12, -3, -1, 2, 1, -1, 4, 8, + 0 +}; + +static short iemmp3_tab_c1[] = +{ + -15, -7, -3, -1, 15, 14, -1, 13, 12, -3, -1, 11, 10, -1, 9, + 8, -7, -3, -1, 7, 6, -1, 5, 4, -3, -1, 3, 2, -1, 1, + 0 +}; + + + +static struct iemmp3_newHuff iemmp3_ht[] = +{ + { /* 0 */ 0 , iemmp3_tab0 } , + { /* 2 */ 0 , iemmp3_tab1 } , + { /* 3 */ 0 , iemmp3_tab2 } , + { /* 3 */ 0 , iemmp3_tab3 } , + { /* 0 */ 0 , iemmp3_tab0 } , + { /* 4 */ 0 , iemmp3_tab5 } , + { /* 4 */ 0 , iemmp3_tab6 } , + { /* 6 */ 0 , iemmp3_tab7 } , + { /* 6 */ 0 , iemmp3_tab8 } , + { /* 6 */ 0 , iemmp3_tab9 } , + { /* 8 */ 0 , iemmp3_tab10 } , + { /* 8 */ 0 , iemmp3_tab11 } , + { /* 8 */ 0 , iemmp3_tab12 } , + { /* 16 */ 0 , iemmp3_tab13 } , + { /* 0 */ 0 , iemmp3_tab0 } , + { /* 16 */ 0 , iemmp3_tab15 } , + + { /* 16 */ 1 , iemmp3_tab16 } , + { /* 16 */ 2 , iemmp3_tab16 } , + { /* 16 */ 3 , iemmp3_tab16 } , + { /* 16 */ 4 , iemmp3_tab16 } , + { /* 16 */ 6 , iemmp3_tab16 } , + { /* 16 */ 8 , iemmp3_tab16 } , + { /* 16 */ 10, iemmp3_tab16 } , + { /* 16 */ 13, iemmp3_tab16 } , + { /* 16 */ 4 , iemmp3_tab24 } , + { /* 16 */ 5 , iemmp3_tab24 } , + { /* 16 */ 6 , iemmp3_tab24 } , + { /* 16 */ 7 , iemmp3_tab24 } , + { /* 16 */ 8 , iemmp3_tab24 } , + { /* 16 */ 9 , iemmp3_tab24 } , + { /* 16 */ 11, iemmp3_tab24 } , + { /* 16 */ 13, iemmp3_tab24 } +}; + +static struct iemmp3_newHuff iemmp3_htc[] = +{ + { /* 1 , 1 , */ 0 , iemmp3_tab_c0 } , + { /* 1 , 1 , */ 0 , iemmp3_tab_c1 } +}; + + +static t_class *sigmp3play_class; + + + +static BOOL InitMP3(struct iemmp3Struct *mp) +{ + memset(mp,0,sizeof(struct iemmp3Struct)); + + mp->framesize = 0; + mp->fsizeold = -1; + mp->bsize = 0; + mp->head = mp->tail = NULL; + mp->fr.single = -1; + mp->bsnum = 0; + mp->synth_bo = 1; + + make_decode_tables(32767); + init_layer3(SBLIMIT); + + return !0; +} + +static BOOL InitAgainMP3(struct iemmp3Struct *mp) +{ + memset(mp,0,sizeof(struct iemmp3Struct)); + + mp->framesize = 0; + mp->fsizeold = -1; + mp->bsize = 0; + mp->head = mp->tail = NULL; + mp->fr.single = -1; + mp->bsnum = 0; + mp->synth_bo = 1; + + return !0; +} + +static void ExitMP3(struct iemmp3Struct *mp) +{ + struct iemmp3_buf *b,*bn; + + b = mp->tail; + while(b) + { + free(b->pnt); + bn = b->next; + free(b); + b = bn; + } +} + +static int decodeMP3(struct iemmp3Struct *mp, char *in, int isize, char *out, int osize, int *done) +{ + int len,error=1; + + iemmp3_gmp = mp; + + if(osize < 4608) + { + post("To less out space\n"); + return MP3_ERR; + } + + if(in) + { + if(addbuf(mp,in,isize) == NULL) + { + return MP3_ERR; + } + } + + /* First decode header */ + if(mp->framesize == 0) + { + if(mp->bsize < 4) + { + return MP3_NEED_MORE; + } + if(!read_head(mp)) + return MP3_EX; + if(decode_header(&mp->fr,mp->header) == MP3_EX) + return MP3_EX; + mp->framesize = mp->fr.framesize; + } + + if(mp->fr.framesize > mp->bsize) + return MP3_NEED_MORE; + + iemmp3_wordpointer = mp->bsspace[mp->bsnum] + 512; + mp->bsnum = (mp->bsnum + 1) & 0x1; + iemmp3_bitindex = 0; + + len = 0; + while(len < mp->framesize) + { + int nlen; + int blen = mp->tail->size - mp->tail->pos; + if( (mp->framesize - len) <= blen) + { + nlen = mp->framesize-len; + } + else + { + nlen = blen; + } + memcpy(iemmp3_wordpointer+len,mp->tail->pnt+mp->tail->pos,nlen); + len += nlen; + mp->tail->pos += nlen; + mp->bsize -= nlen; + if(mp->tail->pos == mp->tail->size) + { + remove_buf(mp); + } + } + + *done = 0; + if(mp->fr.error_protection) + getbits(16); + do_layer3(&mp->fr,(unsigned char *) out,done,&error); + if(!error) + return MP3_EX; + + mp->fsizeold = mp->framesize; + mp->framesize = 0; + + return MP3_OK; +} + +static void make_decode_tables(long scaleval) +{ + int i,j,k,kr,divv; + real *table,*costab; + + for(i=0;i<5;i++) + { + kr=0x10>>i; divv=0x40>>i; + costab = iemmp3_pnts[i]; + for(k=0;k 0) + { + if( i & 1 ) + p1 = pow(base,(i+1.0)*0.5); + else + p2 = pow(base,i*0.5); + } + iemmp3_pow1_1[j][i] = p1; + iemmp3_pow2_1[j][i] = p2; + iemmp3_pow1_2[j][i] = M_SQRT2 * p1; + iemmp3_pow2_2[j][i] = M_SQRT2 * p2; + } + } + + for(j=0;j<9;j++) + { + struct iemmp3_bandInfoStruct *bi = &bandInfo[j]; + int *mp; + int cb,lwin; + short *bdf; + + mp = iemmp3_map[j][0] = iemmp3_mapbuf0[j]; + bdf = bi->longDiff; + for(i=0,cb = 0; cb < 8 ; cb++,i+=*bdf++) + { + *mp++ = (*bdf) >> 1; + *mp++ = i; + *mp++ = 3; + *mp++ = cb; + } + bdf = bi->shortDiff+3; + for(cb=3;cb<13;cb++) + { + int l = (*bdf++) >> 1; + for(lwin=0;lwin<3;lwin++) + { + *mp++ = l; + *mp++ = i + lwin; + *mp++ = lwin; + *mp++ = cb; + } + i += 6*l; + } + iemmp3_mapend[j][0] = mp; + + mp = iemmp3_map[j][1] = iemmp3_mapbuf1[j]; + bdf = bi->shortDiff+0; + for(i=0,cb=0;cb<13;cb++) + { + int l = (*bdf++) >> 1; + for(lwin=0;lwin<3;lwin++) + { + *mp++ = l; + *mp++ = i + lwin; + *mp++ = lwin; + *mp++ = cb; + } + i += 6*l; + } + iemmp3_mapend[j][1] = mp; + + mp = iemmp3_map[j][2] = iemmp3_mapbuf2[j]; + bdf = bi->longDiff; + for(cb = 0; cb < 22 ; cb++) + { + *mp++ = (*bdf++) >> 1; + *mp++ = cb; + } + iemmp3_mapend[j][2] = mp; + } + + for(j=0;j<9;j++) + { + for(i=0;i<23;i++) + { + iemmp3_longLimit[j][i] = (bandInfo[j].longIdx[i] - 1 + 8) / 18 + 1; + if(iemmp3_longLimit[j][i] > (down_sample_sblimit) ) + iemmp3_longLimit[j][i] = down_sample_sblimit; + } + for(i=0;i<14;i++) + { + iemmp3_shortLimit[j][i] = (bandInfo[j].shortIdx[i] - 1) / 18 + 1; + if(iemmp3_shortLimit[j][i] > (down_sample_sblimit) ) + iemmp3_shortLimit[j][i] = down_sample_sblimit; + } + } + + for(i=0;i<5;i++) + { + for(j=0;j<6;j++) + { + for(k=0;k<6;k++) + { + int n = k + j * 6 + i * 36; + iemmp3_slen2[n] = i|(j<<3)|(k<<6)|(3<<12); + } + } + } + for(i=0;i<4;i++) + { + for(j=0;j<4;j++) + { + for(k=0;k<4;k++) + { + int n = k + j * 4 + i * 16; + iemmp3_slen2[n+180] = i|(j<<3)|(k<<6)|(4<<12); + } + } + } + for(i=0;i<4;i++) + { + for(j=0;j<3;j++) + { + int n = j + i * 3; + iemmp3_slen2[n+244] = i|(j<<3) | (5<<12); + iemmp3_n_slen2[n+500] = i|(j<<3) | (2<<12) | (1<<15); + } + } + + for(i=0;i<5;i++) + { + for(j=0;j<5;j++) + { + for(k=0;k<4;k++) + { + for(l=0;l<4;l++) + { + int n = l + k * 4 + j * 16 + i * 80; + iemmp3_n_slen2[n] = i|(j<<3)|(k<<6)|(l<<9)|(0<<12); + } + } + } + } + for(i=0;i<5;i++) + { + for(j=0;j<5;j++) + { + for(k=0;k<4;k++) + { + int n = k + j * 4 + i * 20; + iemmp3_n_slen2[n+400] = i|(j<<3)|(k<<6)|(1<<12); + } + } + } +} + +static void remove_buf(struct iemmp3Struct *mp) +{ + struct iemmp3_buf *buf = mp->tail; + + mp->tail = buf->next; + if(mp->tail) + mp->tail->prev = NULL; + else + { + mp->tail = mp->head = NULL; + } + free(buf->pnt); + free(buf); +} + +static struct iemmp3_buf *addbuf(struct iemmp3Struct *mp,char *buf,int size) +{ + struct iemmp3_buf *nbuf; + + nbuf = malloc( sizeof(struct iemmp3_buf) ); + if(!nbuf) + { + post("Out of memory!\n"); + return NULL; + } + nbuf->pnt = malloc(size); + if(!nbuf->pnt) + { + free(nbuf); + return NULL; + } + nbuf->size = size; + memcpy(nbuf->pnt,buf,size); + nbuf->next = NULL; + nbuf->prev = mp->head; + nbuf->pos = 0; + if(!mp->tail) + { + mp->tail = nbuf; + } + else + { + mp->head->next = nbuf; + } + mp->head = nbuf; + mp->bsize += size; + return nbuf; +} + +static int read_buf_byte(struct iemmp3Struct *mp,int *err) +{ + unsigned int b; + int pos; + + pos = mp->tail->pos; + while(pos >= mp->tail->size) + { + remove_buf(mp); + pos = mp->tail->pos; + if(!mp->tail) + { + post("Fatal error!\n"); + *err = 0; + return(0); + } + } + b = mp->tail->pnt[pos]; + mp->bsize--; + mp->tail->pos++; + return(b); +} + +static int read_head(struct iemmp3Struct *mp) +{ + unsigned long head; + int error=1; + + head = read_buf_byte(mp,&error); + head <<= 8; + head |= read_buf_byte(mp,&error); + head <<= 8; + head |= read_buf_byte(mp,&error); + head <<= 8; + head |= read_buf_byte(mp,&error); + mp->header = head; + return(error); +} + +static int decode_header(struct iemmp3_frame *fr,unsigned long newhead) +{ + if( newhead & (1<<20) ) + { + fr->lsf = (newhead & (1<<19)) ? 0x0 : 0x1; + fr->mpeg25 = 0; + } + else + { + fr->lsf = 1; + fr->mpeg25 = 1; + } + fr->lay = 4-((newhead>>17)&3); + if( ((newhead>>10)&0x3) == 0x3) + { + post("Stream error"); + return(MP3_EX); + } + if(fr->mpeg25) + { + fr->sampling_frequency = 6 + ((newhead>>10)&0x3); + } + else + fr->sampling_frequency = ((newhead>>10)&0x3) + (fr->lsf*3); + fr->error_protection = ((newhead>>16)&0x1)^0x1; + if(fr->mpeg25) /* allow Bitrate change for 2.5 ... */ + fr->bitrate_index = ((newhead>>12)&0xf); + fr->bitrate_index = ((newhead>>12)&0xf); + fr->padding = ((newhead>>9)&0x1); + fr->extension = ((newhead>>8)&0x1); + fr->mode = ((newhead>>6)&0x3); + fr->mode_ext = ((newhead>>4)&0x3); + fr->copyright = ((newhead>>3)&0x1); + fr->original = ((newhead>>2)&0x1); + fr->emphasis = newhead & 0x3; + fr->stereo = (fr->mode == MPG_MD_MONO) ? 1 : 2; + if(!fr->bitrate_index) + { + post("Free format not supported.\n"); + return(0); + } + switch(fr->lay) + { + case 1: + post("Layer I not supported!\n"); + break; + case 2: + post("Layer II not supported!\n"); + break; + case 3: + fr->framesize = (long) iemmp3_tabsel_123[fr->lsf][2][fr->bitrate_index] * 144000; + fr->framesize /= iemmp3_freqs[fr->sampling_frequency]<<(fr->lsf); + fr->framesize = fr->framesize + fr->padding - 4; + //post("Framesize: %d",fr->framesize); + break; + default: + post("Sorry, unknown layer type.\n"); + return (0); + } + return(1); +} + +static unsigned int getbits(int number_of_bits) +{ + unsigned long rval; + + if(!number_of_bits) + return 0; + { + rval = iemmp3_wordpointer[0]; + rval <<= 8; + rval |= iemmp3_wordpointer[1]; + rval <<= 8; + rval |= iemmp3_wordpointer[2]; + rval <<= iemmp3_bitindex; + rval &= 0xffffff; + iemmp3_bitindex += number_of_bits; + rval >>= (24-number_of_bits); + iemmp3_wordpointer += (iemmp3_bitindex>>3); + iemmp3_bitindex &= 7; + } + return rval; +} + +static unsigned int getbits_fast(int number_of_bits) +{ + unsigned long rval; + + { + rval = iemmp3_wordpointer[0]; + rval <<= 8; + rval |= iemmp3_wordpointer[1]; + rval <<= iemmp3_bitindex; + rval &= 0xffff; + iemmp3_bitindex += number_of_bits; + rval >>= (16-number_of_bits); + iemmp3_wordpointer += (iemmp3_bitindex>>3); + iemmp3_bitindex &= 7; + } + return rval; +} + +static unsigned int get1bit(void) +{ + unsigned char rval; + rval = *iemmp3_wordpointer << iemmp3_bitindex; + + iemmp3_bitindex++; + iemmp3_wordpointer += (iemmp3_bitindex>>3); + iemmp3_bitindex &= 7; + + return rval>>7; +} + +static int do_layer3(struct iemmp3_frame *fr,unsigned char *pcm_sample,int *pcm_point,int *err) +{ + int gr, ch, ss,clip=0; + int scalefacs[39]; /* max 39 for short[13][3] mode, mixed: 38, long: 22 */ + struct iemmp3_III_sideinfo sideinfo; + int stereo = fr->stereo; + int single = fr->single; + int ms_stereo,i_stereo; + int sfreq = fr->sampling_frequency; + int stereo1,granules; + + if(stereo == 1) + { /* stream is mono */ + stereo1 = 1; + single = 0; + } + else if(single >= 0) /* stream is stereo, but force to mono */ + stereo1 = 1; + else + stereo1 = 2; + + if(fr->mode == MPG_MD_JOINT_STEREO) + { + ms_stereo = fr->mode_ext & 0x2; + i_stereo = fr->mode_ext & 0x1; + } + else + ms_stereo = i_stereo = 0; + + if(fr->lsf) + { + granules = 1; + if(!III_get_side_info_2(&sideinfo,stereo,ms_stereo,sfreq,single)) + { + *err = 0; + return 0; + } + } + else + { + granules = 2; +#ifdef IEM_MPEG1 + if(!III_get_side_info_1(&sideinfo,stereo,ms_stereo,sfreq,single)) + { + *err = 0; + return 0; + } +#else + post("Not supported\n"); +#endif + } + + if(set_pointer(sideinfo.main_data_begin) == MP3_ERR) + return 0; + + for (gr=0;grlsf) + part2bits = III_get_scale_factors_2(scalefacs,gr_info,0); + else + { +#ifdef IEM_MPEG1 + part2bits = III_get_scale_factors_1(scalefacs,gr_info); +#else + post("Not supported\n"); +#endif + } + if(III_dequantize_sample(hybridIn[0], scalefacs,gr_info,sfreq,part2bits)) + return clip; + } + if(stereo == 2) + { + struct iemmp3_gr_info_s *gr_info = &(sideinfo.ch[1].gr[gr]); + long part2bits; + if(fr->lsf) + part2bits = III_get_scale_factors_2(scalefacs,gr_info,i_stereo); + else + { +#ifdef IEM_MPEG1 + part2bits = III_get_scale_factors_1(scalefacs,gr_info); +#else + post("Not supported\n"); +#endif + } + + if(III_dequantize_sample(hybridIn[1],scalefacs,gr_info,sfreq,part2bits)) + return clip; + + if(ms_stereo) + { + int i; + for(i=0;ilsf); + + if(ms_stereo || i_stereo || (single == 3) ) + { + if(gr_info->maxb > sideinfo.ch[0].gr[gr].maxb) + sideinfo.ch[0].gr[gr].maxb = gr_info->maxb; + else + gr_info->maxb = sideinfo.ch[0].gr[gr].maxb; + } + + switch(single) + { + case 3: + { + register unsigned int i; + register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1]; + for(i=0;imaxb;i++,in0++) + *in0 = (*in0 + *in1++); /* *0.5 done by pow-scale */ + } + break; + case 1: + { + register unsigned int i; + register real *in0 = (real *) hybridIn[0],*in1 = (real *) hybridIn[1]; + for(i=0;imaxb;i++) + *in0++ = *in1++; + } + break; + } + } + + for(ch=0;ch= 0) + { + clip += synth_1to1_mono(hybridOut[0][ss],pcm_sample,pcm_point); + } + else + { + int p1 = *pcm_point; + clip += synth_1to1(hybridOut[0][ss],0,pcm_sample,&p1); + clip += synth_1to1(hybridOut[1][ss],1,pcm_sample,pcm_point); + } + } + } + + return clip; +} + +static int III_get_side_info_2(struct iemmp3_III_sideinfo *si,int stereo, + int ms_stereo,long sfreq,int single) +{ + int ch; + int powdiff = (single == 3) ? 4 : 0; + + si->main_data_begin = getbits(8); + if (stereo == 1) + si->private_bits = get1bit(); + else + si->private_bits = getbits_fast(2); + + for (ch=0; chch[ch].gr[0]); + + gr_info->part2_3_length = getbits(12); + gr_info->big_values = getbits_fast(9); + if(gr_info->big_values > 288) + { + post("big_values too large!\n"); + gr_info->big_values = 288; + } + gr_info->pow2gain = iemmp3_gainpow2+256 - getbits_fast(8) + powdiff; + if(ms_stereo) + gr_info->pow2gain += 2; + gr_info->scalefac_compress = getbits(9); + /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */ + if(get1bit()) + { + int i; + gr_info->block_type = getbits_fast(2); + gr_info->mixed_block_flag = get1bit(); + gr_info->table_select[0] = getbits_fast(5); + gr_info->table_select[1] = getbits_fast(5); + /* + * table_select[2] not needed, because there is no region2, + * but to satisfy some verifications tools we set it either. + */ + gr_info->table_select[2] = 0; + for(i=0;i<3;i++) + gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3); + if(gr_info->block_type == 0) + { + post("Blocktype == 0 and window-switching == 1 not allowed.\n"); + return(0); + } + /* region_count/start parameters are implicit in this case. */ + /* check this again! */ + if(gr_info->block_type == 2) + gr_info->region1start = 36>>1; + else if(sfreq == 8) + /* check this for 2.5 and sfreq=8 */ + gr_info->region1start = 108>>1; + else + gr_info->region1start = 54>>1; + gr_info->region2start = 576>>1; + } + else + { + int i,r0c,r1c; + for (i=0; i<3; i++) + gr_info->table_select[i] = getbits_fast(5); + r0c = getbits_fast(4); + r1c = getbits_fast(3); + gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ; + gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1; + gr_info->block_type = 0; + gr_info->mixed_block_flag = 0; + } + gr_info->scalefac_scale = get1bit(); + gr_info->count1table_select = get1bit(); + } + return(1); +} + + +#ifdef IEM_MPEG1 +static int III_get_side_info_1(struct iemmp3_III_sideinfo *si,int stereo, + int ms_stereo,long sfreq,int single) +{ + int ch, gr; + int powdiff = (single == 3) ? 4 : 0; + + si->main_data_begin = getbits(9); + if (stereo == 1) + si->private_bits = getbits_fast(5); + else + si->private_bits = getbits_fast(3); + + for (ch=0; chch[ch].gr[0].scfsi = -1; + si->ch[ch].gr[1].scfsi = getbits_fast(4); + } + + for (gr=0; gr<2; gr++) + { + for (ch=0; chch[ch].gr[gr]); + + gr_info->part2_3_length = getbits(12); + gr_info->big_values = getbits_fast(9); + if(gr_info->big_values > 288) + { + post("big_values too large!\n"); + gr_info->big_values = 288; + } + gr_info->pow2gain = iemmp3_gainpow2+256 - getbits_fast(8) + powdiff; + if(ms_stereo) + gr_info->pow2gain += 2; + gr_info->scalefac_compress = getbits_fast(4); + /* window-switching flag == 1 for block_Type != 0 .. and block-type == 0 -> win-sw-flag = 0 */ + if(get1bit()) + { + int i; + + gr_info->block_type = getbits_fast(2); + gr_info->mixed_block_flag = get1bit(); + gr_info->table_select[0] = getbits_fast(5); + gr_info->table_select[1] = getbits_fast(5); + /* + * table_select[2] not needed, because there is no region2, + * but to satisfy some verifications tools we set it either. + */ + gr_info->table_select[2] = 0; + for(i=0;i<3;i++) + gr_info->full_gain[i] = gr_info->pow2gain + (getbits_fast(3)<<3); + + if(gr_info->block_type == 0) + { + post("Blocktype == 0 and window-switching == 1 not allowed.\n"); + return(0); + } + /* region_count/start parameters are implicit in this case. */ + gr_info->region1start = 36>>1; + gr_info->region2start = 576>>1; + } + else + { + int i,r0c,r1c; + for (i=0; i<3; i++) + gr_info->table_select[i] = getbits_fast(5); + r0c = getbits_fast(4); + r1c = getbits_fast(3); + gr_info->region1start = bandInfo[sfreq].longIdx[r0c+1] >> 1 ; + gr_info->region2start = bandInfo[sfreq].longIdx[r0c+1+r1c+1] >> 1; + gr_info->block_type = 0; + gr_info->mixed_block_flag = 0; + } + gr_info->preflag = get1bit(); + gr_info->scalefac_scale = get1bit(); + gr_info->count1table_select = get1bit(); + } + } + return(1); +} +#endif + +static int set_pointer(long backstep) +{ + unsigned char *bsbufold; + if(iemmp3_gmp->fsizeold < 0 && backstep > 0) + { + post("Can't step back %ld!\n",backstep); + return MP3_ERR; + } + bsbufold = iemmp3_gmp->bsspace[iemmp3_gmp->bsnum] + 512; + iemmp3_wordpointer -= backstep; + if (backstep) + memcpy(iemmp3_wordpointer,bsbufold+iemmp3_gmp->fsizeold-backstep,backstep); + iemmp3_bitindex = 0; + return MP3_OK; +} + +#ifdef IEM_MPEG1 +static int III_get_scale_factors_1(int *scf,struct iemmp3_gr_info_s *gr_info) +{ + static unsigned char slen[2][16] = { + {0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4}, + {0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3} + }; + int numbits; + int num0 = slen[0][gr_info->scalefac_compress]; + int num1 = slen[1][gr_info->scalefac_compress]; + + if (gr_info->block_type == 2) + { + int i=18; + + numbits = (num0 + num1) * 18; + if (gr_info->mixed_block_flag) + { + for (i=8;i;i--) + *scf++ = getbits_fast(num0); + i = 9; + numbits -= num0; /* num0 * 17 + num1 * 18 */ + } + + for (;i;i--) + *scf++ = getbits_fast(num0); + for (i = 18; i; i--) + *scf++ = getbits_fast(num1); + *scf++ = 0; *scf++ = 0; *scf++ = 0; /* short[13][0..2] = 0 */ + } + else + { + int i; + int scfsi = gr_info->scfsi; + + if(scfsi < 0) + { /* scfsi < 0 => granule == 0 */ + for(i=11;i;i--) + *scf++ = getbits_fast(num0); + for(i=10;i;i--) + *scf++ = getbits_fast(num1); + numbits = (num0 + num1) * 10 + num0; + } + else + { + numbits = 0; + if(!(scfsi & 0x8)) + { + for (i=6;i;i--) + *scf++ = getbits_fast(num0); + numbits += num0 * 6; + } + else + { + *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ + *scf++ = 0; *scf++ = 0; *scf++ = 0; + } + + if(!(scfsi & 0x4)) + { + for (i=5;i;i--) + *scf++ = getbits_fast(num0); + numbits += num0 * 5; + } + else + { + *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ + *scf++ = 0; *scf++ = 0; + } + + if(!(scfsi & 0x2)) + { + for(i=5;i;i--) + *scf++ = getbits_fast(num1); + numbits += num1 * 5; + } + else + { + *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ + *scf++ = 0; *scf++ = 0; + } + + if(!(scfsi & 0x1)) + { + for (i=5;i;i--) + *scf++ = getbits_fast(num1); + numbits += num1 * 5; + } + else + { + *scf++ = 0; *scf++ = 0; *scf++ = 0; /* set to ZERO necessary? */ + *scf++ = 0; *scf++ = 0; + } + } + + *scf++ = 0; /* no l[21] in original sources */ + } + return numbits; +} +#endif + +static int III_get_scale_factors_2(int *scf,struct iemmp3_gr_info_s *gr_info,int i_stereo) +{ + unsigned char *pnt; + int i,j; + unsigned int slen; + int n = 0; + int numbits = 0; + + static unsigned char stab[3][6][4] = { + { { 6, 5, 5,5 } , { 6, 5, 7,3 } , { 11,10,0,0} , + { 7, 7, 7,0 } , { 6, 6, 6,3 } , { 8, 8,5,0} } , + { { 9, 9, 9,9 } , { 9, 9,12,6 } , { 18,18,0,0} , + {12,12,12,0 } , {12, 9, 9,6 } , { 15,12,9,0} } , + { { 6, 9, 9,9 } , { 6, 9,12,6 } , { 15,18,0,0} , + { 6,15,12,0 } , { 6,12, 9,6 } , { 6,18,9,0} } }; + + if(i_stereo) /* i_stereo AND second channel -> do_layer3() checks this */ + slen = iemmp3_slen2[gr_info->scalefac_compress>>1]; + else + slen = iemmp3_n_slen2[gr_info->scalefac_compress]; + + gr_info->preflag = (slen>>15) & 0x1; + + n = 0; + if( gr_info->block_type == 2 ) + { + n++; + if(gr_info->mixed_block_flag) + n++; + } + + pnt = stab[n][(slen>>12)&0x7]; + + for(i=0;i<4;i++) + { + int num = slen & 0x7; + slen >>= 3; + if(num) + { + for(j=0;j<(int)(pnt[i]);j++) + *scf++ = getbits_fast(num); + numbits += pnt[i] * num; + } + else + { + for(j=0;j<(int)(pnt[i]);j++) + *scf++ = 0; + } + } + + n = (n << 1) + 1; + for(i=0;iscalefac_scale; + real *xrpnt = (real *) xr; + int l[3],l3; + int part2remain = gr_info->part2_3_length - part2bits; + int *me; + + { + int bv = gr_info->big_values; + int region1 = gr_info->region1start; + int region2 = gr_info->region2start; + + l3 = ((576>>1)-bv)>>1; + /* + * we may lose the 'odd' bit here !! + * check this later again + */ + if(bv <= region1) + { + l[0] = bv; l[1] = 0; l[2] = 0; + } + else + { + l[0] = region1; + if(bv <= region2) + { + l[1] = bv - l[0]; l[2] = 0; + } + else + { + l[1] = region2 - l[0]; l[2] = bv - region2; + } + } + } + + if(gr_info->block_type == 2) + { + /* + * decoding with short or mixed mode BandIndex table + */ + int i,max[4]; + int step=0,lwin=0,cb=0; + register real v = 0.0; + register int *m,mc; + + if(gr_info->mixed_block_flag) + { + max[3] = -1; + max[0] = max[1] = max[2] = 2; + m = iemmp3_map[sfreq][0]; + me = iemmp3_mapend[sfreq][0]; + } + else + { + max[0] = max[1] = max[2] = max[3] = -1; + /* max[3] not really needed in this case */ + m = iemmp3_map[sfreq][1]; + me = iemmp3_mapend[sfreq][1]; + } + + mc = 0; + for(i=0;i<2;i++) + { + int lp = l[i]; + struct iemmp3_newHuff *h = iemmp3_ht+gr_info->table_select[i]; + for(;lp;lp--,mc--) + { + register int x,y; + if( (!mc) ) + { + mc = *m++; + xrpnt = ((real *) xr) + (*m++); + lwin = *m++; + cb = *m++; + if(lwin == 3) + { + v = gr_info->pow2gain[(*scf++) << shift]; + step = 1; + } + else + { + v = gr_info->full_gain[lwin][(*scf++) << shift]; + step = 3; + } + } + { + register short *val = h->table; + while((y=*val++)<0) + { + if (get1bit()) + val -= y; + part2remain--; + } + x = y >> 4; + y &= 0xf; + } + if(x == 15) + { + max[lwin] = cb; + part2remain -= h->linbits+1; + x += getbits(h->linbits); + if(get1bit()) + *xrpnt = -iemmp3_ispow[x] * v; + else + *xrpnt = iemmp3_ispow[x] * v; + } + else if(x) + { + max[lwin] = cb; + if(get1bit()) + *xrpnt = -iemmp3_ispow[x] * v; + else + *xrpnt = iemmp3_ispow[x] * v; + part2remain--; + } + else + *xrpnt = 0.0; + xrpnt += step; + if(y == 15) + { + max[lwin] = cb; + part2remain -= h->linbits+1; + y += getbits(h->linbits); + if(get1bit()) + *xrpnt = -iemmp3_ispow[y] * v; + else + *xrpnt = iemmp3_ispow[y] * v; + } + else if(y) + { + max[lwin] = cb; + if(get1bit()) + *xrpnt = -iemmp3_ispow[y] * v; + else + *xrpnt = iemmp3_ispow[y] * v; + part2remain--; + } + else + *xrpnt = 0.0; + xrpnt += step; + } + } + for(;l3 && (part2remain > 0);l3--) + { + struct iemmp3_newHuff *h = iemmp3_htc+gr_info->count1table_select; + register short *val = h->table,a; + + while((a=*val++)<0) + { + part2remain--; + if(part2remain < 0) + { + part2remain++; + a = 0; + break; + } + if (get1bit()) + val -= a; + } + + for(i=0;i<4;i++) + { + if(!(i & 1)) + { + if(!mc) + { + mc = *m++; + xrpnt = ((real *) xr) + (*m++); + lwin = *m++; + cb = *m++; + if(lwin == 3) + { + v = gr_info->pow2gain[(*scf++) << shift]; + step = 1; + } + else + { + v = gr_info->full_gain[lwin][(*scf++) << shift]; + step = 3; + } + } + mc--; + } + if( (a & (0x8>>i)) ) + { + max[lwin] = cb; + part2remain--; + if(part2remain < 0) + { + part2remain++; + break; + } + if(get1bit()) + *xrpnt = -v; + else + *xrpnt = v; + } + else + *xrpnt = 0.0; + xrpnt += step; + } + } + + while( m < me ) + { + if(!mc) + { + mc = *m++; + xrpnt = ((real *) xr) + *m++; + if( (*m++) == 3) + step = 1; + else + step = 3; + m++; /* cb */ + } + mc--; + *xrpnt = 0.0; + xrpnt += step; + *xrpnt = 0.0; + xrpnt += step; + /* we could add a little opt. here: + * if we finished a band for window 3 or a long band + * further bands could copied in a simple loop without a + * special 'map' decoding + */ + } + + gr_info->maxband[0] = max[0]+1; + gr_info->maxband[1] = max[1]+1; + gr_info->maxband[2] = max[2]+1; + gr_info->maxbandl = max[3]+1; + + { + int rmax = max[0] > max[1] ? max[0] : max[1]; + rmax = (rmax > max[2] ? rmax : max[2]) + 1; + gr_info->maxb = rmax ? iemmp3_shortLimit[sfreq][rmax] : iemmp3_longLimit[sfreq][max[3]+1]; + } + + } + else + { + /* + * decoding with 'long' BandIndex table (block_type != 2) + */ + int *pretab = gr_info->preflag ? iemmp3_pretab1 : iemmp3_pretab2; + int i,max = -1; + int cb = 0; + register int *m = iemmp3_map[sfreq][2]; + register real v = 0.0; + register int mc = 0; + + /* + * long hash table values + */ + for(i=0;i<3;i++) + { + int lp = l[i]; + struct iemmp3_newHuff *h = iemmp3_ht+gr_info->table_select[i]; + + for(;lp;lp--,mc--) + { + int x,y; + + if(!mc) + { + mc = *m++; + v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; + cb = *m++; + } + { + register short *val = h->table; + while((y=*val++)<0) + { + if (get1bit()) + val -= y; + part2remain--; + } + x = y >> 4; + y &= 0xf; + } + if (x == 15) + { + max = cb; + part2remain -= h->linbits+1; + x += getbits(h->linbits); + if(get1bit()) + *xrpnt++ = -iemmp3_ispow[x] * v; + else + *xrpnt++ = iemmp3_ispow[x] * v; + } + else if(x) + { + max = cb; + if(get1bit()) + *xrpnt++ = -iemmp3_ispow[x] * v; + else + *xrpnt++ = iemmp3_ispow[x] * v; + part2remain--; + } + else + *xrpnt++ = 0.0; + + if (y == 15) + { + max = cb; + part2remain -= h->linbits+1; + y += getbits(h->linbits); + if(get1bit()) + *xrpnt++ = -iemmp3_ispow[y] * v; + else + *xrpnt++ = iemmp3_ispow[y] * v; + } + else if(y) + { + max = cb; + if(get1bit()) + *xrpnt++ = -iemmp3_ispow[y] * v; + else + *xrpnt++ = iemmp3_ispow[y] * v; + part2remain--; + } + else + *xrpnt++ = 0.0; + } + } + + /* + * short (count1table) values + */ + for(;l3 && (part2remain > 0);l3--) + { + struct iemmp3_newHuff *h = iemmp3_htc+gr_info->count1table_select; + register short *val = h->table,a; + + while((a=*val++)<0) + { + part2remain--; + if(part2remain < 0) + { + part2remain++; + a = 0; + break; + } + if (get1bit()) + val -= a; + } + + for(i=0;i<4;i++) + { + if(!(i & 1)) + { + if(!mc) + { + mc = *m++; + cb = *m++; + v = gr_info->pow2gain[((*scf++) + (*pretab++)) << shift]; + } + mc--; + } + if ( (a & (0x8>>i)) ) + { + max = cb; + part2remain--; + if(part2remain < 0) + { + part2remain++; + break; + } + if(get1bit()) + *xrpnt++ = -v; + else + *xrpnt++ = v; + } + else + *xrpnt++ = 0.0; + } + } + + /* + * zero part + */ + for(i=(&xr[SBLIMIT][0]-xrpnt)>>1;i;i--) + { + *xrpnt++ = 0.0; + *xrpnt++ = 0.0; + } + + gr_info->maxbandl = max+1; + gr_info->maxb = iemmp3_longLimit[sfreq][gr_info->maxbandl]; + } + + while( part2remain > 16 ) + { + getbits(16); /* Dismiss stuffing Bits */ + part2remain -= 16; + } + if(part2remain > 0) + getbits(part2remain); + else if(part2remain < 0) + { + post("mpg123: Can't rewind stream by %d bits!\n",-part2remain); + return 1; /* -> error */ + } + return 0; +} + +static void III_i_stereo(real xr_buf[2][SBLIMIT][SSLIMIT],int *scalefac, + struct iemmp3_gr_info_s *gr_info,int sfreq,int ms_stereo,int lsf) +{ + real (*xr)[SBLIMIT*SSLIMIT] = (real (*)[SBLIMIT*SSLIMIT] ) xr_buf; + struct iemmp3_bandInfoStruct *bi = &bandInfo[sfreq]; + real *tab1,*tab2; + + if(lsf) + { + int p = gr_info->scalefac_compress & 0x1; + if(ms_stereo) + { + tab1 = iemmp3_pow1_2[p]; tab2 = iemmp3_pow2_2[p]; + } + else + { + tab1 = iemmp3_pow1_1[p]; tab2 = iemmp3_pow2_1[p]; + } + } + else + { + if(ms_stereo) + { + tab1 = iemmp3_tan1_2; tab2 = iemmp3_tan2_2; + } + else + { + tab1 = iemmp3_tan1_1; tab2 = iemmp3_tan2_1; + } + } + + if (gr_info->block_type == 2) + { + int lwin,do_l = 0; + if( gr_info->mixed_block_flag ) + do_l = 1; + + for (lwin=0;lwin<3;lwin++) /* process each window */ + { + /* get first band with zero values */ + int is_p,sb,idx,sfb = gr_info->maxband[lwin]; /* sfb is minimal 3 for mixed mode */ + if(sfb > 3) + do_l = 0; + + for(;sfb<12;sfb++) + { + is_p = scalefac[sfb*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ + if(is_p != 7) { + real t1,t2; + sb = bi->shortDiff[sfb]; + idx = bi->shortIdx[sfb] + lwin; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for (; sb > 0; sb--,idx+=3) + { + real v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + } + +#if 1 + /* in the original: copy 10 to 11 , here: copy 11 to 12 + maybe still wrong??? (copy 12 to 13?) */ + is_p = scalefac[11*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ + sb = bi->shortDiff[12]; + idx = bi->shortIdx[12] + lwin; +#else + is_p = scalefac[10*3+lwin-gr_info->mixed_block_flag]; /* scale: 0-15 */ + sb = bi->shortDiff[11]; + idx = bi->shortIdx[11] + lwin; +#endif + if(is_p != 7) + { + real t1,t2; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for ( ; sb > 0; sb--,idx+=3 ) + { + real v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + } /* end for(lwin; .. ; . ) */ + + if (do_l) + { + /* also check l-part, if ALL bands in the three windows are 'empty' + * and mode = mixed_mode + */ + int sfb = gr_info->maxbandl; + int idx = bi->longIdx[sfb]; + + for ( ; sfb<8; sfb++ ) + { + int sb = bi->longDiff[sfb]; + int is_p = scalefac[sfb]; /* scale: 0-15 */ + if(is_p != 7) { + real t1,t2; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for ( ; sb > 0; sb--,idx++) + { + real v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + else + idx += sb; + } + } + } + else /* ((gr_info->block_type != 2)) */ + { + int sfb = gr_info->maxbandl; + int is_p,idx = bi->longIdx[sfb]; + for ( ; sfb<21; sfb++) + { + int sb = bi->longDiff[sfb]; + is_p = scalefac[sfb]; /* scale: 0-15 */ + if(is_p != 7) { + real t1,t2; + t1 = tab1[is_p]; t2 = tab2[is_p]; + for ( ; sb > 0; sb--,idx++) + { + real v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + else + idx += sb; + } + + is_p = scalefac[20]; /* copy l-band 20 to l-band 21 */ + if(is_p != 7) + { + int sb; + real t1 = tab1[is_p],t2 = tab2[is_p]; + + for ( sb = bi->longDiff[21]; sb > 0; sb--,idx++ ) + { + real v = xr[0][idx]; + xr[0][idx] = v * t1; + xr[1][idx] = v * t2; + } + } + } /* ... */ +} + + +static void III_antialias(real xr[SBLIMIT][SSLIMIT],struct iemmp3_gr_info_s *gr_info) +{ + int sblim; + + if(gr_info->block_type == 2) + { + if(!gr_info->mixed_block_flag) + return; + sblim = 1; + } + else { + sblim = gr_info->maxb-1; + } + + /* 31 alias-reduction operations between each pair of sub-bands */ + /* with 8 butterflies between each pair */ + + { + int sb; + real *xr1=(real *) xr[1]; + + for(sb=sblim;sb;sb--,xr1+=10) + { + int ss; + real *cs=iemmp3_aa_cs,*ca=iemmp3_aa_ca; + real *xr2 = xr1; + + for(ss=7;ss>=0;ss--) + { /* upper and lower butterfly inputs */ + register real bu = *--xr2,bd = *xr1; + *xr2 = (bu * (*cs) ) - (bd * (*ca) ); + *xr1++ = (bd * (*cs++) ) + (bu * (*ca++) ); + } + } + } +} + +static void III_hybrid(real fsIn[SBLIMIT][SSLIMIT],real tsOut[SSLIMIT][SBLIMIT], + int ch,struct iemmp3_gr_info_s *gr_info) +{ + real *tspnt = (real *) tsOut; + real (*block)[2][SBLIMIT*SSLIMIT] = iemmp3_gmp->hybrid_block; + int *blc = iemmp3_gmp->hybrid_blc; + real *rawout1,*rawout2; + int bt; + unsigned int sb = 0; + + { + int b = blc[ch]; + rawout1=block[b][ch]; + b=-b+1; + rawout2=block[b][ch]; + blc[ch] = b; + } + + + if(gr_info->mixed_block_flag) { + sb = 2; + dct36(fsIn[0],rawout1,rawout2,iemmp3_win[0],tspnt); + dct36(fsIn[1],rawout1+18,rawout2+18,iemmp3_win1[0],tspnt+1); + rawout1 += 36; rawout2 += 36; tspnt += 2; + } + + bt = gr_info->block_type; + if(bt == 2) { + for (; sbmaxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) { + dct12(fsIn[sb],rawout1,rawout2,iemmp3_win[2],tspnt); + dct12(fsIn[sb+1],rawout1+18,rawout2+18,iemmp3_win1[2],tspnt+1); + } + } + else { + for (; sbmaxb; sb+=2,tspnt+=2,rawout1+=36,rawout2+=36) { + dct36(fsIn[sb],rawout1,rawout2,iemmp3_win[bt],tspnt); + dct36(fsIn[sb+1],rawout1+18,rawout2+18,iemmp3_win1[bt],tspnt+1); + } + } + + for(;sbsynth_bo; + + if(!channel) + { + bo--; + bo &= 0xf; + buf = iemmp3_gmp->synth_buffs[0]; + } + else + { + samples++; + buf = iemmp3_gmp->synth_buffs[1]; + } + + if(bo & 0x1) + { + b0 = buf[0]; + bo1 = bo; + dct64(buf[1]+((bo+1)&0xf),buf[0]+bo,bandPtr); + } + else + { + b0 = buf[1]; + bo1 = bo+1; + dct64(buf[0]+bo,buf[1]+bo+1,bandPtr); + } + + iemmp3_gmp->synth_bo = bo; + + { + register int j; + real *window = iemmp3_decwin + 16 - bo1; + + for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step) + { + real sum; + sum = window[0x0] * b0[0x0]; + sum -= window[0x1] * b0[0x1]; + sum += window[0x2] * b0[0x2]; + sum -= window[0x3] * b0[0x3]; + sum += window[0x4] * b0[0x4]; + sum -= window[0x5] * b0[0x5]; + sum += window[0x6] * b0[0x6]; + sum -= window[0x7] * b0[0x7]; + sum += window[0x8] * b0[0x8]; + sum -= window[0x9] * b0[0x9]; + sum += window[0xA] * b0[0xA]; + sum -= window[0xB] * b0[0xB]; + sum += window[0xC] * b0[0xC]; + sum -= window[0xD] * b0[0xD]; + sum += window[0xE] * b0[0xE]; + sum -= window[0xF] * b0[0xF]; + WRITE_SAMPLE(samples,sum,clip); + } + + { + real sum; + sum = window[0x0] * b0[0x0]; + sum += window[0x2] * b0[0x2]; + sum += window[0x4] * b0[0x4]; + sum += window[0x6] * b0[0x6]; + sum += window[0x8] * b0[0x8]; + sum += window[0xA] * b0[0xA]; + sum += window[0xC] * b0[0xC]; + sum += window[0xE] * b0[0xE]; + WRITE_SAMPLE(samples,sum,clip); + b0-=0x10,window-=0x20,samples+=step; + } + window += bo1<<1; + + for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step) + { + real sum; + sum = -window[-0x1] * b0[0x0]; + sum -= window[-0x2] * b0[0x1]; + sum -= window[-0x3] * b0[0x2]; + sum -= window[-0x4] * b0[0x3]; + sum -= window[-0x5] * b0[0x4]; + sum -= window[-0x6] * b0[0x5]; + sum -= window[-0x7] * b0[0x6]; + sum -= window[-0x8] * b0[0x7]; + sum -= window[-0x9] * b0[0x8]; + sum -= window[-0xA] * b0[0x9]; + sum -= window[-0xB] * b0[0xA]; + sum -= window[-0xC] * b0[0xB]; + sum -= window[-0xD] * b0[0xC]; + sum -= window[-0xE] * b0[0xD]; + sum -= window[-0xF] * b0[0xE]; + sum -= window[-0x0] * b0[0xF]; + WRITE_SAMPLE(samples,sum,clip); + } + } + *pnt += 128; + + return clip; +} + + + +static void *sigmp3play_new(void) +{ + char *vec; + t_sigmp3play *x = (t_sigmp3play *)pd_new(sigmp3play_class); + + x->file_is_open = 0; + x->play_state = 0; + x->mp3_encode_size = 0; + x->mp3_out_index = 0; + x->file_block_num = 0; + x->file_remain = 0; + x->file_size = 0; + x->mp3_ch = 1; + x->mp3_sr = 44100; + x->obj_sr = 44100; + x->obj_n = 1; + x->samp_per_frame = 1152; + x->mp3_byterate = 11; + x->down = 0; + x->scale = 1.0/32768.0; + x->offset_sec = 0.0; + x->fh = (FILE *)0L; + x->mp3inbuf = (char *)getzbytes(MY_MP3_MALLOC_IN_SIZE); + x->mp3outbuf = (char *)getzbytes(MY_MP3_MALLOC_OUT_SIZE); + x->filename = (char *)getzbytes(MY_MP3_MALLOC_FN); + x->begframeseek = (int *)0; + x->curframeseek = 0; + x->maxframeseek = 0; + x->frame_counter = 0; + x->time1_bang0_handle = 0; + x->time_factor = 0.0; + vec = x->filename; + *vec = 0; + InitMP3(&(x->mp)); + x->mp_is_init = 1; + x->x_clock = clock_new(x, (t_method)sigmp3play_tick); + outlet_new(&x->x_obj, &s_signal); + outlet_new(&x->x_obj, &s_signal); + x->x_floatout = outlet_new(&x->x_obj, &s_float); + x->x_bangout = outlet_new(&x->x_obj, &s_bang); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); + x->x_canvas = canvas_getcurrent(); + return (x); +} + +static void sigmp3play_cleanup(t_sigmp3play *x) +{ + x->file_is_open = 0; + fclose(x->fh); + x->play_state = 0; + x->mp3_out_index = 0; + x->mp_is_init = 0; + ExitMP3(&(x->mp)); + x->time1_bang0_handle = 0; + clock_delay(x->x_clock, 0); +} + +static int sigmp3play_read_frame_length_first(t_sigmp3play *x, int *frsz) +{ + int framesize, lsf, bitrate_index, sampling_frequency, padding, mpeg25, lay, ret=MP3_EX; + int version, syncword; + unsigned long head; + unsigned char chead; + + *frsz = 0; + if((x->file_size) >= 4) + { + fread(&chead, 1, sizeof(char), x->fh); + head = (unsigned int)chead; + fread(&chead, 1, sizeof(char), x->fh); + head <<= 8; + head |= (unsigned int)chead; + fread(&chead, 1, sizeof(char), x->fh); + head <<= 8; + head |= (unsigned int)chead; + fread(&chead, 1, sizeof(char), x->fh); + head <<= 8; + head |= (unsigned int)chead; + syncword = (head >> 20) & 0x0fff; + version = ((head >> 19) & 0x01) ? 0 : 1; + if((syncword & 0x01) == 0) + version = 2; + if(version == 0) + x->samp_per_frame = 1152; + else + x->samp_per_frame = 576; + + if(head & (1<<20)) + { + lsf = (head & (1<<19)) ? 0x0 : 0x1; + mpeg25 = 0; + } + else + { + lsf = 1; + mpeg25 = 1; + } + lay = 4-((head>>17)&3); + if(((head>>10)&0x3) == 0x3) + { + post("Stream error"); + return(MP3_EX); + } + if(mpeg25) + sampling_frequency = 6 + ((head>>10)&0x3); + else + sampling_frequency = ((head>>10)&0x3) + (lsf*3); + x->mp3_sr = (int)iemmp3_freqs[sampling_frequency]; + if(mpeg25) + bitrate_index = ((head>>12)&0xf); + bitrate_index = ((head>>12)&0xf); + padding = ((head>>9)&0x1); + if(!bitrate_index) + { + post("Free format not supported.\n"); + return(MP3_EX); + } + switch(lay) + { + case 1: + post("Layer I not supported!\n"); + break; + case 2: + post("Layer II not supported!\n"); + break; + case 3: + framesize = iemmp3_tabsel_123[lsf][2][bitrate_index]*144000; + framesize /= (iemmp3_freqs[sampling_frequency] << lsf); + framesize += padding; + *frsz = framesize; + ret = 0; + break; + default: + post("Sorry, unknown layer type.\n"); + break; + } + return(ret); + } + else + { + return(1); + } +} + +static int sigmp3play_read_frame_length_next(t_sigmp3play *x, int *frsz, int frame_counter) +{ + int framesize, lsf, bitrate_index, sampling_frequency, *begframeseek=x->begframeseek; + unsigned long head; + unsigned char chead; + + *frsz = 0; + if(begframeseek[frame_counter] < ((x->file_size) - 4)) + { + fread(&chead, 1, sizeof(char), x->fh); + head = (unsigned int)chead; + fread(&chead, 1, sizeof(char), x->fh); + head <<= 8; + head |= (unsigned int)chead; + fread(&chead, 1, sizeof(char), x->fh); + head <<= 8; + head |= (unsigned int)chead; + fread(&chead, 1, sizeof(char), x->fh); + head <<= 8; + head |= (unsigned int)chead; + if(head & (1<<20)) + { + lsf = (head & (1<<19)) ? 0x0 : 0x1; + sampling_frequency = ((head>>10)&0x3) + (lsf*3); + } + else + { + lsf = 1; + sampling_frequency = 6 + ((head>>10)&0x3); + } + bitrate_index = ((head>>12)&0xf); + framesize = iemmp3_tabsel_123[lsf][2][bitrate_index]*144000; + framesize /= (iemmp3_freqs[sampling_frequency] << lsf); + framesize += ((head>>9)&0x1); + *frsz = framesize; + return(0); + } + else + return(1); +} + +static int sigmp3play_calc_frames(t_sigmp3play *x) +{ + int *begframeseek=x->begframeseek, i, maxframeseek, framesize, frame_counter; + float length; + + fseek(x->fh,0,SEEK_SET); + if(!sigmp3play_read_frame_length_first(x, &framesize)) + { + if(framesize <= 0) + { + return(MP3_EX); + } + i = framesize - 6; + maxframeseek = (x->file_size) / i; + if(!begframeseek) + { + x->begframeseek = (int *)getzbytes((maxframeseek)*sizeof(int)); + x->maxframeseek = maxframeseek; + } + else + { + if(maxframeseek > (x->maxframeseek)) + { + freebytes(x->begframeseek, (x->maxframeseek)*sizeof(int)); + x->begframeseek = (int *)getzbytes((maxframeseek)*sizeof(int)); + x->maxframeseek = maxframeseek; + } + } + begframeseek = x->begframeseek; + begframeseek[0] = 0; + begframeseek[1] = framesize; + frame_counter = 1; + /*x->curframeseek = maxframeseek;*/ + fseek(x->fh, begframeseek[1], SEEK_SET); + while(!sigmp3play_read_frame_length_next(x, &framesize, frame_counter)) + { + begframeseek[frame_counter+1] = begframeseek[frame_counter] + framesize; + frame_counter++; + fseek(x->fh, begframeseek[frame_counter], SEEK_SET); + }; + frame_counter--; + length = (float)(frame_counter)*(float)(x->samp_per_frame) / (float)(x->mp3_sr); + x->length_sec = length; + x->time_factor = length / (float)(frame_counter); + x->curframeseek = frame_counter; + fseek(x->fh,0,SEEK_SET); + return(MP3_OK); + } + else + return(MP3_EX); +} + +static void sigmp3play_do_open(t_sigmp3play *x, char *str, int calc_it) +{ + int mp3_sr, obj_sr; + int file_size, size, mp3_encode_return=MP3_OK, mp3_read_length, i, j, *begframeseek; + static char *modes[4] = { "Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel" }; + static char *layers[4] = { "Unknown" , "I", "II", "III" }; + char completefilename[400]; + + if(x->file_is_open) + { + post("mp3play-ERROR: file is already open, please stop it first!"); + } + else if(*str == 0) + { + post("mp3play-ERROR: there is no filename to open"); + } + else + { + if(str[0] == '/') + { + strcpy(completefilename, str); + } + else if(((str[0] >= 'A')&&(str[0] <= 'Z')|| + (str[0] >= 'a')&&(str[0] <= 'z'))&& + (str[1] == ':')&&(str[2] == '/')) + { + strcpy(completefilename, str); + } + else + { + strcpy(completefilename, canvas_getdir(x->x_canvas)->s_name); + strcat(completefilename, "/"); + strcat(completefilename, str); + } + + if((x->fh = fopen(completefilename, "rb")) == NULL) + { + post("mp3play-ERROR: cannot open %s", completefilename); + } + else + { + strcpy(x->filename, completefilename); + fseek(x->fh,0,SEEK_END); + file_size = (int)ftell(x->fh); + x->file_size = file_size; + if(!x->mp_is_init) + { + InitAgainMP3(&(x->mp)); + x->mp_is_init = 1; + } + if(calc_it) + mp3_encode_return = sigmp3play_calc_frames(x); + if(mp3_encode_return == MP3_EX) + { + sigmp3play_cleanup(x); + return; + } + if(x->frame_counter) + x->frame_counter = (int)(x->offset_sec / x->time_factor); + i = x->frame_counter; + if(i > (x->curframeseek - 1)) + i = x->curframeseek - 1; + begframeseek = x->begframeseek; + j = begframeseek[i]; + fseek(x->fh,j,SEEK_SET); + x->file_block_num = (file_size-j) / MY_MP3_MALLOC_IN_SIZE; + x->file_remain = (file_size-j) - (x->file_block_num)*MY_MP3_MALLOC_IN_SIZE; + if(x->file_block_num) + { + mp3_read_length = MY_MP3_MALLOC_IN_SIZE; + x->file_block_num--; + } + else + { + mp3_read_length = x->file_remain; + x->file_remain = 0; + } + if(mp3_read_length > 0) + { + fread(x->mp3inbuf, mp3_read_length, sizeof(char), x->fh); + mp3_encode_return = decodeMP3(&(x->mp), x->mp3inbuf, mp3_read_length, x->mp3outbuf, + MY_MP3_MALLOC_IN_SIZE2, &size); + if(mp3_encode_return == MP3_EX) + { + sigmp3play_cleanup(x); + return; + } + post ("MPEG %s, Layer: %s, Freq: %ld, mode: %s, modext: %d, BPF : %d", + x->mp.fr.mpeg25 ? "2.5" : (x->mp.fr.lsf ? "2.0" : "1.0"), + layers[x->mp.fr.lay],iemmp3_freqs[x->mp.fr.sampling_frequency], + modes[x->mp.fr.mode],x->mp.fr.mode_ext,x->mp.fr.framesize+4); + post ("Channels: %d, copyright: %s, original: %s, CRC: %s, emphasis: %d.", + x->mp.fr.stereo,x->mp.fr.copyright?"Yes":"No", + x->mp.fr.original?"Yes":"No",x->mp.fr.error_protection?"Yes":"No", + x->mp.fr.emphasis); + post ("Bitrate: %d Kbits/s, Extension value: %d", + iemmp3_tabsel_123[x->mp.fr.lsf][x->mp.fr.lay-1] + [x->mp.fr.bitrate_index],x->mp.fr.extension); + post ("Original Soundfile-Length : %.3f sec.\n",x->length_sec); + + x->mp3_byterate = 128*iemmp3_tabsel_123[x->mp.fr.lsf][x->mp.fr.lay-1][x->mp.fr.bitrate_index]; + /* 1024/8 */ + + if(x->mp.fr.stereo == 2) + x->mp3_ch = 2; + else if(x->mp.fr.stereo == 1) + x->mp3_ch = 1; + else + { + x->mp3_ch = 1; + post("mp3_play~ WARNING: unknown number of channels : %d channels", + x->mp.fr.stereo); + } + mp3_sr = (int)(iemmp3_freqs[x->mp.fr.sampling_frequency]); + obj_sr = x->obj_sr; + x->mp3_sr = mp3_sr; + if(mp3_sr == obj_sr) + { + x->down = 0; + } + else if(2*mp3_sr == obj_sr) + { + x->down = 1; + } + else if(4*mp3_sr == obj_sr) + { + x->down = 2; + } + else if(mp3_sr == 2*obj_sr) + { + x->down = -1; + } + else if(mp3_sr == 4*obj_sr) + { + x->down = -2; + } + else + { + post("mp3_play~ WARNING: playing the filesamplerate of %d Hz at %d Hz", mp3_sr,obj_sr); + x->down = 0; + } + + if(mp3_encode_return == MP3_OK) + { + x->file_is_open = 1; + x->mp3_encode_size = size * sizeof(char) / sizeof(short); + } + else + { + x->file_is_open = 0; + x->mp3_out_index = 0; + fclose(x->fh); + } + } + else + { + x->file_is_open = 0; + fclose(x->fh); + } + } + x->play_state = 2; + x->mp3_out_index = 0; + } +} + +static t_int *sigmp3play_perform(t_int *w) +{ + t_sigmp3play *x = (t_sigmp3play *)(w[1]); + t_float *out1 = (t_float *)(w[2]); + t_float *out2 = (t_float *)(w[3]); + int n = (int)(w[4]); + short *ivec = (short *)(x->mp3outbuf); + int size, mp3_encode_return, mp3_read_length, mp3_ch, down; + float scale = x->scale, outa, outb; + int mp3_out_index = x->mp3_out_index; + + if (!x->file_is_open) + goto sigmp3play_labelzero; + if (x->play_state != 1) + goto sigmp3play_labelzero; + + if(mp3_out_index >= x->mp3_encode_size) + { + x->frame_counter++; + x->time1_bang0_handle = 1; + clock_delay(x->x_clock, 0); + mp3_out_index = 0; + mp3_encode_return = decodeMP3(&(x->mp), NULL, 0, x->mp3outbuf, + MY_MP3_MALLOC_IN_SIZE2, &size); + if(mp3_encode_return == MP3_OK) + x->mp3_encode_size = size * sizeof(char) / sizeof(short); + else if(mp3_encode_return == MP3_EX) + { + sigmp3play_cleanup(x); + goto sigmp3play_labelzero; + } + else + { + if(x->file_block_num > 0) + { + mp3_read_length = MY_MP3_MALLOC_IN_SIZE; + x->file_block_num--; + } + else if(x->file_remain > 0) + { + mp3_read_length = x->file_remain; + x->file_remain = 0; + } + else + { + sigmp3play_cleanup(x); + goto sigmp3play_labelzero; + } + + fread(x->mp3inbuf, mp3_read_length, sizeof(char), x->fh); + mp3_encode_return = decodeMP3(&(x->mp), x->mp3inbuf, mp3_read_length, + x->mp3outbuf, MY_MP3_MALLOC_IN_SIZE2, &size); + x->mp3_encode_size = size * sizeof(char) / sizeof(short); + if(mp3_encode_return == MP3_EX) + { + sigmp3play_cleanup(x); + goto sigmp3play_labelzero; + } + } + } + + mp3_ch = x->mp3_ch; + down = x->down; + if(mp3_ch == 2) + { + if(down == 0) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + 2*n; + while (n--) + { + *out1++ = scale * (float)(*ivec++); + *out2++ = scale * (float)(*ivec++); + } + } + else if(down == 1) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + n; + n /= 2; + while (n--) + { + outa = scale * (float)(*ivec++); + outb = scale * (float)(*ivec++); + *out1++ = outa; + *out2++ = outb; + *out1++ = outa; + *out2++ = outb; + } + } + else if(down == 2) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + n/2; + n /= 4; + while (n--) + { + outa = scale * (float)(*ivec++); + outb = scale * (float)(*ivec++); + *out1++ = outa; + *out2++ = outb; + *out1++ = outa; + *out2++ = outb; + *out1++ = outa; + *out2++ = outb; + *out1++ = outa; + *out2++ = outb; + } + } + else if(down == -1) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + 4*n; + while (n--) + { + outa = scale * (float)(*ivec++); + outb = scale * (float)(*ivec); + ivec += 3; + *out1++ = outa; + *out2++ = outa; + } + } + else if(down == -2) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + 8*n; + while (n--) + { + outa = scale * (float)(*ivec++); + outb = scale * (float)(*ivec); + ivec += 7; + *out1++ = outa; + *out2++ = outa; + } + } + } + else + { + if(down == 0) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + n; + while (n--) + { + outa = scale * (float)(*ivec++); + *out1++ = outa; + *out2++ = outa; + } + } + else if(down == 1) + { + ivec += mp3_out_index; + n /= 2; + x->mp3_out_index = mp3_out_index + n; + while (n--) + { + outa = scale * (float)(*ivec++); + *out1++ = outa; + *out2++ = outa; + *out1++ = outa; + *out2++ = outa; + } + } + else if(down == 2) + { + ivec += mp3_out_index; + n /= 4; + x->mp3_out_index = mp3_out_index + n; + while (n--) + { + outa = scale * (float)(*ivec++); + *out1++ = outa; + *out2++ = outa; + *out1++ = outa; + *out2++ = outa; + *out1++ = outa; + *out2++ = outa; + *out1++ = outa; + *out2++ = outa; + } + } + else if(down == -1) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + 2*n; + while (n--) + { + outa = scale * (float)(*ivec); + ivec += 2; + *out1++ = outa; + *out2++ = outa; + } + } + else if(down == -2) + { + ivec += mp3_out_index; + x->mp3_out_index = mp3_out_index + 4*n; + while (n--) + { + outa = scale * (float)(*ivec); + ivec += 4; + *out1++ = outa; + *out2++ = outa; + } + } + } + return (w+5); + +sigmp3play_labelzero: + + while (n--) + { + *out1++ = 0; + *out2++ = 0; + } + return (w+5); +} + +static void sigmp3play_dsp(t_sigmp3play *x, t_signal **sp) +{ + x->obj_sr = (int)(sp[0]->s_sr); + x->obj_n = (int)(sp[0]->s_n); + dsp_add(sigmp3play_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); +} + + + +static void sigmp3play_stop(t_sigmp3play *x) +{ + if(x->file_is_open) + { + x->file_block_num = 0; + x->file_remain = 0; + } +} + +static void sigmp3play_start(t_sigmp3play *x) +{ + if(x->file_is_open) + { + x->play_state = 1; + } +} + +static void sigmp3play_ft1(t_sigmp3play *x, t_floatarg offset) +{ + if(offset < 0.0) + offset = 0.0; + x->offset_sec = (float)offset; +} + +static void sigmp3play_pause(t_sigmp3play *x) +{ + if(x->file_is_open) + { + if(x->play_state == 0) + x->play_state = 1; + else if(x->play_state == 1) + x->play_state = 0; + } +} + +static void sigmp3play_open(t_sigmp3play *x, t_symbol *s) +{ + x->frame_counter = 0; + sigmp3play_do_open(x, (char *)s->s_name, 1); +} + +static void sigmp3play_open_again(t_sigmp3play *x) +{ + x->frame_counter = 0; + sigmp3play_do_open(x, x->filename, 0); +} + +static void sigmp3play_open_at(t_sigmp3play *x, t_symbol *s) +{ + x->frame_counter = 1; + sigmp3play_do_open(x, (char *)s->s_name, 1); +} + +static void sigmp3play_open_again_at(t_sigmp3play *x) +{ + x->frame_counter = 1; + sigmp3play_do_open(x, x->filename, 0); +} + + +static void sigmp3play_tick(t_sigmp3play *x) +{ + if(x->time1_bang0_handle) + { + outlet_float(x->x_floatout, (float)(x->frame_counter)*(x->time_factor)); + } + else + { + outlet_bang(x->x_bangout); + } +} + +static void sigmp3play_free(t_sigmp3play *x) +{ + if(x->mp_is_init) + ExitMP3(&(x->mp)); + if(x->begframeseek) + freebytes(x->begframeseek, (x->maxframeseek)*sizeof(int)); + freebytes(x->filename, MY_MP3_MALLOC_FN); + freebytes(x->mp3outbuf, MY_MP3_MALLOC_OUT_SIZE); + freebytes(x->mp3inbuf, MY_MP3_MALLOC_IN_SIZE); + clock_free(x->x_clock); +} + +void sigmp3play_setup(void) +{ + sigmp3play_class = class_new(gensym("mp3play~"), (t_newmethod)sigmp3play_new, + (t_method)sigmp3play_free, sizeof(t_sigmp3play), 0, 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_dsp, gensym("dsp"), 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_start, gensym("start"), 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_ft1, + gensym("ft1"), A_FLOAT, 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_stop, gensym("stop"), 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_pause, gensym("pause"), 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_again_at, gensym("open_again_at"), 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_open, gensym("open"), A_DEFSYM, 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_again, gensym("open_again"), 0); + class_addmethod(sigmp3play_class, (t_method)sigmp3play_open_at, gensym("open_at"), A_DEFSYM, 0); + class_sethelpsymbol(sigmp3play_class, gensym("iemhelp/help-mp3play~")); + /*post("\nmp3play~ written by thomas musil & norbert math\nV 0.1 iem graz + austria 05 2000\n");*/ +} diff --git a/src/iem_t3_lib/iem_t3_lib.c b/src/iem_t3_lib/iem_t3_lib.c index 65365ae..91b3725 100644 --- a/src/iem_t3_lib/iem_t3_lib.c +++ b/src/iem_t3_lib/iem_t3_lib.c @@ -1,66 +1,66 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include -#include -/* -#include -#include -#include -#include -#include - -#ifndef NT -#include -#include -#endif - -#ifdef NT -#include -#endif -*/ - -static t_class *iem_t3_lib_class; - -static void *iem_t3_lib_new(void) -{ - t_object *x = (t_object *)pd_new(iem_t3_lib_class); - - return (x); -} - -void sigt3_line_setup(void); -void sigt3_sig_setup(void); -void t3_bpe_setup(void); -void t3_delay_setup(void); -void t3_metro_setup(void); -void t3_timer_setup(void); - -/* ------------------------ setup routine ------------------------- */ - -void iem_t3_lib_setup(void) -{ - iem_t3_lib_class = class_new(gensym("iem_t3_lib"), iem_t3_lib_new, 0, - sizeof(t_object), CLASS_NOINLET, 0); - - sigt3_line_setup(); - sigt3_sig_setup(); - t3_bpe_setup(); - t3_delay_setup(); - t3_metro_setup(); - t3_timer_setup(); - - post("iem_t3_lib (R-1.16) library loaded! (c) Gerhard Eckel, Thomas Musil 05.2005"); - post(" musil%ciem.at iem KUG Graz Austria", '@'); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include +#include +/* +#include +#include +#include +#include +#include + +#ifndef NT +#include +#include +#endif + +#ifdef NT +#include +#endif +*/ + +static t_class *iem_t3_lib_class; + +static void *iem_t3_lib_new(void) +{ + t_object *x = (t_object *)pd_new(iem_t3_lib_class); + + return (x); +} + +void sigt3_line_setup(void); +void sigt3_sig_setup(void); +void t3_bpe_setup(void); +void t3_delay_setup(void); +void t3_metro_setup(void); +void t3_timer_setup(void); + +/* ------------------------ setup routine ------------------------- */ + +void iem_t3_lib_setup(void) +{ + iem_t3_lib_class = class_new(gensym("iem_t3_lib"), iem_t3_lib_new, 0, + sizeof(t_object), CLASS_NOINLET, 0); + + sigt3_line_setup(); + sigt3_sig_setup(); + t3_bpe_setup(); + t3_delay_setup(); + t3_metro_setup(); + t3_timer_setup(); + + post("iem_t3_lib (R-1.16) library loaded! (c) Gerhard Eckel, Thomas Musil 05.2005"); + post(" musil%ciem.at iem KUG Graz Austria", '@'); +} diff --git a/src/iem_t3_lib/sigt3_line.c b/src/iem_t3_lib/sigt3_line.c index e58552f..3666098 100644 --- a/src/iem_t3_lib/sigt3_line.c +++ b/src/iem_t3_lib/sigt3_line.c @@ -1,279 +1,279 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include - -/* -------------------------- t3_line~ ------------------------------ */ -static t_class *sigt3_line_class; - -typedef struct _sigt3_line -{ - t_object x_obj; - t_clock *x_clock; - float *x_beg; - double x_cur_val; - double x_dst_val; - double x_inlet_val; - double x_inc64; - double x_inc; - double x_ms2samps; - double x_ticks2ms; - double x_inlet_time; - double x_dst_time; - int x_cur_samps; - int x_dur_samps; - int x_n; - int x_t3_bang_samps; - int x_transient; -} t_sigt3_line; - -static void sigt3_line_nontransient(float *vec, t_sigt3_line *x, int n) -{ - int cur_samps = x->x_cur_samps, i; - double inc = x->x_inc; - double cur_val = x->x_cur_val; - - if(cur_samps) - { - if(cur_samps > n) - { - x->x_cur_samps -= n; - while(n--) - { - cur_val += inc; - *vec++ = (float)cur_val; - } - x->x_cur_val += x->x_inc64; - } - else if(cur_samps == n) - { - x->x_cur_samps = 0; - while(n--) - { - cur_val += inc; - *vec++ = (float)cur_val; - } - x->x_cur_val = x->x_dst_val; - } - else - { - for(i=0; ix_cur_val = cur_val = x->x_dst_val; - for(i=cur_samps; ix_cur_samps = 0; - } - } - else - { - while(n--) - *vec++ = (float)cur_val; - } -} - -static t_int *sigt3_line_perform(t_int *w) -{ - t_float *out = (t_float *)(w[1]); - t_sigt3_line *x = (t_sigt3_line *)(w[2]); - int n = (int)(w[3]); - - if(x->x_transient) - { - float *trans = x->x_beg; - - while(n--) - *out++ = *trans++; - x->x_transient = 0; - } - else - sigt3_line_nontransient(out, x, n); - return(w+4); -} - -static void sigt3_line_tick(t_sigt3_line *x) -{ - float *trans = x->x_beg; - int n = x->x_n, t3_bang_samps, cur_samps, i; - double inc, cur_val; - - if(!x->x_transient) - sigt3_line_nontransient(trans, x, n); - t3_bang_samps = x->x_t3_bang_samps; - x->x_dst_val = x->x_inlet_val; - if(x->x_inlet_time <= 0.0) - { - x->x_inlet_time = 0.0; - x->x_dst_time = 0.0; - x->x_dur_samps = 0; - x->x_cur_samps = 0; - cur_val = x->x_cur_val = x->x_dst_val; - for(i=t3_bang_samps; ix_dst_time = x->x_inlet_time; - x->x_inlet_time = 0.0; - cur_samps = (int)(x->x_dst_time * x->x_ms2samps); - if(!cur_samps) - cur_samps = 1; - x->x_dur_samps = cur_samps; - x->x_cur_samps = cur_samps; - cur_val = x->x_cur_val = (double)trans[t3_bang_samps]; - inc = x->x_inc = (x->x_dst_val - cur_val)/(double)cur_samps; - x->x_inc64 = (double)x->x_n * inc; - diff = n - t3_bang_samps; - if(cur_samps > diff) - { - for(i=t3_bang_samps; ix_cur_val += (double)diff * inc; - x->x_cur_samps -= diff; - } - else if(cur_samps == diff) - { - for(i=t3_bang_samps; ix_cur_val = x->x_dst_val; - x->x_cur_samps = 0; - } - else - { - end = t3_bang_samps + cur_samps; - for(i=t3_bang_samps; ix_cur_val = x->x_dst_val; - x->x_cur_samps = 0; - for(i=end; ix_transient = 1; -} - -static void sigt3_line_list(t_sigt3_line *x, t_symbol *s, int ac, t_atom *av) -{ - if((ac >= 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) - { - int t3_bang_samps, ticks; - double time; - - x->x_inlet_val = (double)atom_getfloatarg(1, ac, av); - t3_bang_samps = (int)((float)atom_getfloatarg(0, ac, av)*x->x_ms2samps); - if(t3_bang_samps < 0) - t3_bang_samps = 0; - ticks = t3_bang_samps / x->x_n; - x->x_t3_bang_samps = t3_bang_samps - x->x_n * ticks; - if((ac >= 3)&&IS_A_FLOAT(av,2)) - { - time = (double)atom_getfloatarg(2, ac, av); - if(time < 0.0) - time = 0.0; - x->x_inlet_time = time; - } - if(ticks < 1) - sigt3_line_tick(x); - else - clock_delay(x->x_clock, (double)ticks * x->x_ticks2ms); - } -} - -static void sigt3_line_ft1(t_sigt3_line *x, t_float time) -{ - if(time < 0.0) - time = 0.0; - x->x_inlet_time = (double)time; -} - -static void sigt3_line_stop(t_sigt3_line *x) -{ - clock_unset(x->x_clock); - x->x_cur_samps = x->x_dur_samps = x->x_transient = 0; - x->x_inc = x->x_inc64 = x->x_inlet_time = x->x_dst_time = 0.0; -} - -static void sigt3_line_dsp(t_sigt3_line *x, t_signal **sp) -{ - int i; - float val, *trans; - - if(sp[0]->s_n > x->x_n) - { - freebytes(x->x_beg, x->x_n*sizeof(float)); - x->x_n = (int)sp[0]->s_n; - x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); - } - else - x->x_n = (int)sp[0]->s_n; - i = x->x_n; - val = x->x_cur_val; - trans = x->x_beg; - while(i--) - *trans++ = val; - x->x_ms2samps = 0.001*(double)sp[0]->s_sr; - x->x_ticks2ms = (double)x->x_n / x->x_ms2samps; - dsp_add(sigt3_line_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void sigt3_line_free(t_sigt3_line *x) -{ - if(x->x_beg) - freebytes(x->x_beg, x->x_n*sizeof(float)); - clock_free(x->x_clock); -} - -static void *sigt3_line_new(t_floatarg init_val) -{ - t_sigt3_line *x = (t_sigt3_line *)pd_new(sigt3_line_class); - int i; - - x->x_n = (int)sys_getblksize(); - x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); - x->x_inlet_val = x->x_cur_val = x->x_dst_val = init_val; - x->x_t3_bang_samps = x->x_cur_samps = x->x_dur_samps = x->x_transient = 0; - x->x_inlet_time = x->x_dst_time = 0.0; - x->x_inc64 = x->x_inc = 0.0; - x->x_ms2samps = 0.001 * (double)sys_getsr(); - x->x_ticks2ms = (double)x->x_n / x->x_ms2samps; - x->x_clock = clock_new(x, (t_method)sigt3_line_tick); - outlet_new(&x->x_obj, &s_signal); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); - return (x); -} - -void sigt3_line_setup(void) -{ - sigt3_line_class = class_new(gensym("t3_line~"), (t_newmethod)sigt3_line_new, - (t_method)sigt3_line_free, sizeof(t_sigt3_line), 0, A_DEFFLOAT, 0); - class_addmethod(sigt3_line_class, (t_method)sigt3_line_dsp, gensym("dsp"), 0); - class_addmethod(sigt3_line_class, (t_method)sigt3_line_stop, gensym("stop"), 0); - class_addmethod(sigt3_line_class, (t_method)sigt3_line_ft1, gensym("ft1"), A_FLOAT, 0); - class_addlist(sigt3_line_class, (t_method)sigt3_line_list); - class_sethelpsymbol(sigt3_line_class, gensym("iemhelp/help-t3_line~")); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include + +/* -------------------------- t3_line~ ------------------------------ */ +static t_class *sigt3_line_class; + +typedef struct _sigt3_line +{ + t_object x_obj; + t_clock *x_clock; + float *x_beg; + double x_cur_val; + double x_dst_val; + double x_inlet_val; + double x_inc64; + double x_inc; + double x_ms2samps; + double x_ticks2ms; + double x_inlet_time; + double x_dst_time; + int x_cur_samps; + int x_dur_samps; + int x_n; + int x_t3_bang_samps; + int x_transient; +} t_sigt3_line; + +static void sigt3_line_nontransient(float *vec, t_sigt3_line *x, int n) +{ + int cur_samps = x->x_cur_samps, i; + double inc = x->x_inc; + double cur_val = x->x_cur_val; + + if(cur_samps) + { + if(cur_samps > n) + { + x->x_cur_samps -= n; + while(n--) + { + cur_val += inc; + *vec++ = (float)cur_val; + } + x->x_cur_val += x->x_inc64; + } + else if(cur_samps == n) + { + x->x_cur_samps = 0; + while(n--) + { + cur_val += inc; + *vec++ = (float)cur_val; + } + x->x_cur_val = x->x_dst_val; + } + else + { + for(i=0; ix_cur_val = cur_val = x->x_dst_val; + for(i=cur_samps; ix_cur_samps = 0; + } + } + else + { + while(n--) + *vec++ = (float)cur_val; + } +} + +static t_int *sigt3_line_perform(t_int *w) +{ + t_float *out = (t_float *)(w[1]); + t_sigt3_line *x = (t_sigt3_line *)(w[2]); + int n = (int)(w[3]); + + if(x->x_transient) + { + float *trans = x->x_beg; + + while(n--) + *out++ = *trans++; + x->x_transient = 0; + } + else + sigt3_line_nontransient(out, x, n); + return(w+4); +} + +static void sigt3_line_tick(t_sigt3_line *x) +{ + float *trans = x->x_beg; + int n = x->x_n, t3_bang_samps, cur_samps, i; + double inc, cur_val; + + if(!x->x_transient) + sigt3_line_nontransient(trans, x, n); + t3_bang_samps = x->x_t3_bang_samps; + x->x_dst_val = x->x_inlet_val; + if(x->x_inlet_time <= 0.0) + { + x->x_inlet_time = 0.0; + x->x_dst_time = 0.0; + x->x_dur_samps = 0; + x->x_cur_samps = 0; + cur_val = x->x_cur_val = x->x_dst_val; + for(i=t3_bang_samps; ix_dst_time = x->x_inlet_time; + x->x_inlet_time = 0.0; + cur_samps = (int)(x->x_dst_time * x->x_ms2samps); + if(!cur_samps) + cur_samps = 1; + x->x_dur_samps = cur_samps; + x->x_cur_samps = cur_samps; + cur_val = x->x_cur_val = (double)trans[t3_bang_samps]; + inc = x->x_inc = (x->x_dst_val - cur_val)/(double)cur_samps; + x->x_inc64 = (double)x->x_n * inc; + diff = n - t3_bang_samps; + if(cur_samps > diff) + { + for(i=t3_bang_samps; ix_cur_val += (double)diff * inc; + x->x_cur_samps -= diff; + } + else if(cur_samps == diff) + { + for(i=t3_bang_samps; ix_cur_val = x->x_dst_val; + x->x_cur_samps = 0; + } + else + { + end = t3_bang_samps + cur_samps; + for(i=t3_bang_samps; ix_cur_val = x->x_dst_val; + x->x_cur_samps = 0; + for(i=end; ix_transient = 1; +} + +static void sigt3_line_list(t_sigt3_line *x, t_symbol *s, int ac, t_atom *av) +{ + if((ac >= 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) + { + int t3_bang_samps, ticks; + double time; + + x->x_inlet_val = (double)atom_getfloatarg(1, ac, av); + t3_bang_samps = (int)((float)atom_getfloatarg(0, ac, av)*x->x_ms2samps); + if(t3_bang_samps < 0) + t3_bang_samps = 0; + ticks = t3_bang_samps / x->x_n; + x->x_t3_bang_samps = t3_bang_samps - x->x_n * ticks; + if((ac >= 3)&&IS_A_FLOAT(av,2)) + { + time = (double)atom_getfloatarg(2, ac, av); + if(time < 0.0) + time = 0.0; + x->x_inlet_time = time; + } + if(ticks < 1) + sigt3_line_tick(x); + else + clock_delay(x->x_clock, (double)ticks * x->x_ticks2ms); + } +} + +static void sigt3_line_ft1(t_sigt3_line *x, t_float time) +{ + if(time < 0.0) + time = 0.0; + x->x_inlet_time = (double)time; +} + +static void sigt3_line_stop(t_sigt3_line *x) +{ + clock_unset(x->x_clock); + x->x_cur_samps = x->x_dur_samps = x->x_transient = 0; + x->x_inc = x->x_inc64 = x->x_inlet_time = x->x_dst_time = 0.0; +} + +static void sigt3_line_dsp(t_sigt3_line *x, t_signal **sp) +{ + int i; + float val, *trans; + + if(sp[0]->s_n > x->x_n) + { + freebytes(x->x_beg, x->x_n*sizeof(float)); + x->x_n = (int)sp[0]->s_n; + x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); + } + else + x->x_n = (int)sp[0]->s_n; + i = x->x_n; + val = x->x_cur_val; + trans = x->x_beg; + while(i--) + *trans++ = val; + x->x_ms2samps = 0.001*(double)sp[0]->s_sr; + x->x_ticks2ms = (double)x->x_n / x->x_ms2samps; + dsp_add(sigt3_line_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void sigt3_line_free(t_sigt3_line *x) +{ + if(x->x_beg) + freebytes(x->x_beg, x->x_n*sizeof(float)); + clock_free(x->x_clock); +} + +static void *sigt3_line_new(t_floatarg init_val) +{ + t_sigt3_line *x = (t_sigt3_line *)pd_new(sigt3_line_class); + int i; + + x->x_n = (int)sys_getblksize(); + x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); + x->x_inlet_val = x->x_cur_val = x->x_dst_val = init_val; + x->x_t3_bang_samps = x->x_cur_samps = x->x_dur_samps = x->x_transient = 0; + x->x_inlet_time = x->x_dst_time = 0.0; + x->x_inc64 = x->x_inc = 0.0; + x->x_ms2samps = 0.001 * (double)sys_getsr(); + x->x_ticks2ms = (double)x->x_n / x->x_ms2samps; + x->x_clock = clock_new(x, (t_method)sigt3_line_tick); + outlet_new(&x->x_obj, &s_signal); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); + return (x); +} + +void sigt3_line_setup(void) +{ + sigt3_line_class = class_new(gensym("t3_line~"), (t_newmethod)sigt3_line_new, + (t_method)sigt3_line_free, sizeof(t_sigt3_line), 0, A_DEFFLOAT, 0); + class_addmethod(sigt3_line_class, (t_method)sigt3_line_dsp, gensym("dsp"), 0); + class_addmethod(sigt3_line_class, (t_method)sigt3_line_stop, gensym("stop"), 0); + class_addmethod(sigt3_line_class, (t_method)sigt3_line_ft1, gensym("ft1"), A_FLOAT, 0); + class_addlist(sigt3_line_class, (t_method)sigt3_line_list); + class_sethelpsymbol(sigt3_line_class, gensym("iemhelp/help-t3_line~")); +} diff --git a/src/iem_t3_lib/sigt3_sig.c b/src/iem_t3_lib/sigt3_sig.c index fcfedee..27dc01d 100644 --- a/src/iem_t3_lib/sigt3_sig.c +++ b/src/iem_t3_lib/sigt3_sig.c @@ -1,200 +1,200 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include - -/* -------------------------- sigt3_sig~ ------------------------------ */ -static t_class *sigt3_sig_class; - -typedef struct _sigt3_sig -{ - t_object x_obj; - t_clock *x_clock; - float x_old_val; - float x_new_val; - float *x_beg; - int x_n; - int x_t3_bang_samps; - int x_transient; - float x_ms2samps; - float x_ticks2ms; -} t_sigt3_sig; - -static void sigt3_sig_tick(t_sigt3_sig *x) -{ - float *trans = x->x_beg, val; - int n = x->x_n, t3_bang_samps, i; - - t3_bang_samps = x->x_t3_bang_samps; - if(!x->x_transient) - { - val = x->x_old_val; - for(i=0; ix_transient = 1; - } - val = x->x_old_val = x->x_new_val; - for(i=t3_bang_samps; ix_clock); - x->x_new_val = x->x_old_val; -} - -static void sigt3_sig_list(t_sigt3_sig *x, t_symbol *s, int ac, t_atom *av) -{ - if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) - { - int n = x->x_n, t3_bang_samps, ticks; - - t3_bang_samps = (int)((float)atom_getfloatarg(0, ac, av)*x->x_ms2samps); - x->x_new_val = (float)atom_getfloatarg(1, ac, av); - if(t3_bang_samps < 0) - t3_bang_samps = 0; - ticks = t3_bang_samps / n; - x->x_t3_bang_samps = t3_bang_samps - n*ticks; - if(ticks < 1) - sigt3_sig_tick(x); - else - clock_delay(x->x_clock, (double)ticks * (double)x->x_ticks2ms); - } -} - -static t_int *sigt3_sig_perform(t_int *w) -{ - t_float *out = (t_float *)(w[1]); - t_sigt3_sig *x = (t_sigt3_sig *)(w[2]); - int n = (int)(w[3]); - - if(x->x_transient) - { - float *trans = x->x_beg; - - while(n--) - *out++ = *trans++; - x->x_transient = 0; - } - else - { - float val = x->x_new_val; - - while(n--) - *out++ = val; - } - return (w+4); -} - -static t_int *sigt3_sig_perf8(t_int *w) -{ - t_float *out = (t_float *)(w[1]); - t_sigt3_sig *x = (t_sigt3_sig *)(w[2]); - int n = (int)(w[3]), i; - - if(x->x_transient) - { - float *trans = x->x_beg; - - for(i=0; ix_transient = 0; - } - else - { - float val = x->x_new_val; - - for(i=0; is_n > x->x_n) - { - freebytes(x->x_beg, x->x_n*sizeof(float)); - x->x_n = sp[0]->s_n; - x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); - } - else - x->x_n = sp[0]->s_n; - x->x_ms2samps = 0.001*(float)sp[0]->s_sr; - x->x_ticks2ms = (float)x->x_n / x->x_ms2samps; - i = x->x_n; - val = x->x_new_val; - trans = x->x_beg; - while(i--) - *trans++ = val; - - if((sp[0]->s_n)&7) - dsp_add(sigt3_sig_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); - else - dsp_add(sigt3_sig_perf8, 3, sp[0]->s_vec, x, sp[0]->s_n); -} - -static void sigt3_sig_free(t_sigt3_sig *x) -{ - if(x->x_beg) - freebytes(x->x_beg, x->x_n*sizeof(float)); - clock_free(x->x_clock); -} - -static void *sigt3_sig_new(t_floatarg init_val) -{ - t_sigt3_sig *x = (t_sigt3_sig *)pd_new(sigt3_sig_class); - - x->x_new_val = x->x_old_val = init_val; - x->x_n = (int)sys_getblksize(); - x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); - x->x_t3_bang_samps = x->x_transient = 0; - x->x_ms2samps = 0.001 * (float)sys_getsr(); - x->x_ticks2ms = (float)x->x_n / x->x_ms2samps; - x->x_clock = clock_new(x, (t_method)sigt3_sig_tick); - outlet_new(&x->x_obj, &s_signal); - return (x); -} - -void sigt3_sig_setup(void) -{ - sigt3_sig_class = class_new(gensym("t3_sig~"), (t_newmethod)sigt3_sig_new, - (t_method)sigt3_sig_free, sizeof(t_sigt3_sig), 0, A_DEFFLOAT, 0); - class_addmethod(sigt3_sig_class, (t_method)sigt3_sig_dsp, gensym("dsp"), 0); - class_addmethod(sigt3_sig_class, (t_method)sigt3_sig_stop, gensym("stop"), 0); - class_addlist(sigt3_sig_class, (t_method)sigt3_sig_list); - class_sethelpsymbol(sigt3_sig_class, gensym("iemhelp/help-t3_sig~")); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include + +/* -------------------------- sigt3_sig~ ------------------------------ */ +static t_class *sigt3_sig_class; + +typedef struct _sigt3_sig +{ + t_object x_obj; + t_clock *x_clock; + float x_old_val; + float x_new_val; + float *x_beg; + int x_n; + int x_t3_bang_samps; + int x_transient; + float x_ms2samps; + float x_ticks2ms; +} t_sigt3_sig; + +static void sigt3_sig_tick(t_sigt3_sig *x) +{ + float *trans = x->x_beg, val; + int n = x->x_n, t3_bang_samps, i; + + t3_bang_samps = x->x_t3_bang_samps; + if(!x->x_transient) + { + val = x->x_old_val; + for(i=0; ix_transient = 1; + } + val = x->x_old_val = x->x_new_val; + for(i=t3_bang_samps; ix_clock); + x->x_new_val = x->x_old_val; +} + +static void sigt3_sig_list(t_sigt3_sig *x, t_symbol *s, int ac, t_atom *av) +{ + if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) + { + int n = x->x_n, t3_bang_samps, ticks; + + t3_bang_samps = (int)((float)atom_getfloatarg(0, ac, av)*x->x_ms2samps); + x->x_new_val = (float)atom_getfloatarg(1, ac, av); + if(t3_bang_samps < 0) + t3_bang_samps = 0; + ticks = t3_bang_samps / n; + x->x_t3_bang_samps = t3_bang_samps - n*ticks; + if(ticks < 1) + sigt3_sig_tick(x); + else + clock_delay(x->x_clock, (double)ticks * (double)x->x_ticks2ms); + } +} + +static t_int *sigt3_sig_perform(t_int *w) +{ + t_float *out = (t_float *)(w[1]); + t_sigt3_sig *x = (t_sigt3_sig *)(w[2]); + int n = (int)(w[3]); + + if(x->x_transient) + { + float *trans = x->x_beg; + + while(n--) + *out++ = *trans++; + x->x_transient = 0; + } + else + { + float val = x->x_new_val; + + while(n--) + *out++ = val; + } + return (w+4); +} + +static t_int *sigt3_sig_perf8(t_int *w) +{ + t_float *out = (t_float *)(w[1]); + t_sigt3_sig *x = (t_sigt3_sig *)(w[2]); + int n = (int)(w[3]), i; + + if(x->x_transient) + { + float *trans = x->x_beg; + + for(i=0; ix_transient = 0; + } + else + { + float val = x->x_new_val; + + for(i=0; is_n > x->x_n) + { + freebytes(x->x_beg, x->x_n*sizeof(float)); + x->x_n = sp[0]->s_n; + x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); + } + else + x->x_n = sp[0]->s_n; + x->x_ms2samps = 0.001*(float)sp[0]->s_sr; + x->x_ticks2ms = (float)x->x_n / x->x_ms2samps; + i = x->x_n; + val = x->x_new_val; + trans = x->x_beg; + while(i--) + *trans++ = val; + + if((sp[0]->s_n)&7) + dsp_add(sigt3_sig_perform, 3, sp[0]->s_vec, x, sp[0]->s_n); + else + dsp_add(sigt3_sig_perf8, 3, sp[0]->s_vec, x, sp[0]->s_n); +} + +static void sigt3_sig_free(t_sigt3_sig *x) +{ + if(x->x_beg) + freebytes(x->x_beg, x->x_n*sizeof(float)); + clock_free(x->x_clock); +} + +static void *sigt3_sig_new(t_floatarg init_val) +{ + t_sigt3_sig *x = (t_sigt3_sig *)pd_new(sigt3_sig_class); + + x->x_new_val = x->x_old_val = init_val; + x->x_n = (int)sys_getblksize(); + x->x_beg = (float *)getbytes(x->x_n*sizeof(float)); + x->x_t3_bang_samps = x->x_transient = 0; + x->x_ms2samps = 0.001 * (float)sys_getsr(); + x->x_ticks2ms = (float)x->x_n / x->x_ms2samps; + x->x_clock = clock_new(x, (t_method)sigt3_sig_tick); + outlet_new(&x->x_obj, &s_signal); + return (x); +} + +void sigt3_sig_setup(void) +{ + sigt3_sig_class = class_new(gensym("t3_sig~"), (t_newmethod)sigt3_sig_new, + (t_method)sigt3_sig_free, sizeof(t_sigt3_sig), 0, A_DEFFLOAT, 0); + class_addmethod(sigt3_sig_class, (t_method)sigt3_sig_dsp, gensym("dsp"), 0); + class_addmethod(sigt3_sig_class, (t_method)sigt3_sig_stop, gensym("stop"), 0); + class_addlist(sigt3_sig_class, (t_method)sigt3_sig_list); + class_sethelpsymbol(sigt3_sig_class, gensym("iemhelp/help-t3_sig~")); +} diff --git a/src/iem_t3_lib/t3_bpe.c b/src/iem_t3_lib/t3_bpe.c index 24c61f9..2aa7846 100644 --- a/src/iem_t3_lib/t3_bpe.c +++ b/src/iem_t3_lib/t3_bpe.c @@ -1,141 +1,141 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include - -/* ------------------------ t3_bpe ---------------------------- */ -static t_class *t3_bpe_class; - -typedef struct _t3_bpe -{ - t_object x_obj; - t_atom x_at[2]; - t_clock *x_clock; - int x_maxnum; - int x_curnum; - int x_curindex; - t_atom *x_beg; - double x_t3_bang; - double x_ticks2ms; - int x_hit; - void *x_out_val; - void *x_out_time; - void *x_out_finished; -} t_t3_bpe; - -static void t3_bpe_stop(t_t3_bpe *x) -{ - clock_unset(x->x_clock); -} - -static void t3_bpe_tick(t_t3_bpe *x) -{ - t_atom *vec = x->x_beg; - float val; - double dticks, time; - int iticks; - - if(x->x_curindex >= x->x_curnum) - { - t3_bpe_stop(x); - outlet_float(x->x_out_finished, x->x_t3_bang); - } - else - { - x->x_hit = 0; - vec += x->x_curindex; - val = atom_getfloat(vec++); - time = (double)atom_getfloat(vec); - outlet_float(x->x_out_time, (float)time); - x->x_at[1].a_w.w_float = val; - x->x_at[0].a_w.w_float = x->x_t3_bang; - outlet_list(x->x_obj.ob_outlet, &s_list, 2, x->x_at); - dticks = (time + x->x_t3_bang)/x->x_ticks2ms; - iticks = (int)dticks; - x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; - if(!x->x_hit) - clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); - x->x_curindex += 2; - } -} - -static void t3_bpe_float(t_t3_bpe *x, t_floatarg f) -{ - double dticks; - int iticks; - - if(x->x_curnum) - { - x->x_curindex = 0; - dticks = (double)f/x->x_ticks2ms; - iticks = (int)dticks; - x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; - clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); - x->x_hit = 1; - } -} - -static void t3_bpe_list(t_t3_bpe *x, t_symbol *s, int ac, t_atom *av) -{ - int n = ac & 0xfffffffe, i; - t_atom *vec = x->x_beg; - if(n > x->x_maxnum) - { - freebytes(x->x_beg, x->x_maxnum*sizeof(t_atom)); - x->x_maxnum = 2 + n; - x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom)); - vec = x->x_beg; - } - x->x_curnum = n; - for(i=0; ix_beg, x->x_maxnum*sizeof(t_atom)); - clock_free(x->x_clock); -} - -static void *t3_bpe_new(void) -{ - t_t3_bpe *x = (t_t3_bpe *)pd_new(t3_bpe_class); - - x->x_t3_bang = 0.0; - x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr(); - x->x_curindex = 0; - x->x_maxnum = 20; - x->x_curnum = 0; - x->x_hit = 0; - x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom)); - x->x_clock = clock_new(x, (t_method)t3_bpe_tick); - outlet_new(&x->x_obj, &s_list); - x->x_out_time = outlet_new(&x->x_obj, &s_float); - x->x_out_finished = outlet_new(&x->x_obj, &s_float); - x->x_at[0].a_type = A_FLOAT; - x->x_at[1].a_type = A_FLOAT; - return (x); -} - -void t3_bpe_setup(void) -{ - t3_bpe_class = class_new(gensym("t3_bpe"), (t_newmethod)t3_bpe_new, - (t_method)t3_bpe_free, sizeof(t_t3_bpe), 0, 0); - class_addmethod(t3_bpe_class, (t_method)t3_bpe_stop, gensym("stop"), 0); - class_addfloat(t3_bpe_class, (t_method)t3_bpe_float); - class_addlist(t3_bpe_class, (t_method)t3_bpe_list); - class_sethelpsymbol(t3_bpe_class, gensym("iemhelp/help-t3_bpe")); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include + +/* ------------------------ t3_bpe ---------------------------- */ +static t_class *t3_bpe_class; + +typedef struct _t3_bpe +{ + t_object x_obj; + t_atom x_at[2]; + t_clock *x_clock; + int x_maxnum; + int x_curnum; + int x_curindex; + t_atom *x_beg; + double x_t3_bang; + double x_ticks2ms; + int x_hit; + void *x_out_val; + void *x_out_time; + void *x_out_finished; +} t_t3_bpe; + +static void t3_bpe_stop(t_t3_bpe *x) +{ + clock_unset(x->x_clock); +} + +static void t3_bpe_tick(t_t3_bpe *x) +{ + t_atom *vec = x->x_beg; + float val; + double dticks, time; + int iticks; + + if(x->x_curindex >= x->x_curnum) + { + t3_bpe_stop(x); + outlet_float(x->x_out_finished, x->x_t3_bang); + } + else + { + x->x_hit = 0; + vec += x->x_curindex; + val = atom_getfloat(vec++); + time = (double)atom_getfloat(vec); + outlet_float(x->x_out_time, (float)time); + x->x_at[1].a_w.w_float = val; + x->x_at[0].a_w.w_float = x->x_t3_bang; + outlet_list(x->x_obj.ob_outlet, &s_list, 2, x->x_at); + dticks = (time + x->x_t3_bang)/x->x_ticks2ms; + iticks = (int)dticks; + x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; + if(!x->x_hit) + clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); + x->x_curindex += 2; + } +} + +static void t3_bpe_float(t_t3_bpe *x, t_floatarg f) +{ + double dticks; + int iticks; + + if(x->x_curnum) + { + x->x_curindex = 0; + dticks = (double)f/x->x_ticks2ms; + iticks = (int)dticks; + x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; + clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); + x->x_hit = 1; + } +} + +static void t3_bpe_list(t_t3_bpe *x, t_symbol *s, int ac, t_atom *av) +{ + int n = ac & 0xfffffffe, i; + t_atom *vec = x->x_beg; + if(n > x->x_maxnum) + { + freebytes(x->x_beg, x->x_maxnum*sizeof(t_atom)); + x->x_maxnum = 2 + n; + x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom)); + vec = x->x_beg; + } + x->x_curnum = n; + for(i=0; ix_beg, x->x_maxnum*sizeof(t_atom)); + clock_free(x->x_clock); +} + +static void *t3_bpe_new(void) +{ + t_t3_bpe *x = (t_t3_bpe *)pd_new(t3_bpe_class); + + x->x_t3_bang = 0.0; + x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr(); + x->x_curindex = 0; + x->x_maxnum = 20; + x->x_curnum = 0; + x->x_hit = 0; + x->x_beg = (t_atom *)getbytes(x->x_maxnum*sizeof(t_atom)); + x->x_clock = clock_new(x, (t_method)t3_bpe_tick); + outlet_new(&x->x_obj, &s_list); + x->x_out_time = outlet_new(&x->x_obj, &s_float); + x->x_out_finished = outlet_new(&x->x_obj, &s_float); + x->x_at[0].a_type = A_FLOAT; + x->x_at[1].a_type = A_FLOAT; + return (x); +} + +void t3_bpe_setup(void) +{ + t3_bpe_class = class_new(gensym("t3_bpe"), (t_newmethod)t3_bpe_new, + (t_method)t3_bpe_free, sizeof(t_t3_bpe), 0, 0); + class_addmethod(t3_bpe_class, (t_method)t3_bpe_stop, gensym("stop"), 0); + class_addfloat(t3_bpe_class, (t_method)t3_bpe_float); + class_addlist(t3_bpe_class, (t_method)t3_bpe_list); + class_sethelpsymbol(t3_bpe_class, gensym("iemhelp/help-t3_bpe")); +} diff --git a/src/iem_t3_lib/t3_delay.c b/src/iem_t3_lib/t3_delay.c index da7dd06..0298832 100644 --- a/src/iem_t3_lib/t3_delay.c +++ b/src/iem_t3_lib/t3_delay.c @@ -1,96 +1,96 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include - -/* ------------------------ t3_delay ---------------------------- */ -static t_class *t3_delay_class; - -typedef struct _t3_delay -{ - t_object x_obj; - t_clock *x_clock; - double x_deltime; - double x_ticks2ms; - double x_t3_bang; -} t_t3_delay; - -static void t3_delay_tick(t_t3_delay *x) -{ - outlet_float(x->x_obj.ob_outlet, x->x_t3_bang); -} - -static void t3_delay_stop(t_t3_delay *x) -{ - clock_unset(x->x_clock); -} - -static void t3_delay_float(t_t3_delay *x, t_floatarg t3_bang) -{ - double dticks; - int iticks; - - if(t3_bang < 0) - t3_bang = 0; - dticks = (x->x_deltime + (double)t3_bang)/x->x_ticks2ms; - iticks = (int)dticks; - x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; - clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); -} - -static void t3_delay_ft1(t_t3_delay *x, t_floatarg f) -{ - if(f < 0) - f = 0; - x->x_deltime = f; -} - -static void t3_delay_list(t_t3_delay *x, t_symbol *s, int ac, t_atom *av) -{ - if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) - { - t3_delay_ft1(x, atom_getfloatarg(1, ac, av)); - t3_delay_float(x, atom_getfloatarg(0, ac, av)); - } -} - -static void t3_delay_free(t_t3_delay *x) -{ - clock_free(x->x_clock); -} - -static void *t3_delay_new(t_floatarg f) -{ - t_t3_delay *x = (t_t3_delay *)pd_new(t3_delay_class); - - x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr(); - t3_delay_ft1(x, f); - x->x_clock = clock_new(x, (t_method)t3_delay_tick); - outlet_new(&x->x_obj, &s_float); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); - return (x); -} - -void t3_delay_setup(void) -{ - t3_delay_class = class_new(gensym("t3_delay"), (t_newmethod)t3_delay_new, - (t_method)t3_delay_free, sizeof(t_t3_delay), 0, A_DEFFLOAT, 0); - class_addcreator((t_newmethod)t3_delay_new, gensym("t3_del"), A_DEFFLOAT, 0); - class_addmethod(t3_delay_class, (t_method)t3_delay_stop, gensym("stop"), 0); - class_addmethod(t3_delay_class, (t_method)t3_delay_ft1, - gensym("ft1"), A_FLOAT, 0); - class_addfloat(t3_delay_class, (t_method)t3_delay_float); - class_addlist(t3_delay_class, (t_method)t3_delay_list); - class_sethelpsymbol(t3_delay_class, gensym("iemhelp/help-t3_delay")); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include + +/* ------------------------ t3_delay ---------------------------- */ +static t_class *t3_delay_class; + +typedef struct _t3_delay +{ + t_object x_obj; + t_clock *x_clock; + double x_deltime; + double x_ticks2ms; + double x_t3_bang; +} t_t3_delay; + +static void t3_delay_tick(t_t3_delay *x) +{ + outlet_float(x->x_obj.ob_outlet, x->x_t3_bang); +} + +static void t3_delay_stop(t_t3_delay *x) +{ + clock_unset(x->x_clock); +} + +static void t3_delay_float(t_t3_delay *x, t_floatarg t3_bang) +{ + double dticks; + int iticks; + + if(t3_bang < 0) + t3_bang = 0; + dticks = (x->x_deltime + (double)t3_bang)/x->x_ticks2ms; + iticks = (int)dticks; + x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; + clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); +} + +static void t3_delay_ft1(t_t3_delay *x, t_floatarg f) +{ + if(f < 0) + f = 0; + x->x_deltime = f; +} + +static void t3_delay_list(t_t3_delay *x, t_symbol *s, int ac, t_atom *av) +{ + if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) + { + t3_delay_ft1(x, atom_getfloatarg(1, ac, av)); + t3_delay_float(x, atom_getfloatarg(0, ac, av)); + } +} + +static void t3_delay_free(t_t3_delay *x) +{ + clock_free(x->x_clock); +} + +static void *t3_delay_new(t_floatarg f) +{ + t_t3_delay *x = (t_t3_delay *)pd_new(t3_delay_class); + + x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr(); + t3_delay_ft1(x, f); + x->x_clock = clock_new(x, (t_method)t3_delay_tick); + outlet_new(&x->x_obj, &s_float); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); + return (x); +} + +void t3_delay_setup(void) +{ + t3_delay_class = class_new(gensym("t3_delay"), (t_newmethod)t3_delay_new, + (t_method)t3_delay_free, sizeof(t_t3_delay), 0, A_DEFFLOAT, 0); + class_addcreator((t_newmethod)t3_delay_new, gensym("t3_del"), A_DEFFLOAT, 0); + class_addmethod(t3_delay_class, (t_method)t3_delay_stop, gensym("stop"), 0); + class_addmethod(t3_delay_class, (t_method)t3_delay_ft1, + gensym("ft1"), A_FLOAT, 0); + class_addfloat(t3_delay_class, (t_method)t3_delay_float); + class_addlist(t3_delay_class, (t_method)t3_delay_list); + class_sethelpsymbol(t3_delay_class, gensym("iemhelp/help-t3_delay")); +} diff --git a/src/iem_t3_lib/t3_metro.c b/src/iem_t3_lib/t3_metro.c index 8dcdb61..d71c54a 100644 --- a/src/iem_t3_lib/t3_metro.c +++ b/src/iem_t3_lib/t3_metro.c @@ -1,120 +1,120 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include - -/* ------------------------ t3_metro ---------------------------- */ -static t_class *t3_metro_class; - -typedef struct _t3_metro -{ - t_object x_obj; - t_clock *x_clock; - double x_metrotime; - double x_ticks2ms; - double x_t3_bang; - int x_hit; - void *x_out_next; -} t_t3_metro; - -static void t3_metro_stop(t_t3_metro *x) -{ - clock_unset(x->x_clock); -} - -static void t3_metro_tick(t_t3_metro *x) -{ - double dticks; - int iticks; - - x->x_hit = 0; - outlet_float(x->x_out_next, x->x_metrotime); - outlet_float(x->x_obj.ob_outlet, x->x_t3_bang); - dticks = (x->x_metrotime + x->x_t3_bang)/x->x_ticks2ms; - iticks = (int)dticks; - x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; - if(!x->x_hit) - clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); -} - -static void t3_metro_float(t_t3_metro *x, t_floatarg t3_bang) -{ - double dticks; - int iticks; - - if(t3_bang < 0) - t3_bang = 0; - dticks = (double)t3_bang/x->x_ticks2ms; - iticks = (int)dticks; - x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; - clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); - x->x_hit = 1; -} - -static void t3_metro_start(t_t3_metro *x, t_floatarg f) -{ - t3_metro_float(x, f); - x->x_hit = 1; -} - -static void t3_metro_ft1(t_t3_metro *x, t_floatarg f) -{ - if(f < 0.01) f = 0.01; - x->x_metrotime = (double)f; -} - -static void t3_metro_list(t_t3_metro *x, t_symbol *s, int ac, t_atom *av) -{ - if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) - { - t3_metro_ft1(x, atom_getfloatarg(1, ac, av)); - t3_metro_float(x, atom_getfloatarg(0, ac, av)); - } -} - -static void t3_metro_free(t_t3_metro *x) -{ - clock_free(x->x_clock); -} - -static void *t3_metro_new(t_symbol *s, int ac, t_atom *av) -{ - t_t3_metro *x = (t_t3_metro *)pd_new(t3_metro_class); - - x->x_metrotime = 10.0; - x->x_t3_bang = 0.0; - x->x_hit = 0; - if((ac == 1)&&IS_A_FLOAT(av,0)) - { - t3_metro_ft1(x, atom_getfloatarg(0, ac, av)); - } - x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr(); - x->x_clock = clock_new(x, (t_method)t3_metro_tick); - outlet_new(&x->x_obj, &s_float); - x->x_out_next = outlet_new(&x->x_obj, &s_float); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); - return (x); -} - -void t3_metro_setup(void) -{ - t3_metro_class = class_new(gensym("t3_metro"), (t_newmethod)t3_metro_new, - (t_method)t3_metro_free, sizeof(t_t3_metro), 0, A_GIMME, 0); - class_addmethod(t3_metro_class, (t_method)t3_metro_stop, gensym("stop"), 0); - class_addmethod(t3_metro_class, (t_method)t3_metro_start, gensym("start"), A_FLOAT, 0); - class_addmethod(t3_metro_class, (t_method)t3_metro_ft1, gensym("ft1"), A_FLOAT, 0); - class_addfloat(t3_metro_class, (t_method)t3_metro_float); - class_addlist(t3_metro_class, (t_method)t3_metro_list); - class_sethelpsymbol(t3_metro_class, gensym("iemhelp/help-t3_metro")); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include + +/* ------------------------ t3_metro ---------------------------- */ +static t_class *t3_metro_class; + +typedef struct _t3_metro +{ + t_object x_obj; + t_clock *x_clock; + double x_metrotime; + double x_ticks2ms; + double x_t3_bang; + int x_hit; + void *x_out_next; +} t_t3_metro; + +static void t3_metro_stop(t_t3_metro *x) +{ + clock_unset(x->x_clock); +} + +static void t3_metro_tick(t_t3_metro *x) +{ + double dticks; + int iticks; + + x->x_hit = 0; + outlet_float(x->x_out_next, x->x_metrotime); + outlet_float(x->x_obj.ob_outlet, x->x_t3_bang); + dticks = (x->x_metrotime + x->x_t3_bang)/x->x_ticks2ms; + iticks = (int)dticks; + x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; + if(!x->x_hit) + clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); +} + +static void t3_metro_float(t_t3_metro *x, t_floatarg t3_bang) +{ + double dticks; + int iticks; + + if(t3_bang < 0) + t3_bang = 0; + dticks = (double)t3_bang/x->x_ticks2ms; + iticks = (int)dticks; + x->x_t3_bang = (dticks - (double)iticks)*x->x_ticks2ms; + clock_delay(x->x_clock, (double)iticks*x->x_ticks2ms); + x->x_hit = 1; +} + +static void t3_metro_start(t_t3_metro *x, t_floatarg f) +{ + t3_metro_float(x, f); + x->x_hit = 1; +} + +static void t3_metro_ft1(t_t3_metro *x, t_floatarg f) +{ + if(f < 0.01) f = 0.01; + x->x_metrotime = (double)f; +} + +static void t3_metro_list(t_t3_metro *x, t_symbol *s, int ac, t_atom *av) +{ + if((ac == 2)&&IS_A_FLOAT(av,0)&&IS_A_FLOAT(av,1)) + { + t3_metro_ft1(x, atom_getfloatarg(1, ac, av)); + t3_metro_float(x, atom_getfloatarg(0, ac, av)); + } +} + +static void t3_metro_free(t_t3_metro *x) +{ + clock_free(x->x_clock); +} + +static void *t3_metro_new(t_symbol *s, int ac, t_atom *av) +{ + t_t3_metro *x = (t_t3_metro *)pd_new(t3_metro_class); + + x->x_metrotime = 10.0; + x->x_t3_bang = 0.0; + x->x_hit = 0; + if((ac == 1)&&IS_A_FLOAT(av,0)) + { + t3_metro_ft1(x, atom_getfloatarg(0, ac, av)); + } + x->x_ticks2ms = 1000.0*(double)sys_getblksize()/(double)sys_getsr(); + x->x_clock = clock_new(x, (t_method)t3_metro_tick); + outlet_new(&x->x_obj, &s_float); + x->x_out_next = outlet_new(&x->x_obj, &s_float); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1")); + return (x); +} + +void t3_metro_setup(void) +{ + t3_metro_class = class_new(gensym("t3_metro"), (t_newmethod)t3_metro_new, + (t_method)t3_metro_free, sizeof(t_t3_metro), 0, A_GIMME, 0); + class_addmethod(t3_metro_class, (t_method)t3_metro_stop, gensym("stop"), 0); + class_addmethod(t3_metro_class, (t_method)t3_metro_start, gensym("start"), A_FLOAT, 0); + class_addmethod(t3_metro_class, (t_method)t3_metro_ft1, gensym("ft1"), A_FLOAT, 0); + class_addfloat(t3_metro_class, (t_method)t3_metro_float); + class_addlist(t3_metro_class, (t_method)t3_metro_list); + class_sethelpsymbol(t3_metro_class, gensym("iemhelp/help-t3_metro")); +} diff --git a/src/iem_t3_lib/t3_timer.c b/src/iem_t3_lib/t3_timer.c index c6dc392..5f0bc3a 100644 --- a/src/iem_t3_lib/t3_timer.c +++ b/src/iem_t3_lib/t3_timer.c @@ -1,55 +1,55 @@ -/* For information on usage and redistribution, and for a DISCLAIMER OF ALL -* WARRANTIES, see the file, "LICENSE.txt," in this distribution. - -iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ - -#ifdef NT -#pragma warning( disable : 4244 ) -#pragma warning( disable : 4305 ) -#endif - -#include "m_pd.h" -#include "iemlib.h" -#include -#include -#include - -/* -------------------------- t3_timer ------------------------------ */ -static t_class *t3_timer_class; - -typedef struct _t3_timer -{ - t_object x_obj; - double x_settime; - double x_t3_off; -} t_t3_timer; - -static void t3_timer_float(t_t3_timer *x, t_float t3_bang) -{ - x->x_settime = (double)clock_getsystime(); - x->x_t3_off = (double)t3_bang; -} - -static void t3_timer_ft1(t_t3_timer *x, t_float t3_bang) -{ - outlet_float(x->x_obj.ob_outlet, clock_gettimesince(x->x_settime) - + (double)t3_bang - x->x_t3_off); -} - -static void *t3_timer_new(void) -{ - t_t3_timer *x = (t_t3_timer *)pd_new(t3_timer_class); - t3_timer_float(x, 0.0); - outlet_new(&x->x_obj, &s_float); - inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); - return (x); -} - -void t3_timer_setup(void) -{ - t3_timer_class = class_new(gensym("t3_timer"), (t_newmethod)t3_timer_new, 0, - sizeof(t_t3_timer), 0, 0); - class_addfloat(t3_timer_class, t3_timer_float); - class_addmethod(t3_timer_class, (t_method)t3_timer_ft1, gensym("ft1"), A_FLOAT, 0); - class_sethelpsymbol(t3_timer_class, gensym("iemhelp/help-t3_timer")); -} +/* For information on usage and redistribution, and for a DISCLAIMER OF ALL +* WARRANTIES, see the file, "LICENSE.txt," in this distribution. + +iem_t3_lib written by Gerhard Eckel, Thomas Musil, Copyright (c) IEM KUG Graz Austria 2000 - 2005 */ + +#ifdef NT +#pragma warning( disable : 4244 ) +#pragma warning( disable : 4305 ) +#endif + +#include "m_pd.h" +#include "iemlib.h" +#include +#include +#include + +/* -------------------------- t3_timer ------------------------------ */ +static t_class *t3_timer_class; + +typedef struct _t3_timer +{ + t_object x_obj; + double x_settime; + double x_t3_off; +} t_t3_timer; + +static void t3_timer_float(t_t3_timer *x, t_float t3_bang) +{ + x->x_settime = (double)clock_getsystime(); + x->x_t3_off = (double)t3_bang; +} + +static void t3_timer_ft1(t_t3_timer *x, t_float t3_bang) +{ + outlet_float(x->x_obj.ob_outlet, clock_gettimesince(x->x_settime) + + (double)t3_bang - x->x_t3_off); +} + +static void *t3_timer_new(void) +{ + t_t3_timer *x = (t_t3_timer *)pd_new(t3_timer_class); + t3_timer_float(x, 0.0); + outlet_new(&x->x_obj, &s_float); + inlet_new(&x->x_obj, &x->x_obj.ob_pd, &s_float, gensym("ft1")); + return (x); +} + +void t3_timer_setup(void) +{ + t3_timer_class = class_new(gensym("t3_timer"), (t_newmethod)t3_timer_new, 0, + sizeof(t_t3_timer), 0, 0); + class_addfloat(t3_timer_class, t3_timer_float); + class_addmethod(t3_timer_class, (t_method)t3_timer_ft1, gensym("ft1"), A_FLOAT, 0); + class_sethelpsymbol(t3_timer_class, gensym("iemhelp/help-t3_timer")); +} diff --git a/src/iemlib2/makefile_win b/src/iemlib2/makefile_win index e1cd6ae..1dc3bf7 100644 --- a/src/iemlib2/makefile_win +++ b/src/iemlib2/makefile_win @@ -63,7 +63,6 @@ SRC = add2_comma.c \ OBJ = $(SRC:.c=.obj) .c.obj: - cl $(PD_WIN_C_FLAGS) $(PD_WIN_INCLUDE_PATH) /c $*.c ..\..\lib\iemlib2.dll: $(OBJ) -- cgit v1.2.1