Yet another mp3 player, but this time using SVGALib under Linux. The idea was to use a 320x240 disp

源代码在线查看: mpgcontrol.cpp

软件大小: 37 K
上传用户: li444255
关键词: SVGALib 320x240 another player
下载地址: 免注册下载 普通下载 VIP

相关代码

								/* 				  mpgcontrol.cpp  mpg123 controller class								  This program is free software; you can redistribute it and/or modify it				  under the terms of the GNU General Public License as published by the				  Free Software Foundation; either version 2 of the License, or (at your				  option) any later version.								  This program is distributed in the hope that it will be useful, but				  WITHOUT ANY WARRANTY; without even the implied warranty of				  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU				  General Public License for more details, www.gnu.org.								  Copyright (C) 2000  Simon Harrison (email smh@N_O_S_P_A_M@dr.com)				*/												#include "mpgcontrol.h"				#include "synvis.h"								const int mpgcontroller::QUIT=1;				const int mpgcontroller::LOAD=2;				const int mpgcontroller::STOP=3;				const int mpgcontroller::PAUSE=4;				const int mpgcontroller::JUMP=5;												int mpgcontroller::inpipe[2]={0,0};				int mpgcontroller::outpipe[2]={0,0};				struct sigaction mpgcontroller::handler;				int mpgcontroller::errno=0;				pid_t mpgcontroller::pid =23;				int mpgcontroller::buffersize =0;				char mpgcontroller::mpgpath[1024] = "";				fd_set mpgcontroller::fds;				mpgreturn mpgcontroller::mpg_data;				pthread_mutex_t mpgcontroller::mpg_mutex;  // control access to variables				pthread_t mpgcontroller::threadid;				bool mpgcontroller::now_playing=false;				char mpgcontroller::current_track[1024]="";																				int mpgcontroller::start_mpg_child( int bufsize, char* mp=NULL)				{					int i;				        buffersize = bufsize;								        if (!mp) {				           strcpy( mpgpath, "/usr/local/bin/mpg123" );				        } else {				           if (strlen(mp)				              strcpy(mpgpath,mp);				           } else {				              strcpy(mpgpath,"");				           }				        }									if (pipe(inpipe) || pipe(outpipe))				           return 0;					fcntl(outpipe[1], F_SETFD, O_NONBLOCK);									handler.sa_handler = SIG_DFL;					handler.sa_flags = 0;					sigaction(SIGCHLD, &handler, NULL);									errno = 0;					switch (pid = fork()) {						case -1:				                        // TODO: handle some kind of error here				                        printf( "error forking()\n " );							break;						case 0:   //  child case.				                        printf( "mpg123 child started.\n");							dup2(inpipe[0], 0);							dup2(outpipe[1], 1);							inpipe[1] = outpipe[0] = -1;							for (i = 2; i < 256; i++)								close(i);							errno = 0;							if (buffersize > 0) {								char buf[128];								memset(buf, 0, sizeof(buf));								snprintf(buf, 127, "%d", buffersize? buffersize : 0);							   execlp(mpgpath,"mpg123","-R","-b",buffersize,"-w",FIFO_NAME,"-",(char *)NULL);				                                printf( "mpg child started with buffer..\n" );							} else {								execlp(mpgpath, "mpg123", "-R","-w", FIFO_NAME, "-", (char *)NULL);								//execlp(mpgpath, "mpg123", "-R", "-", (char *)NULL);				                                printf( "mpg child started without buffer.\n" );				                        }							if (errno)								exit(0);						default:  // parent.							handler.sa_handler = restart_mpg_child;							handler.sa_flags = SA_NOCLDSTOP | SA_RESTART;							sigaction(SIGCHLD, &handler, NULL);							break;					}													return pid;				}																void mpgcontroller::add_player_descriptor(fd_set *fds)				{					FD_SET(outpipe[0], fds);				}																void mpgcontroller::restart_mpg_child(int i)				{								// we will use this to clean up on a SIGCHLD 					if (pid)						waitpid(pid, NULL, 0);					pid = 0;									        start_mpg_child(buffersize, mpgpath);									}																								int mpgcontroller::send_cmd(int type, ...)				{					char buf[512], *filename;					int fd = inpipe[1];					long int skip;					va_list args;										memset(buf, 0, 512);					if (fd < 0)						return 0;					switch (type) {						case QUIT:							write(fd, "QUIT\n", 5);							break;						case LOAD:							va_start(args, type);							filename = va_arg(args, char *);							snprintf(buf, 511, "LOAD %s\n", filename);							write(fd, buf, strlen(buf));							va_end(args);							break;						case STOP:							write(fd, "STOP\n", 5);							break;						case PAUSE:							write(fd, "PAUSE\n", 6);							break;						case JUMP:							va_start(args, type);							skip = va_arg(args, long int);							snprintf(buf, 511, "JUMP %+ld\n", skip);							write(fd, buf, strlen(buf));							va_end(args);							break;						default:							return 0;					}					return 1;				        				}												int mpgcontroller::quit()				{				   send_cmd(QUIT);				}								int mpgcontroller::load( char* name)				{				   pthread_mutex_lock( &mpg_mutex );				   strcpy( current_track, name );				   now_playing = true;				   pthread_mutex_unlock( &mpg_mutex );				   send_cmd(LOAD,name);				}								int mpgcontroller::stop()				{				   pthread_mutex_lock( &mpg_mutex );				   now_playing = false;				   pthread_mutex_unlock( &mpg_mutex );				   send_cmd(STOP);				}								int mpgcontroller::pause()				{				   send_cmd(PAUSE);				}								int mpgcontroller::jump(long skip)				{				   send_cmd(JUMP,skip);				}																				void mpgcontroller::check_player_output( fd_set* fds, mpgreturn *mpr)				{				   if (FD_ISSET(outpipe[0],fds)) {				       read_cmd( outpipe[0], mpr );				   }				}												bool mpgcontroller::wait_for_player( mpgreturn* mpgr )				{				bool bRet=false;				   FD_ZERO(&fds);				   FD_SET(0,&fds);				   add_player_descriptor(&fds);				   if (select(FD_SETSIZE, &fds, NULL, NULL, NULL) >0) {				      if (FD_ISSET(0,&fds)) {				         bRet = false;				      } else {				         mpgcontroller::check_player_output( &fds, mpgr );				         bRet = true;				      }				   }				   return bRet;				}																mpgreturn* mpgcontroller::read_cmd(int fd, mpgreturn *status)				{									char buf[512], c = '\0', *p = NULL, *s = NULL;					int n = 0, tmpstatus;									memset(buf, 0, 512);					memset(status, 0, sizeof(mpgreturn));					status->active = true;				        // this seems inefficient but 1) i dont want to use FILE * and 2) we only				        // one to get one line at a time				        //					while ((n < 511) && read(fd, &c, 1)) {						if (c != '\n')							buf[n++] = c;						else							break;					}					if (*buf != '@')						return NULL;					switch (*(p = buf+1)) {						case 'F':							status->played = strtoul(++p, &s, 10);							status->left = strtoul(s, &p, 10);							status->elapsed = strtod(p, &s);							status->remaining = strtod(s, &p);							return status;						case 'P':							tmpstatus = strtoul(++p, &s, 10);							if (tmpstatus == 0) {								status->active = false;							}							break;						default:							break;					}					return NULL;				}												char* mpgcontroller::format_playinfo(mpgreturn *message)				{				static char buffer[1024];				int minleft = (int)message->remaining / 60;				double secleft = message->remaining - minleft*60;				int minused = (int)message->elapsed / 60;				double secused = message->elapsed - minused*60;								  sprintf( buffer, 				                "Time: %02d:%05.2f/%02d:%05.2f   Frames: (%d/%d)    ",				  minused, secused, minleft, secleft, message->played, message->left);				  return buffer;				}												//				//  Below the threaded interface... 				//								void mpgcontroller::startthread()				{				   pthread_mutex_init( &mpg_mutex, NULL );				   pthread_create( &threadid, NULL, mainthread, NULL );				}								void* mpgcontroller::mainthread( void* )				{				// mpg123 thread-related variables.				char next_track[1024];    // next track to play.				mpgreturn mpgr;           // the data coming back from the player.				int mpg_command=0;        // zero = no data				bool ok = true;								   				   // start up the mpg123 player, no buffer				   start_mpg_child( 0 );				   wait_for_player( &mpgr );				   				   // Loop indefinitely waiting for commands,				   // at frequency of player response.				 try {				   while(ok) {				        if (wait_for_player( &mpgr )) {				            // copy data to critical section.				            pthread_mutex_lock( &mpg_mutex );				            memcpy( (void*)&mpg_data, (void*)&mpgr, sizeof(mpgreturn) );				            if (!mpgr.active) {				               now_playing = false;				            } else {				               now_playing = true;				            }				            pthread_mutex_unlock( &mpg_mutex );				        }				   }				 } catch (...) {				   pthread_mutex_destroy( &mpg_mutex );				 }				}												bool mpgcontroller::get_safe_data( mpgreturn* mpgr, char* trackname )				{				bool b;				    pthread_mutex_lock( &mpg_mutex );				    memcpy( (void*)mpgr, (void*)&mpg_data, sizeof(mpgreturn) );				    if ((trackname) && now_playing) strcpy( trackname, current_track );				    b = now_playing;				    pthread_mutex_unlock( &mpg_mutex );				    return b;				}												// Example main program comment in and re-compile to see how the 				// class works.				/*				int main()				{				   mpgreturn mpgr;				   int notloaded=1;				   				   mpgcontroller::start_mpg_child( 0 );				   for (int i=0;;i++) {				       if (mpgcontroller::wait_for_player( &mpgr )) {				          printf( "played - %d\n", mpgr.played );				          if (notloaded) {				             printf( "loading track.\n" );				             mpgcontroller::load( "./tr.mp3" );				             notloaded = 0;				          }				       }				   }				   return 0;				}				*/																			

相关资源