#include #include #include #include #include "mp3play.h" static long rates[3][3] = { { 32000,44100,48000 } , { 16000,22050,24000 } , { 8000,11025,12000 } }; int supported_rates = 0; int outmode = DECODE_AUDIO; int songchoice = 0; char *listname = NULL; long outscale = 32768; int checkrange = FALSE; int tryresync = TRUE; int verbose = 0; int force_8bit = 0; int force_frequency = -1; long startFrame= 0; int frontend_type = 0; int remote = 0; int buffer_fd[2]; const char* fname = NULL; static char remote_buffer[1024]; static struct frame fr; static struct audio_info_struct ai; static Glxf_pane pane; /* X-OpenGL integration */ FD_Interface *form; /* global form */ void init_output(void) { if (!(pcm_sample = (unsigned char *) malloc(audiobufsize * 2))) { perror ("malloc()"); exit (1); } if(audio_open(&ai) < 0) { perror("audio"); exit(1); } } /* * Change the playback sample rate. */ static void reset_audio_samplerate(void) { /* close and re-open in order to flush * the device's internal buffer before * changing the sample rate. [OF] */ audio_close (&ai); if (audio_open(&ai) < 0) { perror("audio"); exit(1); } } /* * play a frame read read_frame(); * (re)initialize audio if necessary. */ void play_frame(int init,struct frame *fr) { int clip; if(fr->header_change || init) { int reset_audio = 0; if (init) if (verbose) print_header(fr); else print_header_compact(fr); if(force_frequency < 0) { if(ai.rate != freqs[fr->sampling_frequency]>>(fr->down_sample)) { ai.rate = freqs[fr->sampling_frequency]>>(fr->down_sample); reset_audio = 1; } } else if(ai.rate != force_frequency) { ai.rate = force_frequency; reset_audio = 1; } if (init) init_output(); if(reset_audio) reset_audio_samplerate(); } if (fr->error_protection) { getbits(16); /* get the crc bits out*/ } clip = (fr->do_layer)(fr,outmode,&ai); if(clip > 0 && checkrange) fprintf(stderr,"%d samples clipped\n", clip); } void handle_file(void) { int init; unsigned long frameNum = 0; int result=0; char* msg = NULL; int max=550; if (!*fname) fname = NULL; if(!fname){ fprintf(stderr, "No File Entered ...\n"); return; } if (open_stream(fname,-1)==-1) return; fprintf(stderr, "\nPlaying MPEG stream from %s ...\n\nHeader Information:\n", fname); /* gettimeofday (&start_time, NULL);*/ read_frame_init(); init = 1; fl_set_slider_bounds(form->position, 0, max); for(frameNum=0;(result = read_frame(&fr));frameNum++) { if (frameNum>max) { max+=50; fl_set_slider_bounds(form->position, 0, max); } fl_set_slider_value(form->position, frameNum); fl_check_forms(); if (result == -1) return; if(frameNum < startFrame) { if(fr.lay == 3) set_pointer(512); continue; } play_frame(init,&fr); if (init) fprintf(stderr, "\n"); init = 0; if(verbose > 1 || !(frameNum & 0xf)) fprintf(stderr, "\rDecoding Frame: %4lu.. ",frameNum); } msg = "Finished Playing MPEG stream from file\n"; fl_set_object_label(form->message, msg); fl_redraw_object(form->message); close_stream(); { int sfd = freqs[fr.sampling_frequency] * (fr.lsf + 1); int secs = (frameNum * (fr.lay==1 ? 384 : 1152) + sfd / 2) / sfd; fprintf(stderr,"[%d:%02d] Decoding of %s finished.\n", secs / 60, secs % 60, fname); } audio_flush(outmode, &ai); free (pcm_sample); audio_close(&ai); } void pb_back(FL_OBJECT *obj, long val) { char* msg; msg = "Playing MPEG stream from file\n"; fl_set_object_label(form->message, msg); fname = fl_get_input(form->filename); fl_check_forms(); handle_file(); } void pback(FL_OBJECT *obj, long val) { } void plistback(FL_OBJECT *obj, long val) { char* msg; songchoice = fl_get_menu(form->plist); fname = fl_get_menu_item_text(form->plist, songchoice); msg = "Playing MPEG stream from file\n"; fl_set_object_label(form->message, msg); fl_check_forms(); handle_file(); } void add_back(FL_OBJECT *obj, long val) { fl_addto_menu(form->plist,fl_get_input(form->filename) ); } void mback(FL_OBJECT *obj, long val) { } void ex_back(FL_OBJECT *obj, long val) { exit(0); } void file_cb(FL_OBJECT *obj, long val) { fname = fl_get_input(form->filename); handle_file(); } void error_check(int loc) { /* this routine checks to see if OpenGL errors have occurred recently */ GLenum e; while ((e = glGetError()) != GL_NO_ERROR) fprintf(stderr, "Error: %s before location %d\n", gluErrorString(e), loc); } int main(int argc, char *argv[]) { int result; struct timeval start_time, now; unsigned long secdiff; verbose=2; fprintf(stderr,"MPEG 1.0/2.0 Layer III Audio Player by Doug Fawley and Brandon McLean\n"); fr.single = -1; /* both channels */ fr.synth = synth_1to1; fr.down_sample = 0; ai.format = AUDIO_FORMAT_SIGNED_16; ai.gain = ai.rate = ai.output = -1; ai.device = NULL; ai.channels = 2; { int fmts; int i,j; struct audio_info_struct ai; audio_info_struct_init(&ai); audio_open(&ai); fmts = audio_get_formats(&ai); supported_rates = 0; for(i=0;i<3;i++) { for(j=0;j<3;j++) { ai.rate = rates[i][j]; audio_rate_best_match(&ai); /* allow about 2% difference */ if( ((rates[i][j]*98) < (ai.rate*100)) && ((rates[i][j]*102) > (ai.rate*100)) ) supported_rates |= 1<<(i*3+j); } } audio_close(&ai); if(!force_8bit && !(fmts & AUDIO_FORMAT_SIGNED_16)) force_8bit = 1; if(force_8bit && !(fmts & AUDIO_FORMAT_ULAW_8)) { fprintf(stderr,"No supported audio format found!\n"); exit(1); } } fr.synth = synth_1to1; fr.synth_mono = synth_1to1_mono; fr.block_size = 128; make_decode_tables(outscale); init_layer3(fr.down_sample); fl_initialize(&argc, argv, "Interface", 0, 0); form = create_form_Interface(); /* reveal the form */ fl_show_form(form->Interface, /* form */ FL_PLACE_SIZE, /* pos & size flags */ FL_FULLBORDER, /* border flags */ argv[0] /* window name */ ); fl_set_bitmap_file(form->logobmp, "logo2.xbm"); /* set viewport for OpenGL (part 1) */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); /* Set up coordinate system so (0,0) is in upper left and (WIDTH-1,HEIGHT-1) is in lower right. OpenGL defaults to Y increasing upward, whereas X Windows defaults to Y pointing downward, so force OpenGL to conform to X Windows by "flipping" the Y values (we use HEIGHT,0 instead of 0,HEIGHT) */ /* set viewport for OpenGL (part 2) */ glMatrixMode(GL_MODELVIEW); glLoadIdentity(); /* disable z-buffer, lighting, and shading */ glDisable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); /* clear image buffer to black */ glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT); /* when linking with Mesa, it's necessary to call glFlush() whenever you want to make * sure that stuff is drawn now (as opposed to buffered) */ glFlush(); /* Xforms handles events until "exit" */ while (fl_check_forms() != form->ExitButton) { /* Calling the following routine occasionally can aid debugging. * It will print something only if there's been an OpenGL error * since it was last called. */ error_check(__LINE__); } }