1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
/**
** mpg123_play.c - playing of songs usung mpg123
**
** Copyright (C) 2000 Matthew Pratt <mattpratt@yahoo.com>
**
** This software is licensed under the terms of the GNU General
** Public License (GPL). Please see the file LICENSE for details.
**/
#include <sys/types.h>
#include <signal.h>
#include <sys/wait.h>
#include "mp3_control.h"
#include "gnomp3.h"
#include "mp3list.h"
int mpg123_play_pipe[2];
pid_t mpg123_child;
MP3 *currently_playing;
int total_frames;
void mpg123_get_data(gpointer data, gint source, GdkInputCondition condition );
/*
* this is a signal handler for the SIGCHLD signal. It is used in mp3play.c
* Since it is a signal handler it has to be reentrant. As a result it signals
* the above routing by sending some data on the pipe
*/
void mpg123_play_song_finished(int sig)
{
write( mpg123_play_pipe[1], "Stopped\n", 8 );
}
/*
* Initialise the mpg123 playback routines
*/
void mpg123_play_init()
{
pipe(mpg123_play_pipe);
mpg123_child = 0;
gdk_input_add( mpg123_play_pipe[0], GDK_INPUT_READ, mpg123_get_data, NULL);
}
/*
* Stop the mpg123 playback
*/
void mpg123_play_stop()
{
if( mpg123_child == 0 )
return;
currently_playing->playing = FALSE;
signal( SIGCHLD, SIG_IGN);
kill( mpg123_child, SIGTERM );
wait(NULL);
mpg123_child = 0;
}
/*
* Play the given mp3 from the given point
*/
void mpg123_play_song(MP3 *mp3, float frame)
{
char ntext[128];
if( mpg123_child != 0 )
mpg123_play_stop();
if( mp3 )
currently_playing = mp3;
else
mp3 = currently_playing;
if(!mp3)return;
frame = frame * total_frames / 100;
gtk_label_set_text(GTK_LABEL(gnomp3.mp3_control_song_name), mp3->display_name);
signal( SIGCHLD, mpg123_play_song_finished );
mpg123_child = fork();
if( mpg123_child == -1 )
exit(1);
if( mpg123_child == 0 ){
g_snprintf( ntext, sizeof(ntext), "%d", (int)frame );
dup2( mpg123_play_pipe[1], STDERR_FILENO );
execlp( "mpg123", "gnomp3-mpg123", "-vk", ntext, mp3->filename, NULL );
perror("execlp");
fprintf( stderr, " *** Could not exec mpg123, gnomp3 will not be able to play mp3s.\nCheck that mpg123 is installed correctly and is in the path.\nmpg123 can be downloaded from http://mpg.123.org\n");
_exit(1);
}
}
/*
* IO callback. accepts the output from the pipes from mpg123.
* Example output from mpg123
* Frame# 977 [ 6366], Time: 00:25.52 [02:46.29],
*/
void mpg123_get_data(gpointer data, gint source, GdkInputCondition condition )
{
char line[1024];
int curr_frame, inv_frame;
int bytes;
int i;
char *start;
bytes = read( source, line, 1024);
line[bytes-1] = 0;
for( i = 0; line[i]; i++){
if( line[i] == '[' || line[i] == ']')line[i] = ' ';
if( line[i] == '\r')line[i] = ' ';
}
start = strstr( line, "Frame#" );
if( start ){
strtok( start, " ");
curr_frame = atoi( strtok( NULL, " " ) );
inv_frame = atoi( strtok( NULL, " " ) );
total_frames = curr_frame + inv_frame;
mp3_control_state.progress = 100.0 * (double)curr_frame / (double)total_frames;
strtok( NULL, " " );
strtok( NULL, " " );
mp3_control_state.time = strtok( NULL, "." );
}else{
mp3_control_state.time = "";
if( !strncmp( "Bitrate:", line, 8 )){
strtok( line, " ");
mp3_control_state.bitrate = atoi( strtok( NULL, " ") );
}else if( !strncmp( "Audio:", line, 6 )){
strtok( line, " ");
strtok( NULL, " ");strtok( NULL, " "); strtok( NULL, " ");
start = strtok( NULL, " ");
if( start )
mp3_control_state.freq = atoi( start );
}else if( !strncmp( "Stopped", line, 7 )){
if( mp3_control_state.playing == TRUE )
mp3_control_play_next();
}
}
mp3_control_update_display();
}
|