File: mpg123_play.c

package info (click to toggle)
gnomp3 0.1.7-2
  • links: PTS
  • area: main
  • in suites: woody
  • size: 488 kB
  • ctags: 342
  • sloc: ansic: 3,285; makefile: 74; awk: 33
file content (154 lines) | stat: -rw-r--r-- 3,767 bytes parent folder | download | duplicates (3)
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();
}