1 /* Sound Player 2 3 Copyright (C) 1997 by Woo-jae Jung */ 4 5 // It's an example of using MPEG Sound library 6 7 // Anyone can use MPEG Sound library under GPL 8 9 #ifdef HAVE_CONFIG_H 10 #include "config.h" 11 #endif 12 13 #include <string.h> 14 #include <unistd.h> 15 #include <stdlib.h> 16 17 #include <sys/types.h> 18 #include <sys/wait.h> 19 #include <iostream> 20 using namespace std; 21 22 #ifdef HAVE_LIBID3 23 #include <id3/tag.h> 24 #include <id3/misc_support.h> 25 #endif /* HAVE_LIBID3 */ 26 27 #include <iomanip> 28 29 #include "mpegsound.h" 30 31 #include "splay.h" 32 33 static char *help= 34 "\t-2 : playing with half frequency.\n" 35 "\t-e : exit when playing is done. (only XSPLAY)\n" 36 "\t-f : display frame and time info (played and remaining).\n" 37 "\t-m : force to mono.\n" 38 "\t-r : repeat forever.\n" 39 "\t-s : shuffle play.\n" 40 "\t-v : verbose, Very verbose, Very very verbose.\n" 41 "\t-M : playing MPEG-Audio file as standard input.\n" 42 "\t-V : display version.\n" 43 "\n" 44 "\t-k num : start playing at frame num.\n" 45 "\t-d dev : Set dev as device or file.\n" 46 "\t-l list : list file.\n" 47 "\t-t buf : Set number of buffer. (default : 50)\n" 48 "\n" 49 "For detail, see man pages.\n"; 50 51 /***********************/ 52 /* Command line player */ 53 /***********************/ 54 inline void error(int n) 55 { 56 fprintf(stderr,"%s: %s\n",splay_progname,splay_Sounderrors[n-1]); 57 return; 58 } 59 60 #ifdef PTHREADEDMPEG 61 static void playingthread(Mpegfileplayer *player) 62 { 63 if(player->geterrorcode()>0)error(player->geterrorcode()); 64 else 65 { 66 player->setforcetomono(splay_forcetomonoflag); 67 player->playingwiththread(splay_verbose-1,splay_frameinfo, 68 splay_threadnum, splay_startframe); 69 if(player->geterrorcode()>0)error(player->geterrorcode()); 70 } 71 } 72 #endif 73 74 static void playing(Fileplayer *player) 75 { 76 if(player->geterrorcode()>0)error(player->geterrorcode()); 77 else 78 { 79 player->setforcetomono(splay_forcetomonoflag); 80 player->playing(splay_verbose-1,splay_frameinfo,splay_startframe); 81 if(player->geterrorcode()>0)error(player->geterrorcode()); Panel(QWidget * parent,const char * name)82 } 83 } 84 85 //Wrapper to convert null-string to the empty string 86 inline const char * nn(const char* str) 87 { 88 return str?str:""; 89 } 90 91 #ifdef HAVE_LIBID3 92 93 //List of ID3 genre names, copied from xmms.org 94 const char *ID3_gen_list[255] = 95 { 96 //0-24 97 "Blues", "Classic Rock", "Country", "Dance", "Disco", 98 "Funk", "Grunge", "Hip-Hop", "Jazz", "Metal", 99 "New Age", "Oldies", "Other", "Pop", "R&B", 100 "Rap", "Reggae", "Rock", "Techno", "Industrial", 101 "Alternative", "Ska", "Death Metal", "Pranks", "Soundtrack", 102 //25-49 103 "Euro-Techno", "Ambient", "Trip-Hop", "Vocal", "Jazz+Funk", 104 "Fusion", "Trance", "Classical", "Instrumental", "Acid", 105 "House", "Game", "Sound Clip", "Gospel", "Noise", 106 "Alt", "Bass", "Soul", "Punk", "Space", 107 "Meditative", "Instrumental Pop", "Instrumental Rock", "Ethnic", "Gothic", 108 //50-74 109 "Darkwave", "Techno-Industrial", "Electronic", "Pop-Folk", "Eurodance", 110 "Dream", "Southern Rock", "Comedy", "Cult", "Gangsta Rap", 111 "Top 40", "Christian Rap", "Pop/Funk", "Jungle", "Native American", 112 "Cabaret", "New Wave", "Psychedelic", "Rave", "Showtunes", 113 "Trailer", "Lo-Fi", "Tribal", "Acid Punk", "Acid Jazz", 114 //75-99 115 "Polka", "Retro", "Musical", "Rock & Roll", "Hard Rock", 116 "Folk", "Folk/Rock", "National Folk", "Swing", "Fast-Fusion", 117 "Bebob", "Latin", "Revival", "Celtic", "Bluegrass", 118 "Avantgarde", "Gothic Rock", "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", 119 "Slow Rock", "Big Band", "Chorus", "Easy Listening", "Acoustic", 120 //100-124 121 "Humour", "Speech", "Chanson", "Opera", "Chamber Music", 122 "Sonata", "Symphony", "Booty Bass", "Primus", "Porn Groove", 123 "Satire", "Slow Jam", "Club", "Tango", "Samba", 124 "Folklore", "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle", 125 "Duet", "Punk Rock", "Drum Solo", "A Cappella", "Euro-House", 126 //125-149 127 "Dance Hall", "Goa", "Drum & Bass", "Club-House", "Hardcore", 128 "Terror", "Indie", "BritPop", "Negerpunk", "Polsk Punk", 129 "Beat", "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover", 130 "Contemporary Christian", "Christian Rock", "Merengue", "Salsa", "Thrash Metal", 131 "Anime", "JPop", "Synthpop" 132 }; 133 134 ostream& operator<<(ostream& s, const ID3_Tag* tag ) 135 { 136 /* this gets all frames, but the info is rather difficult to get, 137 just assume all is ID3FN_TEXT here and hope we get the most... 138 */ 139 /* 140 size_t max = tag->NumFrames(); 141 // s << "frames: " << max << endl; 142 for ( size_t n=0; n<max ; n++){ 143 if ( ID3_Frame* frame = (*tag)[n] ){ 144 s << "@@@" << frame->GetDescription() << " " << 145 ID3_GetString(frame,ID3FN_TEXT) << endl; 146 } 147 } 148 */ 149 150 151 // Print just what we want... 152 s.setf(ios::left); // The filled fields get the text to the left 153 s << 154 "Title : " << nn(ID3_GetTitle(tag)) << endl; 155 s << 156 "Artist: " << setw(30) << nn(ID3_GetArtist(tag)) << 157 "Album: " << nn(ID3_GetAlbum(tag)) << 158 endl ; 159 160 s << 161 "Genre : " << setw(18) << nn(ID3_gen_list[ID3_GetGenreNum(tag)]) << 162 "Track: " << setw(5) << ID3_GetTrackNum(tag) << 163 "Year: " << setw(6) << nn(ID3_GetYear(tag)); 164 // if ( ID3_GetComment(tag) ){ 165 // s << endl << "Comment:" << nn(ID3_GetComment(tag)) << 166 // nn(ID3_GetLyricist(tag)) << nn(ID3_GetLyrics(tag)); 167 // } 168 169 return s; 170 } 171 #endif /* HAVE_LIBID3 */ 172 173 static void play(char *filename) 174 { 175 if( splay_verbose-- ) 176 cout << filename << ":" << endl; 177 if( splay_verbose>0 ) 178 { 179 // cerr << getpid() << endl; 180 #ifdef HAVE_LIBID3 181 try { 182 const ID3_Tag* mytag = new ID3_Tag(filename); 183 if ( mytag->HasV1Tag() || mytag->HasV2Tag() ) 184 cout << mytag << endl; 185 delete mytag; 186 187 } 188 catch(ID3_Error &err){ 189 cout << err.GetErrorFile() << " (" << err.GetErrorLine() << "): " 190 << err.GetErrorType() << ": " << err.GetErrorDesc() << endl; 191 } 192 #endif /* HAVE_LIBID3 */ 193 } 194 195 Mpegfileplayer *player; 196 197 player=new Mpegfileplayer; 198 if(!player->openfile(filename,splay_devicename)) 199 { 200 error(player->geterrorcode()); 201 delete player; 202 return; 203 } 204 player->setdownfrequency(splay_downfrequency); 205 #ifdef PTHREADEDMPEG 206 playingthread(player); 207 #else 208 playing(player); 209 #endif 210 delete player; 211 } 212 213 #include <signal.h> 214 215 void mtest(int) 216 { 217 // cerr << "mtest got nr " << i << endl; 218 } 219 220 void mstop(int) 221 { 222 // cerr << "mstop got nr " << i << endl; 223 exit(1); 224 } 225 226 227 int main(int argc,char *argv[]) 228 { 229 int c; 230 231 splay_progname=argv[0]; 232 233 while((c=getopt(argc,argv, 234 "VM2mfrsvd:k:l:" 235 #ifdef PTHREADEDMPEG 236 "t:" 237 #endif 238 ))>=0) 239 { 240 switch(c) 241 { 242 case 'V':printf("%s %s" 243 #ifdef PTHREADEDMPEG 244 " with pthread" 245 #endif 246 "\n",PACKAGE,VERSION); 247 return 0; 248 case 'M': refreshlabel(Label * l)249 { 250 Mpegfileplayer player; 251 252 player.openfile(NULL,splay_devicename); 253 playing(&player); 254 return 0; 255 } 256 257 case '2':splay_downfrequency = 1;break; Setframeslider(int frame,int maxframe)258 case 'f':splay_frameinfo =true;break; 259 case 'm':splay_forcetomonoflag=true;break; 260 case 'r':splay_repeatflag =true;break; 261 case 's':splay_shuffleflag =true;break; 262 case 'v':splay_verbose++; break; 263 initializelabel(void)264 case 'd':splay_devicename=optarg; break; 265 case 'k':splay_startframe=atoi(optarg); break; 266 case 'l':if(splay_verbose) 267 fprintf(stderr,"List file : %s\n",optarg); 268 readlist(optarg); 269 break; 270 #ifdef PTHREADEDMPEG 271 case 't': 272 { 273 int a; 274 timerEvent(QTimerEvent *)275 sscanf(optarg,"%d",&a); 276 splay_threadnum=a; 277 } 278 break; 279 #endif 280 default:fprintf(stderr,"Bad argument.\n"); 281 } 282 } 283 284 if(argc<=optind && splay_listsize==0) 285 { 286 printf("%s %s" 287 #ifdef PTHREADEDMPEG 288 " with pthread" 289 #endif 290 "\n" 291 "Usage : splay [-2mrsvMVW] [-d device] [-l listfile] " 292 #ifdef PTHREADEDMPEG 293 "[-t number] " 294 #endif 295 "files ...\n" 296 "\n" 297 "%s" 298 ,PACKAGE,VERSION,help); 299 return 0; 300 } 301 302 if(splay_listsize==0) // Make list by arguments 303 arglist(argc,argv,optind); 304 305 do 306 { 307 if(splay_shuffleflag)shufflelist(); 308 309 for(int i=0;i<splay_listsize;i++){ 310 signal(SIGINT,&mtest); 311 if ( fork() ) { 312 // pid_t pid=getpid(); 313 // cout << "parent process " << pid << endl; 314 int a; 315 wait(&a); 316 signal(SIGINT,&mstop); 317 // cerr << "stoppable "<<endl; 318 usleep (500*1000); 319 // cerr << "not stoppable "<<endl; 320 signal(SIGINT,&mtest); 321 } 322 else{ 323 // cout << "child process " << getpid() << endl; 324 signal(SIGINT,&mstop); 325 play(splay_list[i]); 326 exit(0); load()327 } 328 } 329 330 }while(splay_repeatflag); 331 332 return 0; 333 } loadlist()334