⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpgcontrol.cpp

📁 Yet another mp3 player, but this time using SVGALib under Linux. The idea was to use a 320x240 disp
💻 CPP
字号:
/*   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 variablespthread_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)<1024) {              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 databool 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;}*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -