?? mpg123.c
字號:
buffermem->buf[0] = ai.rate; buffermem->buf[1] = ai.channels; buffermem->buf[2] = ai.format; buffer_reset(); } else #endif if (param.outmode == DECODE_AUDIO) { /* audio_reset_parameters(&ai); */ /* 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"); safe_exit(1); } }}/* precog the audio rate that will be set before output begins this is needed to give gapless code a chance to keep track for firstframe != 0*/void prepare_audioinfo(struct frame *fr, struct audio_info_struct *nai){ long newrate = freqs[fr->sampling_frequency]>>(param.down_sample); fr->down_sample = param.down_sample; if(!audio_fit_capabilities(nai,fr->stereo,newrate)) safe_exit(1);}/* * play a frame read by read_frame(); * (re)initialize audio if necessary. * * needs a major rewrite .. it's incredible ugly! */int play_frame(int init,struct frame *fr){ int clip; long newrate; long old_rate,old_format,old_channels; if(fr->header_change || init) { if (!param.quiet && init) { if (param.verbose) print_header(fr); else print_header_compact(fr); } if(fr->header_change > 1 || init) { old_rate = ai.rate; old_format = ai.format; old_channels = ai.channels; newrate = freqs[fr->sampling_frequency]>>(param.down_sample); prepare_audioinfo(fr, &ai); if(param.verbose > 1) fprintf(stderr, "Note: audio output rate = %li\n", ai.rate); #ifdef GAPLESS if(param.gapless && (fr->lay == 3)) layer3_gapless_bytify(fr, &ai); #endif /* check, whether the fitter set our proposed rate */ if(ai.rate != newrate) { if(ai.rate == (newrate>>1) ) fr->down_sample++; else if(ai.rate == (newrate>>2) ) fr->down_sample+=2; else { fr->down_sample = 3; fprintf(stderr,"Warning, flexible rate not heavily tested!\n"); } if(fr->down_sample > 3) fr->down_sample = 3; } switch(fr->down_sample) { case 0: case 1: case 2: fr->down_sample_sblimit = SBLIMIT>>(fr->down_sample); break; case 3: { long n = freqs[fr->sampling_frequency]; long m = ai.rate; if(!synth_ntom_set_step(n,m)) return 0; if(n>m) { fr->down_sample_sblimit = SBLIMIT * m; fr->down_sample_sblimit /= n; } else { fr->down_sample_sblimit = SBLIMIT; } } break; } init_output(); if(ai.rate != old_rate || ai.channels != old_channels || ai.format != old_format || param.force_reopen) { if(param.force_mono < 0) { if(ai.channels == 1) fr->single = 3; else fr->single = -1; } else fr->single = param.force_mono; param.force_stereo &= ~0x2; if(fr->single >= 0 && ai.channels == 2) { param.force_stereo |= 0x2; } set_synth_functions(fr); init_layer3(fr->down_sample_sblimit); reset_audio(); if(param.verbose) { if(fr->down_sample == 3) { long n = freqs[fr->sampling_frequency]; long m = ai.rate; if(n > m) { fprintf(stderr,"Audio: %2.4f:1 conversion,",(float)n/(float)m); } else { fprintf(stderr,"Audio: 1:%2.4f conversion,",(float)m/(float)n); } } else { fprintf(stderr,"Audio: %ld:1 conversion,",(long)pow(2.0,fr->down_sample)); } fprintf(stderr," rate: %ld, encoding: %s, channels: %d\n",ai.rate,audio_encoding_name(ai.format),ai.channels); } } if (intflag) return 1; } } if (fr->error_protection) { getbits(16); /* skip crc */ } /* do the decoding */ clip = (fr->do_layer)(fr,param.outmode,&ai);#ifndef NOXFERMEM if (param.usebuffer) { if (!intflag) { buffermem->freeindex = (buffermem->freeindex + pcm_point) % buffermem->size; if (buffermem->wakeme[XF_READER]) xfermem_putcmd(buffermem->fd[XF_WRITER], XF_CMD_WAKEUP_INFO); } pcm_sample = (unsigned char *) (buffermem->data + buffermem->freeindex); pcm_point = 0; while (xfermem_get_freespace(buffermem) < (FRAMEBUFUNIT << 1)) if (xfermem_block(XF_WRITER, buffermem) == XF_CMD_TERMINATE) { intflag = TRUE; break; } if (intflag) return 1; }#endif if(clip > 0 && param.checkrange) fprintf(stderr,"%d samples clipped\n", clip); return 1;}void set_synth_functions(struct frame *fr){ typedef int (*func)(real *,int,unsigned char *,int *); typedef int (*func_mono)(real *,unsigned char *,int *); typedef void (*func_dct36)(real *,real *,real *,real *,real *); int ds = fr->down_sample; int p8=0;#ifdef USE_3DNOW static func funcs[3][4] = {#else static func funcs[2][4] = { #endif { synth_1to1, synth_2to1, synth_4to1, synth_ntom } , { synth_1to1_8bit, synth_2to1_8bit, synth_4to1_8bit, synth_ntom_8bit } #ifdef USE_3DNOW ,{ synth_1to1_3dnow, synth_2to1, synth_4to1, synth_ntom }#endif }; static func_mono funcs_mono[2][2][4] = { { { synth_1to1_mono2stereo , synth_2to1_mono2stereo , synth_4to1_mono2stereo , synth_ntom_mono2stereo } , { synth_1to1_8bit_mono2stereo , synth_2to1_8bit_mono2stereo , synth_4to1_8bit_mono2stereo , synth_ntom_8bit_mono2stereo } } , { { synth_1to1_mono , synth_2to1_mono , synth_4to1_mono , synth_ntom_mono } , { synth_1to1_8bit_mono , synth_2to1_8bit_mono , synth_4to1_8bit_mono , synth_ntom_8bit_mono } } };#ifdef USE_3DNOW static func_dct36 funcs_dct36[2] = {dct36 , dct36_3dnow};#endif if((ai.format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_8) p8 = 1; fr->synth = funcs[p8][ds]; fr->synth_mono = funcs_mono[param.force_stereo?0:1][p8][ds];/* TODO: make autodetection for _all_ x86 optimizations (maybe just for i586+ and keep separate 486 build?) */#ifdef USE_3DNOW /* check cpuflags bit 31 (3DNow!) and 23 (MMX) */ if((param.stat_3dnow < 2) && ((param.stat_3dnow == 1) || (getcpuflags() & 0x80800000) == 0x80800000)) { fr->synth = funcs[2][ds]; /* 3DNow! optimized synth_1to1() */ fr->dct36 = funcs_dct36[1]; /* 3DNow! optimized dct36() */ } else { fr->dct36 = funcs_dct36[0]; }#endif if(p8) { if(make_conv16to8_table(ai.format) != 0) { /* it's a bit more work to get proper error propagation up */ safe_exit(1); } }}int main(int argc, char *argv[]){ int result; char *fname;#if !defined(WIN32) && !defined(GENERIC) struct timeval start_time, now; unsigned long secdiff;#endif int init; #ifdef GAPLESS int pre_init; #endif int j;#ifdef OS2 _wildcard(&argc,&argv);#endif if(sizeof(short) != 2) { fprintf(stderr,"Ouch SHORT has size of %d bytes (required: '2')\n",(int)sizeof(short)); safe_exit(1); } if(sizeof(long) < 4) { fprintf(stderr,"Ouch LONG has size of %d bytes (required: at least 4)\n",(int)sizeof(long)); } (prgName = strrchr(argv[0], '/')) ? prgName++ : (prgName = argv[0]); audio_info_struct_init(&ai); while ((result = getlopt(argc, argv, opts))) switch (result) { case GLO_UNKNOWN: fprintf (stderr, "%s: Unknown option \"%s\".\n", prgName, loptarg); usage(1); case GLO_NOARG: fprintf (stderr, "%s: Missing argument for option \"%s\".\n", prgName, loptarg); usage(1); }#ifdef USE_3DNOW if (param.test_3dnow) { int cpuflags = getcpuflags(); fprintf(stderr,"CPUFLAGS = %08x\n",cpuflags); if ((cpuflags & 0x00800000) == 0x00800000) { fprintf(stderr,"MMX instructions are supported.\n"); } if ((cpuflags & 0x80000000) == 0x80000000) { fprintf(stderr,"3DNow! instructions are supported.\n"); } safe_exit(0); }#endif if (loptind >= argc && !param.listname && !param.remote) usage(1);#if !defined(WIN32) && !defined(GENERIC) if (param.remote) { param.verbose = 0; param.quiet = 1; }#endif if (!(param.listentry < 0) && !param.quiet) print_title(stderr); /* do not pollute stdout! */ if(param.force_mono >= 0) { fr.single = param.force_mono; } if(param.force_rate && param.down_sample) { fprintf(stderr,"Down sampling and fixed rate options not allowed together!\n"); safe_exit(1); } audio_capabilities(&ai); /* equalizer initialization regardless of equalfile */ for(j=0; j<32; j++) { equalizer[0][j] = equalizer[1][j] = 1.0; equalizer_sum[0][j] = equalizer_sum[1][j] = 0.0; } if(equalfile != NULL) { /* tst; ThOr: not TRUE or FALSE: allocated or not... */ FILE *fe; int i; equalizer_cnt = 0; fe = fopen(equalfile,"r"); if(fe) { char line[256]; for(i=0;i<32;i++) { float e1,e0; /* %f -> float! */ line[0]=0; fgets(line,255,fe); if(line[0]=='#') continue; sscanf(line,"%f %f",&e0,&e1); equalizer[0][i] = e0; equalizer[1][i] = e1; } fclose(fe); have_eq_settings = TRUE; } else fprintf(stderr,"Can't open equalizer file '%s'\n",equalfile); }#ifdef HAVE_SETPRIORITY if(param.aggressive) { /* tst */ int mypid = getpid(); setpriority(PRIO_PROCESS,mypid,-20); }#endif#ifdef HAVE_SCHED_SETSCHEDULER if (param.realtime) { /* Get real-time priority */ struct sched_param sp; fprintf(stderr,"Getting real-time priority\n"); memset(&sp, 0, sizeof(struct sched_param)); sp.sched_priority = sched_get_priority_min(SCHED_FIFO); if (sched_setscheduler(0, SCHED_RR, &sp) == -1) fprintf(stderr,"Can't get real-time priority\n"); }#endif set_synth_functions(&fr); if(!param.remote) prepare_playlist(argc, argv); make_decode_tables(outscale); init_layer2(); /* inits also shared tables with layer1 */ init_layer3(fr.down_sample);#if !defined(WIN32) && !defined(GENERIC) /* This ctrl+c for title skip only when not in some control mode */ if ( !param.remote #ifdef HAVE_TERMIOS && !param.term_ctrl #endif ) catchsignal (SIGINT, catch_interrupt); if(param.remote) { int ret; init_id3(); init_icy();
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -