3
* Control interface to generic front ends.
4
* written/copyrights 1997/99 by Andreas Neuhaus (and Michael Hipp)
11
#include <sys/types.h>
17
#include <sys/socket.h>
21
#define MODE_STOPPED 0
22
#define MODE_PLAYING 1
25
extern struct audio_info_struct ai;
26
extern int buffer_pid;
27
extern int tabsel_123[2][3][16];
29
void generic_sendmsg (char *fmt, ...)
39
static double compute_bpf (struct frame *fr)
44
bpf = tabsel_123[fr->lsf][0][fr->bitrate_index];
46
bpf /= freqs[fr->sampling_frequency] << (fr->lsf);
50
bpf = tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index];
52
bpf /= freqs[fr->sampling_frequency] << (fr->lsf);
60
static double compute_tpf (struct frame *fr)
62
static int bs[4] = { 0, 384, 1152, 1152 };
65
tpf = (double) bs[fr->lay];
66
tpf /= freqs[fr->sampling_frequency] << (fr->lsf);
70
void generic_sendstat (struct frame *fr, int no)
73
double bpf, tpf, tim1, tim2;
77
/* this and the 2 above functions are taken from common.c.
78
/ maybe the compute_* functions shouldn't be static there
79
/ so that they can also used here (performance problems?).
80
/ isn't there an easier way to compute the time? */
82
buffsize = xfermem_get_usedspace(buffermem);
85
bpf = compute_bpf(fr);
86
tpf = compute_tpf(fr);
87
if (buffsize > 0 && ai.rate > 0 && ai.channels > 0) {
88
dt = (double) buffsize / ai.rate / ai.channels;
89
if ((ai.format & AUDIO_FORMAT_MASK) == AUDIO_FORMAT_16)
94
if (rd->filelen >= 0) {
95
long t = rd->tell(rd);
96
rno = (int)((double)(rd->filelen-t)/bpf);
97
sno = (int)((double)t/bpf);
99
tim1 = sno * tpf - dt;
100
tim2 = rno * tpf + dt;
102
generic_sendmsg("F %d %d %3.2f %3.2f", sno, rno, tim1, tim2);
105
extern char *genre_table[];
106
extern int genre_count;
107
void generic_sendinfoid3 (char *buf)
109
char info[200] = "", *c;
112
for (i=0, c=buf+3; i<124; i++, c++)
113
info[i] = *c ? *c : ' ';
116
generic_sendmsg("I ID3:%s%s", info, (genre<=genre_count) ? genre_table[genre] : "Unknown");
119
void generic_sendinfo (char *filename)
122
s = strrchr(filename, '/');
130
generic_sendmsg("I %s", s);
133
void control_generic (struct frame *fr)
138
int mode = MODE_STOPPED;
143
printf("@R MPG123\n");
148
FD_SET(STDIN_FILENO, &fds);
150
/* play frame if no command needs to be processed */
151
if (mode == MODE_PLAYING) {
152
n = select(32, &fds, NULL, NULL, &tv);
154
if (!read_frame(fr)) {
157
generic_sendmsg("P 0");
162
static char *modes[4] = {"Stereo", "Joint-Stereo", "Dual-Channel", "Single-Channel"};
163
generic_sendmsg("S %s %d %ld %s %d %d %d %d %d %d %d %d",
164
fr->mpeg25 ? "2.5" : (fr->lsf ? "2.0" : "1.0"),
166
freqs[fr->sampling_frequency],
171
fr->copyright ? 1 : 0,
172
fr->error_protection ? 1 : 0,
174
tabsel_123[fr->lsf][fr->lay-1][fr->bitrate_index],
179
generic_sendstat(fr, framecnt);
183
/* wait for command */
185
n = select(32, &fds, NULL, NULL, NULL);
193
fprintf(stderr, "Error waiting for command: %s\n", strerror(errno));
197
/* process command */
204
len = read(STDIN_FILENO, buf, sizeof(buf)-1);
209
fprintf(stderr, "Error reading command: %s\n", strerror(errno));
213
/* strip CR/LF at EOL */
214
while (len>0 && (buf[strlen(buf)-1] == '\n' || buf[strlen(buf)-1] == '\r')) {
215
buf[strlen(buf)-1] = 0;
219
/* continue if no command */
222
cmd = strtok(buf, " \t");
223
if (!cmd || !strlen(cmd))
227
if (!strcasecmp(cmd, "Q") || !strcasecmp(cmd, "QUIT"))
231
if (!strcasecmp(cmd, "L") || !strcasecmp(cmd, "LOAD")) {
233
filename = strtok(NULL, "");
234
if (mode != MODE_STOPPED) {
238
open_stream(filename, -1);
239
if (rd && rd->flags & READER_ID3TAG)
240
generic_sendinfoid3((char *)rd->id3buf);
242
generic_sendinfo(filename);
251
if (!strcasecmp(cmd, "S") || !strcasecmp(cmd, "STOP")) {
252
if (mode != MODE_STOPPED) {
255
generic_sendmsg("P 0");
261
if (!strcasecmp(cmd, "P") || !strcasecmp(cmd, "PAUSE")) {
262
if (mode == MODE_STOPPED)
264
if (mode == MODE_PLAYING) {
267
kill(buffer_pid, SIGSTOP);
268
generic_sendmsg("P 1");
272
kill(buffer_pid, SIGCONT);
273
generic_sendmsg("P 2");
279
if (!strcasecmp(cmd, "J") || !strcasecmp(cmd, "JUMP")) {
283
spos = strtok(NULL, " \t");
287
pos = framecnt + atoi(spos);
288
else if (spos[0] == '+')
289
pos = framecnt + atoi(spos+1);
293
if (mode == MODE_STOPPED)
296
if (pos < framecnt) {
299
for (framecnt=0; ok && framecnt<pos; framecnt++) {
305
for (; ok && framecnt<pos; framecnt++) {
314
/* unknown command */
315
generic_sendmsg("E Unknown command '%s'", cmd);
320
/* quit gracefully */
321
if (param.usebuffer) {
322
kill(buffer_pid, SIGINT);
323
xfermem_done_writer(buffermem);
324
waitpid(buffer_pid, NULL, 0);
325
xfermem_done(buffermem);
327
audio_flush(param.outmode, &ai);
330
if (param.outmode == DECODE_AUDIO)
332
if (param.outmode == DECODE_WAV)