📄 mpg123.c
字号:
/* * Mpeg Audio Player (see version.h for version number) * ------------------------ * copyright (c) 1995,1996,1997,1998,1999 by Michael Hipp, All rights reserved. * See also 'README' ! * * this file was hevily adapted for mpeg2ts1394dec. much unneeded stuff eliminated. * Copyright (C) 2000-2007, Manfred Weihs <mweihs@users.sourceforge.net> */#include <stdlib.h>#include <sys/types.h>#if !defined(WIN32) && !defined(GENERIC)#include <sys/wait.h>#include <sys/time.h>#include <sys/resource.h>#endif#include <errno.h>#include <string.h>#include <fcntl.h>#if 0#define SET_RT #endif#ifdef SET_RT#include <sched.h>#endif#include "mpg123.h"struct parameter param = { FALSE , /* aggressiv */ FALSE , /* shuffle */ FALSE , /* remote */ DECODE_AUDIO , /* write samples to audio device */ FALSE , /* silent operation */ 0 , /* second level buffer size */ TRUE , /* resync after stream error */ 0 , /* verbose level */ -1 , /* force mono */ 0 , /* force stereo */ 0 , /* force 8bit */ 0 , /* force rate */ 0 , /* down sample */ FALSE , /* checkrange */ 0 , /* doublespeed */ 0 , /* halfspeed */ 0 , /* force_reopen, always (re)opens audio device for next song */ FALSE, /* try to run process in 'realtime mode' */ { 0,}, /* wav,cdr,au Filename */};/*char *listname = NULL;char *listnamedir = NULL; */char *equalfile = NULL;long outscale = 32768;/*long numframes = -1;long startFrame= 0;int frontend_type = 0; */int buffer_fd[2]; /*int buffer_pid;char **shufflist= NULL;int *shuffleord= NULL;int shuffle_listsize = 0; */static int intflag = FALSE;int OutputDescriptor;struct audio_info_struct ai;#define FRAMEBUFUNIT (18 * 64 * 4)static void set_synth_functions(struct frame *fr);void init_output(void){ /* + 1024 for NtoM rate converter */ if (!(pcm_sample = (unsigned char *) malloc(audiobufsize * 2 + 1024))) { perror ("malloc()"); exit (1); } if(audio_open(&ai) < 0) { perror("audio"); exit(1); }}/* * Change the playback sample rate. */static void reset_audio(void){ 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"); exit(1); } }}/* * play a frame read by read_frame(); * (re)initialize audio if necessary. * * needs a major rewrite .. it's incredible ugly! */static int init_play_frame=1; /*initialize play_frame */void play_frame(struct frame *fr){ int clip; long newrate; long old_rate,old_format,old_channels; if(fr->header_change || init_play_frame) { if(fr->header_change > 1 || init_play_frame) { old_rate = ai.rate; old_format = ai.format; old_channels = ai.channels; newrate = freqs[fr->sampling_frequency]>>(param.down_sample); fr->down_sample = param.down_sample; audio_fit_capabilities(&ai,fr->stereo,newrate);#if SIMPLE_SYNCHRONISATION /* check, whether the fitter setted 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, flexibel rate not heavily tested!\n"); } if(fr->down_sample > 3) fr->down_sample = 3; }#else/* Since we want to precisely adapt the up- or downsampling, we commented out the determination of the downsample and set it to 3 (=flexible up-/downsampling */ fr->down_sample=3;#endif 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; synth_ntom_set_step(n,m); if(n>m) { fr->down_sample_sblimit = SBLIMIT * m; fr->down_sample_sblimit /= n; } else { fr->down_sample_sblimit = SBLIMIT; } } break; }/* init_output(); now in initialisation */ 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 || fr->stereo == 1) && 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; } } if (fr->error_protection) { getbits(16); /* skip crc */ } /* do the decoding */ clip = (fr->do_layer)(fr,param.outmode,&ai); if(clip > 0 && param.checkrange) fprintf(stderr,"%d samples clipped\n", clip); init_play_frame=0;}static void set_synth_functions(struct frame *fr){ typedef int (*func)(real *,int,unsigned char *,int *); typedef int (*func_mono)(real *,unsigned char *,int *); int ds = fr->down_sample; int p8=0; static func funcs[2][4] = { { synth_1to1, synth_2to1, synth_4to1, synth_ntom } , { synth_1to1_8bit, synth_2to1_8bit, synth_4to1_8bit, synth_ntom_8bit } }; 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 } } }; 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]; if(p8) { make_conv16to8_table(ai.format); }}int initmpegaudioplayer(struct frame *fr){ if(sizeof(short) != 2) { fprintf(stderr,"Ouch SHORT has size of %d bytes (required: '2')\n",(int)sizeof(short)); return 0; } if(sizeof(long) < 4) { fprintf(stderr,"Ouch LONG has size of %d bytes (required: at least 4)\n",(int)sizeof(long)); return 0; } audio_info_struct_init(&ai); if(param.force_mono >= 0) { fr->single = param.force_mono; } if(param.force_rate && param.down_sample) { fprintf(stderr,"Down smapling and fixed rate options not allowed together!\n"); return 0; } audio_capabilities(&ai);/* if(equalfile) { // tst FILE *fe; int i; equalizer_cnt = 0; for(i=0;i<32;i++) { equalizer[0][i] = equalizer[1][i] = 1.0; equalizer_sum[0][i] = equalizer_sum[1][i] = 0.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); } else fprintf(stderr,"Can't open equalizer file '%s'\n",equalfile); }*/ set_synth_functions(fr); make_decode_tables(outscale); init_layer2(); /* inits also shared tables with layer1 */ init_layer3(fr->down_sample); init_play_frame=1; /* tell play_frame to do the initialization-part next time */ init_output(); /* moved here from play_frame */ return 1;}int donempegaudioplayer(){ audio_flush(param.outmode, &ai); free (pcm_sample); audio_close(&ai); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -