|
Packit |
dd8086 |
/*
|
|
Packit |
dd8086 |
Copyright (C) 2005, 2006, 2008, 2009, 2010, 2011, 2012, 2017
|
|
Packit |
dd8086 |
Rocky Bernstein <rocky@gnu.org>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Adapted from Gerd Knorr's player.c program <kraxel@bytesex.org>
|
|
Packit |
dd8086 |
Copyright (C) 1997, 1998
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This program is free software: you can redistribute it and/or modify
|
|
Packit |
dd8086 |
it under the terms of the GNU General Public License as published by
|
|
Packit |
dd8086 |
the Free Software Foundation, either version 3 of the License, or
|
|
Packit |
dd8086 |
(at your option) any later version.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
This program is distributed in the hope that it will be useful,
|
|
Packit |
dd8086 |
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
dd8086 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit |
dd8086 |
GNU General Public License for more details.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
You should have received a copy of the GNU General Public License
|
|
Packit |
dd8086 |
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
dd8086 |
# include "config.h"
|
|
Packit |
dd8086 |
# define __CDIO_CONFIG_H__ 1
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_STDIO_H
|
|
Packit |
dd8086 |
#include <stdio.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_STDLIB_H
|
|
Packit |
dd8086 |
#include <stdlib.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_UNISTD_H
|
|
Packit |
dd8086 |
#include <unistd.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_STRING_H
|
|
Packit |
dd8086 |
#include <string.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_SYS_TIME_H
|
|
Packit |
dd8086 |
#include <sys/time.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
#include <cddb/cddb.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <signal.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_ERRNO_H
|
|
Packit |
dd8086 |
#include <errno.h>
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CURSES_H
|
|
Packit |
dd8086 |
# include <curses.h>
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
# ifdef HAVE_NCURSES_H
|
|
Packit |
dd8086 |
#include <ncurses.h>
|
|
Packit |
dd8086 |
# else
|
|
Packit |
dd8086 |
# ifdef HAVE_NCURSES_NCURSES_H
|
|
Packit |
dd8086 |
# include <ncurses/ncurses.h>
|
|
Packit |
dd8086 |
# else
|
|
Packit |
dd8086 |
# error "You need <curses.h> or
|
|
Packit |
dd8086 |
# endif
|
|
Packit |
dd8086 |
# endif
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include <cdio/cdio.h>
|
|
Packit |
dd8086 |
#include <cdio/mmc.h>
|
|
Packit |
dd8086 |
#include <cdio/util.h>
|
|
Packit |
dd8086 |
#include <cdio/cd_types.h>
|
|
Packit |
dd8086 |
#include <cdio/logging.h>
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#include "cddb.h"
|
|
Packit |
dd8086 |
#include "getopt.h"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void action(const char *psz_action);
|
|
Packit |
dd8086 |
static void display_cdinfo(CdIo_t *p_cdio, track_t i_tracks,
|
|
Packit |
dd8086 |
track_t i_first_track);
|
|
Packit |
dd8086 |
static void display_tracks(void);
|
|
Packit |
dd8086 |
static void get_cddb_track_info(track_t i_track);
|
|
Packit |
dd8086 |
static void get_cdtext_track_info(track_t i_track);
|
|
Packit |
dd8086 |
static void get_track_info(track_t i_track);
|
|
Packit |
dd8086 |
static bool play_track(track_t t1, track_t t2);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static CdIo_t *p_cdio_global; /* libcdio handle */
|
|
Packit |
dd8086 |
static driver_id_t driver_id = DRIVER_DEVICE;
|
|
Packit |
dd8086 |
static int b_sig = false; /* set on some signals */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* cdrom data */
|
|
Packit |
dd8086 |
static track_t i_first_track_global;
|
|
Packit |
dd8086 |
static track_t i_last_track;
|
|
Packit |
dd8086 |
static track_t i_first_audio_track;
|
|
Packit |
dd8086 |
static track_t i_last_audio_track;
|
|
Packit |
dd8086 |
static track_t i_last_display_track = CDIO_INVALID_TRACK;
|
|
Packit |
dd8086 |
static track_t i_tracks_global;
|
|
Packit |
dd8086 |
static msf_t toc[CDIO_CDROM_LEADOUT_TRACK+1];
|
|
Packit |
dd8086 |
static cdio_subchannel_t sub; /* subchannel last time read */
|
|
Packit |
dd8086 |
static int i_data; /* # of data tracks present ? */
|
|
Packit |
dd8086 |
static int start_track = 0;
|
|
Packit |
dd8086 |
static int stop_track = 0;
|
|
Packit |
dd8086 |
static int one_track = 0;
|
|
Packit |
dd8086 |
static int i_vol_port = 5; /* If 5, retrieve volume port.
|
|
Packit |
dd8086 |
Otherwise the port number 0..3
|
|
Packit |
dd8086 |
of a working volume port and
|
|
Packit |
dd8086 |
4 for no working port.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* settings which can be set from the command or interactively. */
|
|
Packit |
dd8086 |
static bool b_cd = false;
|
|
Packit |
dd8086 |
static bool auto_mode = false;
|
|
Packit |
dd8086 |
static bool b_verbose = false;
|
|
Packit |
dd8086 |
static bool debug = false;
|
|
Packit |
dd8086 |
static bool b_interactive = true;
|
|
Packit |
dd8086 |
static bool b_prefer_cdtext = true;
|
|
Packit |
dd8086 |
#ifdef CDDB_ADDED
|
|
Packit |
dd8086 |
static bool b_cddb = false; /* CDDB database present */
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
static bool b_db = false; /* we have a database at all */
|
|
Packit |
dd8086 |
static bool b_record = false; /* we have a record for
|
|
Packit |
dd8086 |
static the inserted CD */
|
|
Packit |
dd8086 |
static bool b_all_tracks = false; /* True if we display all tracks*/
|
|
Packit |
dd8086 |
static int8_t i_volume_level = -1; /* Valid range is 0..100 */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static char *psz_device_global=NULL;
|
|
Packit |
dd8086 |
static char *psz_program;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Info about songs and titles. The 0 entry will contain the disc info.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
typedef struct
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
char title[80];
|
|
Packit |
dd8086 |
char artist[80];
|
|
Packit |
dd8086 |
char length[8];
|
|
Packit |
dd8086 |
char ext_data[80];
|
|
Packit |
dd8086 |
bool b_cdtext; /* true if from CD-Text, false if from CDDB */
|
|
Packit |
dd8086 |
} cd_track_info_rec_t;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static cd_track_info_rec_t cd_info[CDIO_CD_MAX_TRACKS+2];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static char title[80];
|
|
Packit |
dd8086 |
static char artist[80];
|
|
Packit |
dd8086 |
static char genre[40];
|
|
Packit |
dd8086 |
static char category[40];
|
|
Packit |
dd8086 |
static char year[5];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static bool b_cdtext_title; /* true if from CD-Text, false if from CDDB */
|
|
Packit |
dd8086 |
static bool b_cdtext_artist; /* true if from CD-Text, false if from CDDB */
|
|
Packit |
dd8086 |
static bool b_cdtext_genre; /* true if from CD-Text, false if from CDDB */
|
|
Packit |
dd8086 |
#ifdef CDTEXT_CATEGORY_ADDED
|
|
Packit |
dd8086 |
static bool b_cdtext_category; /* true if from CD-Text, false if from CDDB */
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
static bool b_cdtext_year; /* true if from CD-Text, false if from CDDB */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static cdio_audio_volume_t audio_volume;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
static cddb_conn_t *p_conn = NULL;
|
|
Packit |
dd8086 |
static cddb_disc_t *p_cddb_disc = NULL;
|
|
Packit |
dd8086 |
static int i_cddb_matches = 0;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define MAX_KEY_STR 50
|
|
Packit |
dd8086 |
static const char key_bindings[][MAX_KEY_STR] = {
|
|
Packit |
dd8086 |
" right play / next track",
|
|
Packit |
dd8086 |
" left previous track",
|
|
Packit |
dd8086 |
" up/down 10 sec forward / back",
|
|
Packit |
dd8086 |
" 1-9 jump to track 1-9",
|
|
Packit |
dd8086 |
" 0 jump to track 10",
|
|
Packit |
dd8086 |
" F1-F20 jump to track 11-30",
|
|
Packit |
dd8086 |
" ",
|
|
Packit |
dd8086 |
" k, h, ? show this key help",
|
|
Packit |
dd8086 |
" l, toggle listing all tracks",
|
|
Packit |
dd8086 |
" e eject",
|
|
Packit |
dd8086 |
" c close tray",
|
|
Packit |
dd8086 |
" p, space pause / resume",
|
|
Packit |
dd8086 |
" s stop",
|
|
Packit |
dd8086 |
" q, ^C quit",
|
|
Packit |
dd8086 |
" x quit and continue playing",
|
|
Packit |
dd8086 |
" a toggle auto-mode",
|
|
Packit |
dd8086 |
" - decrease volume level",
|
|
Packit |
dd8086 |
" + increase volume level",
|
|
Packit |
dd8086 |
};
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static const unsigned int i_key_bindings = sizeof(key_bindings) / MAX_KEY_STR;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ---------------------------------------------------------------------- */
|
|
Packit |
dd8086 |
/* tty stuff */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
typedef enum {
|
|
Packit |
dd8086 |
LINE_STATUS = 0,
|
|
Packit |
dd8086 |
LINE_CDINFO = 1,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
LINE_ARTIST = 3,
|
|
Packit |
dd8086 |
LINE_CDNAME = 4,
|
|
Packit |
dd8086 |
LINE_GENRE = 5,
|
|
Packit |
dd8086 |
LINE_YEAR = 6,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
LINE_TRACK_PREV = 8,
|
|
Packit |
dd8086 |
LINE_TRACK_TITLE = 9,
|
|
Packit |
dd8086 |
LINE_TRACK_ARTIST = 10,
|
|
Packit |
dd8086 |
LINE_TRACK_NEXT = 11,
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
} track_line_t;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static unsigned int LINE_ACTION = 25;
|
|
Packit |
dd8086 |
static unsigned int COLS_LAST;
|
|
Packit |
dd8086 |
static char psz_action_line[300] = "";
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static int rounded_div(unsigned int i_a, unsigned int i_b)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
const unsigned int i_b_half=i_b/2;
|
|
Packit |
dd8086 |
return ((i_a)+i_b_half)/i_b;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Curses window initialization. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
tty_raw(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (!b_interactive) return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
initscr();
|
|
Packit |
dd8086 |
cbreak();
|
|
Packit |
dd8086 |
clear();
|
|
Packit |
dd8086 |
noecho();
|
|
Packit |
dd8086 |
#ifdef HAVE_KEYPAD
|
|
Packit |
dd8086 |
keypad(stdscr,1);
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
getmaxyx(stdscr, LINE_ACTION, COLS_LAST);
|
|
Packit |
dd8086 |
LINE_ACTION--;
|
|
Packit |
dd8086 |
refresh();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Curses window finalization. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
tty_restore(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (!b_interactive) return;
|
|
Packit |
dd8086 |
endwin();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define UNUSED(x) (void)(x)
|
|
Packit |
dd8086 |
/* Called when window is resized. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
sigwinch(int dummy)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
UNUSED(dummy);
|
|
Packit |
dd8086 |
tty_restore();
|
|
Packit |
dd8086 |
tty_raw();
|
|
Packit |
dd8086 |
action(NULL);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Signal handler - Ctrl-C and others. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
ctrlc(int signal_num)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
b_sig = true;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Timed wait on an event. */
|
|
Packit |
dd8086 |
static int
|
|
Packit |
dd8086 |
select_wait(int sec)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
struct timeval tv;
|
|
Packit |
dd8086 |
fd_set se;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
FD_ZERO(&se);
|
|
Packit |
dd8086 |
tv.tv_sec = sec;
|
|
Packit |
dd8086 |
tv.tv_usec = 0;
|
|
Packit |
dd8086 |
return select(1,&se,NULL,NULL,&tv;;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ---------------------------------------------------------------------- */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Display the action line. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
action(const char *psz_action)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (!b_interactive) {
|
|
Packit |
dd8086 |
if (b_verbose && psz_action)
|
|
Packit |
dd8086 |
fprintf(stderr,"action: %s\n", psz_action);
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!psz_action)
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
else if (psz_action && strlen(psz_action))
|
|
Packit |
dd8086 |
snprintf(psz_action_line, sizeof(psz_action_line), "action : %s",
|
|
Packit |
dd8086 |
psz_action);
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
snprintf(psz_action_line, sizeof(psz_action_line), "%s", "" );
|
|
Packit |
dd8086 |
mvprintw(LINE_ACTION, 0, psz_action_line);
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
refresh();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Display an error message.. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
xperror(const char *psz_msg)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
char line[80];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_interactive) {
|
|
Packit |
dd8086 |
if (b_verbose) {
|
|
Packit |
dd8086 |
fprintf(stderr, "error: ");
|
|
Packit |
dd8086 |
perror(psz_msg);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (b_verbose) {
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line), "%s: %s", psz_msg, strerror(errno));
|
|
Packit |
dd8086 |
attron(A_STANDOUT);
|
|
Packit |
dd8086 |
mvprintw(LINE_ACTION, 0, (char *) "error : %s", line);
|
|
Packit |
dd8086 |
attroff(A_STANDOUT);
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
refresh();
|
|
Packit |
dd8086 |
select_wait(3);
|
|
Packit |
dd8086 |
action("");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
finish(const char *psz_msg, int rc)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (b_interactive) {
|
|
Packit |
dd8086 |
attron(A_STANDOUT);
|
|
Packit |
dd8086 |
mvprintw(LINE_ACTION, 0, (char *) "%s, exiting...\n", psz_msg);
|
|
Packit |
dd8086 |
attroff(A_STANDOUT);
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
refresh();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
tty_restore();
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
if (p_conn) cddb_destroy(p_conn);
|
|
Packit |
dd8086 |
cddb_disc_destroy(p_cddb_disc);
|
|
Packit |
dd8086 |
libcddb_shutdown();
|
|
Packit |
dd8086 |
#endif /*HAVE_CDDB*/
|
|
Packit |
dd8086 |
cdio_destroy (p_cdio_global);
|
|
Packit |
dd8086 |
free (psz_device_global);
|
|
Packit |
dd8086 |
exit (rc);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ---------------------------------------------------------------------- */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Set all audio channels to level. level is assumed to be in the range
|
|
Packit |
dd8086 |
0..100.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
set_volume_level(CdIo_t *p_cdio, uint8_t i_level)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
const unsigned int i_new_level= rounded_div(i_level*256, 100);
|
|
Packit |
dd8086 |
unsigned int i;
|
|
Packit |
dd8086 |
driver_return_code_t rc;
|
|
Packit |
dd8086 |
for (i=0; i<=3; i++) {
|
|
Packit |
dd8086 |
audio_volume.level[i] = i_new_level;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
rc = cdio_audio_set_volume(p_cdio, &audio_volume);
|
|
Packit |
dd8086 |
if ( DRIVER_OP_SUCCESS != rc ) {
|
|
Packit |
dd8086 |
/* If we can't do a get volume, audio_volume.level is used as
|
|
Packit |
dd8086 |
a second-best guess. But if this set failed restore it to
|
|
Packit |
dd8086 |
an invalid value so we don't get confused and think that this
|
|
Packit |
dd8086 |
was set. */
|
|
Packit |
dd8086 |
for (i=0; i<=3; i++) {
|
|
Packit |
dd8086 |
audio_volume.level[i] = 0;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
/* Set i_vol_port so volume levels set above will get used. */
|
|
Packit |
dd8086 |
i_vol_port=0;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return rc;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Subtract one from the volume level. If we are at the minimum value,
|
|
Packit |
dd8086 |
* nothing is done.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
We used to wrap at the boundaries but this is probably wrong because
|
|
Packit |
dd8086 |
is assumes someone:
|
|
Packit |
dd8086 |
* looks at the display while listening,
|
|
Packit |
dd8086 |
* knows that 99 is the maximum value.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
See issue #33333
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
If the volume level is undefined, then this means we could not get
|
|
Packit |
dd8086 |
the current value and we'll' set it to 50 the midway point.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Return the status of setting the volume level. */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
decrease_volume_level(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (i_volume_level == -1) i_volume_level = 51;
|
|
Packit |
dd8086 |
if (i_volume_level <= 0) i_volume_level = 1;
|
|
Packit |
dd8086 |
return set_volume_level(p_cdio, --i_volume_level);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Add 1 to the volume level. If we are at the maximum value, nothing
|
|
Packit |
dd8086 |
is done.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
We used to wrap at the boundaries but this is probably wrong because
|
|
Packit |
dd8086 |
is assumes someone:
|
|
Packit |
dd8086 |
* looks at the display while listening,
|
|
Packit |
dd8086 |
* knows that 99 is the maximum value.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
See issue #33333
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
If volume level is undefined, then this means we could not get the
|
|
Packit |
dd8086 |
current value and we'll' set it to 50 the midway point.
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
Return the status of setting the volume level. */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
increase_volume_level(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
if (i_volume_level == -1) i_volume_level = 49;
|
|
Packit |
dd8086 |
if (i_volume_level <= 0) i_volume_level = 0;
|
|
Packit |
dd8086 |
if (i_volume_level > 98) i_volume_level = 98;
|
|
Packit |
dd8086 |
return set_volume_level(p_cdio, ++i_volume_level);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Stop playing audio CD */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
cd_stop(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
bool b_ok = true;
|
|
Packit |
dd8086 |
if (b_cd && p_cdio) {
|
|
Packit |
dd8086 |
action("stop...");
|
|
Packit |
dd8086 |
i_last_audio_track = CDIO_INVALID_TRACK;
|
|
Packit |
dd8086 |
b_ok = DRIVER_OP_SUCCESS == cdio_audio_stop(p_cdio);
|
|
Packit |
dd8086 |
if ( !b_ok )
|
|
Packit |
dd8086 |
xperror("stop");
|
|
Packit |
dd8086 |
if (b_all_tracks) display_tracks();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return b_ok;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Eject CD */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
cd_eject(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
bool b_ok = true;
|
|
Packit |
dd8086 |
if (p_cdio_global) {
|
|
Packit |
dd8086 |
cd_stop(p_cdio_global);
|
|
Packit |
dd8086 |
action("eject...");
|
|
Packit |
dd8086 |
b_ok = DRIVER_OP_SUCCESS == cdio_eject_media(&p_cdio_global);
|
|
Packit |
dd8086 |
if (!b_ok)
|
|
Packit |
dd8086 |
xperror("eject");
|
|
Packit |
dd8086 |
b_cd = false;
|
|
Packit |
dd8086 |
cdio_destroy (p_cdio_global);
|
|
Packit |
dd8086 |
p_cdio_global = NULL;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return b_ok;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Close CD tray */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
cd_close(const char *psz_device)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
bool b_ok = true;
|
|
Packit |
dd8086 |
if (!b_cd) {
|
|
Packit |
dd8086 |
action("close...");
|
|
Packit |
dd8086 |
b_ok = DRIVER_OP_SUCCESS == cdio_close_tray(psz_device, &driver_id);
|
|
Packit |
dd8086 |
if (!b_ok)
|
|
Packit |
dd8086 |
xperror("close");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return b_ok;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Pause playing audio CD */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
cd_pause(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
bool b_ok = true;
|
|
Packit |
dd8086 |
if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
|
|
Packit |
dd8086 |
b_ok = DRIVER_OP_SUCCESS == cdio_audio_pause(p_cdio);
|
|
Packit |
dd8086 |
if (!b_ok)
|
|
Packit |
dd8086 |
xperror("pause");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return b_ok;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Get status/track/position info of an audio CD */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
read_subchannel(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
bool b_ok = true;
|
|
Packit |
dd8086 |
if (!p_cdio) return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
b_ok = DRIVER_OP_SUCCESS == cdio_audio_read_subchannel(p_cdio, &sub);
|
|
Packit |
dd8086 |
if (!b_ok) {
|
|
Packit |
dd8086 |
xperror("read subchannel");
|
|
Packit |
dd8086 |
b_cd = 0;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (auto_mode && sub.audio_status == CDIO_MMC_READ_SUB_ST_COMPLETED)
|
|
Packit |
dd8086 |
cd_eject();
|
|
Packit |
dd8086 |
return b_ok;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
/** This routine is called by vcd routines on error.
|
|
Packit |
dd8086 |
Setup is done by init_input_plugin.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
cddb_log_handler (cddb_log_level_t level, const char message[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
switch (level) {
|
|
Packit |
dd8086 |
case CDDB_LOG_DEBUG:
|
|
Packit |
dd8086 |
case CDDB_LOG_INFO:
|
|
Packit |
dd8086 |
if (!b_verbose)
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
/* Fall through if to warn case */
|
|
Packit |
dd8086 |
case CDDB_LOG_WARN:
|
|
Packit |
dd8086 |
case CDDB_LOG_ERROR:
|
|
Packit |
dd8086 |
case CDDB_LOG_CRITICAL:
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
xperror(message);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* gl_default_cdio_log_handler (level, message); */
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
#endif /* HAVE_CDDB */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
get_cddb_disc_info(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
b_db = init_cddb(p_cdio, &p_conn, &p_cddb_disc, xperror, i_first_track_global,
|
|
Packit |
dd8086 |
i_tracks_global, &i_cddb_matches);
|
|
Packit |
dd8086 |
if (b_db) {
|
|
Packit |
dd8086 |
int i_year;
|
|
Packit |
dd8086 |
i_year = atoi(year);
|
|
Packit |
dd8086 |
cddb_disc_set_artist(p_cddb_disc, artist);
|
|
Packit |
dd8086 |
cddb_disc_set_title(p_cddb_disc, title);
|
|
Packit |
dd8086 |
cddb_disc_set_genre(p_cddb_disc, genre);
|
|
Packit |
dd8086 |
cddb_disc_set_year(p_cddb_disc, i_year);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
#endif /* HAVE_CDDB */
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define add_cdtext_disc_info(format_str, info_field, FIELD) \
|
|
Packit |
dd8086 |
if (cdtext_get_const(p_cdtext, FIELD, 0) && !strlen(info_field)) { \
|
|
Packit |
dd8086 |
snprintf(info_field, sizeof(info_field), format_str, \
|
|
Packit |
dd8086 |
cdtext_get_const(p_cdtext, FIELD, 0)); \
|
|
Packit |
dd8086 |
b_cdtext_ ## info_field = true; \
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
get_cdtext_disc_info(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
cdtext_t *p_cdtext = cdio_get_cdtext(p_cdio);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (p_cdtext) {
|
|
Packit |
dd8086 |
add_cdtext_disc_info("%s", title, CDTEXT_FIELD_TITLE);
|
|
Packit |
dd8086 |
add_cdtext_disc_info("%s", artist, CDTEXT_FIELD_PERFORMER);
|
|
Packit |
dd8086 |
add_cdtext_disc_info("%s", genre, CDTEXT_FIELD_GENRE);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
get_disc_info(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
b_db = false;
|
|
Packit |
dd8086 |
if (b_prefer_cdtext) {
|
|
Packit |
dd8086 |
get_cdtext_disc_info(p_cdio);
|
|
Packit |
dd8086 |
get_cddb_disc_info(p_cdio);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
get_cddb_disc_info(p_cdio);
|
|
Packit |
dd8086 |
get_cdtext_disc_info(p_cdio);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Read CD TOC and set CD information. */
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
read_toc(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
track_t i;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
action("read toc...");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memset(cd_info, 0, sizeof(cd_info));
|
|
Packit |
dd8086 |
title[0] = artist[0] = genre[0] = category[0] = year[0] = '\0';
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
i_first_track_global = cdio_get_first_track_num(p_cdio);
|
|
Packit |
dd8086 |
i_last_track = cdio_get_last_track_num(p_cdio);
|
|
Packit |
dd8086 |
i_tracks_global = cdio_get_num_tracks(p_cdio);
|
|
Packit |
dd8086 |
i_first_audio_track = i_first_track_global;
|
|
Packit |
dd8086 |
i_last_audio_track = i_last_track;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_audio_get_volume(p_cdio, &audio_volume);
|
|
Packit |
dd8086 |
for (i_vol_port=0; i_vol_port<4; i_vol_port++) {
|
|
Packit |
dd8086 |
if (audio_volume.level[i_vol_port] > 0) break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( CDIO_INVALID_TRACK == i_first_track_global ||
|
|
Packit |
dd8086 |
CDIO_INVALID_TRACK == i_last_track ) {
|
|
Packit |
dd8086 |
xperror("read toc header");
|
|
Packit |
dd8086 |
b_cd = false;
|
|
Packit |
dd8086 |
b_record = false;
|
|
Packit |
dd8086 |
i_last_display_track = CDIO_INVALID_TRACK;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
b_cd = true;
|
|
Packit |
dd8086 |
i_data = 0;
|
|
Packit |
dd8086 |
get_disc_info(p_cdio);
|
|
Packit |
dd8086 |
for (i = i_first_track_global; i <= i_last_track+1; i++) {
|
|
Packit |
dd8086 |
int s;
|
|
Packit |
dd8086 |
if ( !cdio_get_track_msf(p_cdio, i, &(toc[i])) )
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
xperror("read toc entry");
|
|
Packit |
dd8086 |
b_cd = false;
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if ( TRACK_FORMAT_AUDIO == cdio_get_track_format(p_cdio, i) ) {
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (i != i_first_track_global)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
s = cdio_audio_get_msf_seconds(&toc[i])
|
|
Packit |
dd8086 |
- cdio_audio_get_msf_seconds(&toc[i-1]);
|
|
Packit |
dd8086 |
snprintf(cd_info[i-1].length, sizeof(cd_info[0].length),
|
|
Packit |
dd8086 |
"%02d:%02d",
|
|
Packit |
dd8086 |
(uint8_t) (s / CDIO_CD_SECS_PER_MIN),
|
|
Packit |
dd8086 |
(uint8_t) (s % CDIO_CD_SECS_PER_MIN));
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
if ((i != i_last_track+1) ) {
|
|
Packit |
dd8086 |
i_data++;
|
|
Packit |
dd8086 |
if (i == i_first_track_global) {
|
|
Packit |
dd8086 |
if (i == i_last_track)
|
|
Packit |
dd8086 |
i_first_audio_track = CDIO_CDROM_LEADOUT_TRACK;
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
i_first_audio_track++;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
get_track_info(i);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
b_record = true;
|
|
Packit |
dd8086 |
read_subchannel(p_cdio);
|
|
Packit |
dd8086 |
if (auto_mode && sub.audio_status != CDIO_MMC_READ_SUB_ST_PLAY)
|
|
Packit |
dd8086 |
play_track(1, CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
action("");
|
|
Packit |
dd8086 |
if (!b_all_tracks)
|
|
Packit |
dd8086 |
display_cdinfo(p_cdio, i_tracks_global, i_first_track_global);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Play an audio track. */
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
play_track(track_t i_start_track, track_t i_end_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
bool b_ok = true;
|
|
Packit |
dd8086 |
char line[80];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_cd) {
|
|
Packit |
dd8086 |
read_toc(p_cdio_global);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
read_subchannel(p_cdio_global);
|
|
Packit |
dd8086 |
if (!b_cd || i_first_track_global == CDIO_CDROM_LEADOUT_TRACK)
|
|
Packit |
dd8086 |
return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (debug)
|
|
Packit |
dd8086 |
fprintf(stderr,"play tracks: %d-%d => ", i_start_track, i_end_track-1);
|
|
Packit |
dd8086 |
if (i_start_track < i_first_track_global) i_start_track = i_first_track_global;
|
|
Packit |
dd8086 |
if (i_start_track > i_last_audio_track) i_start_track = i_last_audio_track;
|
|
Packit |
dd8086 |
if (i_end_track < i_first_track_global) i_end_track = i_first_track_global;
|
|
Packit |
dd8086 |
if (i_end_track > i_last_audio_track) i_end_track = i_last_audio_track;
|
|
Packit |
dd8086 |
i_end_track++;
|
|
Packit |
dd8086 |
if (debug)
|
|
Packit |
dd8086 |
fprintf(stderr,"%d-%d\n",i_start_track, i_end_track-1);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cd_pause(p_cdio_global);
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line), "play track %d to track %d.",
|
|
Packit |
dd8086 |
i_start_track, i_end_track-1);
|
|
Packit |
dd8086 |
action(line);
|
|
Packit |
dd8086 |
b_ok = (DRIVER_OP_SUCCESS == cdio_audio_play_msf(p_cdio_global,
|
|
Packit |
dd8086 |
&(toc[i_start_track]),
|
|
Packit |
dd8086 |
&(toc[i_end_track])) );
|
|
Packit |
dd8086 |
if (!b_ok) xperror("play");
|
|
Packit |
dd8086 |
return b_ok;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
skip(int diff)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
msf_t start_msf;
|
|
Packit |
dd8086 |
int sec;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
read_subchannel(p_cdio_global);
|
|
Packit |
dd8086 |
if (!b_cd || i_first_track_global == CDIO_CDROM_LEADOUT_TRACK)
|
|
Packit |
dd8086 |
return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
sec = cdio_audio_get_msf_seconds(&sub.abs_addr);
|
|
Packit |
dd8086 |
sec += diff;
|
|
Packit |
dd8086 |
if (sec < 0) sec = 0;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
start_msf.m = cdio_to_bcd8(sec / CDIO_CD_SECS_PER_MIN);
|
|
Packit |
dd8086 |
start_msf.s = cdio_to_bcd8(sec % CDIO_CD_SECS_PER_MIN);
|
|
Packit |
dd8086 |
start_msf.f = 0;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cd_pause(p_cdio_global);
|
|
Packit |
dd8086 |
if ( DRIVER_OP_SUCCESS != cdio_audio_play_msf(p_cdio_global, &start_msf,
|
|
Packit |
dd8086 |
&(toc[i_last_audio_track])) )
|
|
Packit |
dd8086 |
xperror("play");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static bool
|
|
Packit |
dd8086 |
toggle_pause(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
bool b_ok = true;
|
|
Packit |
dd8086 |
if (!b_cd) return false;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (CDIO_MMC_READ_SUB_ST_PAUSED == sub.audio_status) {
|
|
Packit |
dd8086 |
b_ok = DRIVER_OP_SUCCESS != cdio_audio_resume(p_cdio_global);
|
|
Packit |
dd8086 |
if (!b_ok)
|
|
Packit |
dd8086 |
xperror("resume");
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
b_ok = DRIVER_OP_SUCCESS != cdio_audio_pause(p_cdio_global);
|
|
Packit |
dd8086 |
if (!b_ok)
|
|
Packit |
dd8086 |
xperror("pause");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
return b_ok;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/** Update windows with status and possibly track info. This used in
|
|
Packit |
dd8086 |
interactive playing not batch mode.
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
display_status(bool b_status_only)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
char line[80];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_interactive) return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_cd) {
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line), "no CD in drive (%s)", psz_device_global);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
} else if (i_first_track_global == CDIO_CDROM_LEADOUT_TRACK) {
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line), "CD has only data tracks");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
} else if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
|
|
Packit |
dd8086 |
sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
|
|
Packit |
dd8086 |
cdio_audio_get_volume(p_cdio_global, &audio_volume);
|
|
Packit |
dd8086 |
if (i_vol_port < 4) {
|
|
Packit |
dd8086 |
i_volume_level = rounded_div(audio_volume.level[i_vol_port]*100, 256);
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line),
|
|
Packit |
dd8086 |
"track %2d - %02x:%02x of %s (%02x:%02x abs) %s volume: %d",
|
|
Packit |
dd8086 |
sub.track, sub.rel_addr.m, sub.rel_addr.s,
|
|
Packit |
dd8086 |
cd_info[sub.track].length,
|
|
Packit |
dd8086 |
sub.abs_addr.m, sub.abs_addr.s,
|
|
Packit |
dd8086 |
mmc_audio_state2str(sub.audio_status),
|
|
Packit |
dd8086 |
i_volume_level);
|
|
Packit |
dd8086 |
} else
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line),
|
|
Packit |
dd8086 |
"track %2d - %02x:%02x of %s (%02x:%02x abs) %s",
|
|
Packit |
dd8086 |
sub.track, sub.rel_addr.m, sub.rel_addr.s,
|
|
Packit |
dd8086 |
cd_info[sub.track].length, sub.abs_addr.m, sub.abs_addr.s,
|
|
Packit |
dd8086 |
mmc_audio_state2str(sub.audio_status));
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line), "%s", mmc_audio_state2str(sub.audio_status));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
action(NULL);
|
|
Packit |
dd8086 |
mvprintw(LINE_STATUS, 0, (char *) "status%s: %s",
|
|
Packit |
dd8086 |
auto_mode ? "*" : " ", line);
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if ( !b_status_only && b_db && i_last_display_track != sub.track &&
|
|
Packit |
dd8086 |
(sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
|
|
Packit |
dd8086 |
sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) &&
|
|
Packit |
dd8086 |
b_cd) {
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (b_all_tracks)
|
|
Packit |
dd8086 |
display_tracks();
|
|
Packit |
dd8086 |
else {
|
|
Packit |
dd8086 |
const cd_track_info_rec_t *p_cd_info = &cd_info[sub.track];
|
|
Packit |
dd8086 |
i_last_display_track = sub.track;
|
|
Packit |
dd8086 |
if (i_first_audio_track != sub.track &&
|
|
Packit |
dd8086 |
strlen(cd_info[sub.track-1].title)) {
|
|
Packit |
dd8086 |
const cd_track_info_rec_t *p_cd_info_track = &cd_info[sub.track-1];
|
|
Packit |
dd8086 |
mvprintw(LINE_TRACK_PREV, 0, (char *) " track %2d title : %s [%s]",
|
|
Packit |
dd8086 |
sub.track-1, p_cd_info->title,
|
|
Packit |
dd8086 |
p_cd_info_track->b_cdtext ? "CD-Text" : "CDDB");
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
mvprintw(LINE_TRACK_PREV, 0, (char *) "%s","");
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (strlen(p_cd_info->title)) {
|
|
Packit |
dd8086 |
mvprintw(LINE_TRACK_TITLE, 0, (char *) ">track %2d title : %s [%s]",
|
|
Packit |
dd8086 |
sub.track, p_cd_info->title,
|
|
Packit |
dd8086 |
(char *) (p_cd_info->b_cdtext ? "CD-Text" : "CDDB"));
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (strlen(p_cd_info->artist)) {
|
|
Packit |
dd8086 |
mvprintw(LINE_TRACK_ARTIST, 0, (char *) ">track %2d artist: %s [%s]",
|
|
Packit |
dd8086 |
sub.track, p_cd_info->artist,
|
|
Packit |
dd8086 |
p_cd_info->b_cdtext ? "CD-Text" : "CDDB");
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (i_last_audio_track != sub.track &&
|
|
Packit |
dd8086 |
strlen(cd_info[sub.track+1].title)) {
|
|
Packit |
dd8086 |
const cd_track_info_rec_t *p_cd_info_track = &cd_info[sub.track+1];
|
|
Packit |
dd8086 |
mvprintw(LINE_TRACK_NEXT, 0, (char *) " track %2d title : %s [%s]",
|
|
Packit |
dd8086 |
sub.track+1, p_cd_info_track->title,
|
|
Packit |
dd8086 |
p_cd_info->b_cdtext ? "CD-Text" : "CDDB");
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
mvprintw(LINE_TRACK_NEXT, 0, (char *) "%s","");
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
clrtobot();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
action(NULL); /* Redisplay action line. */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
get_cddb_track_info(track_t i_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
cddb_track_t *t = cddb_disc_get_track(p_cddb_disc,
|
|
Packit |
dd8086 |
i_track - i_first_track_global);
|
|
Packit |
dd8086 |
if (t) {
|
|
Packit |
dd8086 |
cddb_track_set_title(t, title);
|
|
Packit |
dd8086 |
cddb_track_set_artist(t, artist);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define add_cdtext_track_info(format_str, info_field, FIELD) \
|
|
Packit |
dd8086 |
if (cdtext_get_const(p_cdtext, FIELD, i_track)) { \
|
|
Packit |
dd8086 |
snprintf(cd_info[i_track].info_field, \
|
|
Packit |
dd8086 |
sizeof(cd_info[i_track].info_field), \
|
|
Packit |
dd8086 |
format_str, cdtext_get_const(p_cdtext, FIELD, i_track)); \
|
|
Packit |
dd8086 |
cd_info[i_track].b_cdtext = true; \
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
get_cdtext_track_info(track_t i_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdtext_t *p_cdtext = cdio_get_cdtext(p_cdio_global);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (NULL != p_cdtext) {
|
|
Packit |
dd8086 |
add_cdtext_track_info("%s", title, CDTEXT_FIELD_TITLE);
|
|
Packit |
dd8086 |
add_cdtext_track_info("%s", artist, CDTEXT_FIELD_PERFORMER);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
get_track_info(track_t i_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (b_prefer_cdtext) {
|
|
Packit |
dd8086 |
get_cdtext_track_info(i_track);
|
|
Packit |
dd8086 |
get_cddb_track_info(i_track);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
get_cddb_track_info(i_track);
|
|
Packit |
dd8086 |
get_cdtext_track_info(i_track);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
#define display_line(LINE_NO, COL_NO, format_str, field) \
|
|
Packit |
dd8086 |
if (field != NULL && field[0]) { \
|
|
Packit |
dd8086 |
mvprintw(LINE_NO, COL_NO, (char *) format_str " [%s]", \
|
|
Packit |
dd8086 |
field, \
|
|
Packit |
dd8086 |
b_cdtext_ ## field ? "CD-Text": "CDDB"); \
|
|
Packit |
dd8086 |
clrtoeol(); \
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
display_cdinfo(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int len;
|
|
Packit |
dd8086 |
char line[80];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_interactive) return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_cd) snprintf(line, sizeof(line), "-");
|
|
Packit |
dd8086 |
else {
|
|
Packit |
dd8086 |
len = snprintf(line, sizeof(line), "%2u tracks (%02x:%02x min)",
|
|
Packit |
dd8086 |
(unsigned int) i_last_track,
|
|
Packit |
dd8086 |
toc[i_last_track+1].m, toc[i_last_track+1].s);
|
|
Packit |
dd8086 |
if (i_data && i_first_track != CDIO_CDROM_LEADOUT_TRACK)
|
|
Packit |
dd8086 |
snprintf(line+len, sizeof(line)-len, ", audio=%u-%u",
|
|
Packit |
dd8086 |
(unsigned int) i_first_audio_track,
|
|
Packit |
dd8086 |
(unsigned int) i_last_audio_track);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
display_line(LINE_ARTIST, 0, "CD Artist : %s", artist);
|
|
Packit |
dd8086 |
display_line(LINE_CDNAME, 0, "CD Title : %s", title);
|
|
Packit |
dd8086 |
display_line(LINE_GENRE, 0, "CD Genre : %s", genre);
|
|
Packit |
dd8086 |
display_line(LINE_YEAR, 0, "CD Year : %s", year);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
mvprintw(LINE_CDINFO, 0, (char *) "CD info: %s", line);
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
action(NULL);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* ---------------------------------------------------------------------- */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
usage(char *prog)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
fprintf(stderr,
|
|
Packit |
dd8086 |
"%s is a simple curses CD player. It can pick up artist,\n"
|
|
Packit |
dd8086 |
"CD name and song title from CD-Text info on the CD or\n"
|
|
Packit |
dd8086 |
"via CDDB.\n"
|
|
Packit |
dd8086 |
"\n"
|
|
Packit |
dd8086 |
"usage: %s [options] [device]\n"
|
|
Packit |
dd8086 |
"\n"
|
|
Packit |
dd8086 |
"default for to search for a CD-ROM device with a CD-DA loaded\n"
|
|
Packit |
dd8086 |
"\n"
|
|
Packit |
dd8086 |
"These command line options available:\n"
|
|
Packit |
dd8086 |
" -h print this help\n"
|
|
Packit |
dd8086 |
" -k print key mapping\n"
|
|
Packit |
dd8086 |
" -a start up in auto-mode\n"
|
|
Packit |
dd8086 |
" -v verbose\n"
|
|
Packit |
dd8086 |
"\n"
|
|
Packit |
dd8086 |
"for non-interactive use (only one) of these:\n"
|
|
Packit |
dd8086 |
" -l list tracks\n"
|
|
Packit |
dd8086 |
" -c print cover (PostScript to stdout)\n"
|
|
Packit |
dd8086 |
" -C close CD-ROM tray. If you use this option,\n"
|
|
Packit |
dd8086 |
" a CD-ROM device name must be specified.\n"
|
|
Packit |
dd8086 |
" -p play the whole CD\n"
|
|
Packit |
dd8086 |
" -t n play track >n<\n"
|
|
Packit |
dd8086 |
" -t a-b play all tracks between a and b (inclusive)\n"
|
|
Packit |
dd8086 |
" -L set volume level\n"
|
|
Packit |
dd8086 |
" -s stop playing\n"
|
|
Packit |
dd8086 |
" -S list audio subchannel information\n"
|
|
Packit |
dd8086 |
" -e eject cdrom\n"
|
|
Packit |
dd8086 |
"\n"
|
|
Packit |
dd8086 |
"That's all. Oh, maybe a few words more about the auto-mode. This\n"
|
|
Packit |
dd8086 |
"is the 'dont-touch-any-key' feature. You load a CD, player starts\n"
|
|
Packit |
dd8086 |
"to play it, and when it is done it ejects the CD. Start it that\n"
|
|
Packit |
dd8086 |
"way on a spare console and forget about it...\n"
|
|
Packit |
dd8086 |
"\n"
|
|
Packit |
dd8086 |
"(c) 1997-98 Gerd Knorr <kraxel@goldbach.in-berlin.de>\n"
|
|
Packit |
dd8086 |
"(c) 2005-2006, 2017 Rocky Bernstein <rocky@gnu.org>\n"
|
|
Packit |
dd8086 |
, prog, prog);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
print_keys(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
unsigned int i;
|
|
Packit |
dd8086 |
for (i=0; i < i_key_bindings; i++)
|
|
Packit |
dd8086 |
fprintf(stderr, "%s\n", key_bindings[i]);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
keypress_wait(CdIo_t *p_cdio)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
action("press any key to continue");
|
|
Packit |
dd8086 |
while (1 != select_wait(b_cd ? 1 : 5)) {
|
|
Packit |
dd8086 |
read_subchannel(p_cdio);
|
|
Packit |
dd8086 |
display_status(true);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
(void) getch();
|
|
Packit |
dd8086 |
clrtobot();
|
|
Packit |
dd8086 |
action(NULL);
|
|
Packit |
dd8086 |
if (!b_all_tracks)
|
|
Packit |
dd8086 |
display_cdinfo(p_cdio, i_tracks_global, i_first_track_global);
|
|
Packit |
dd8086 |
i_last_display_track = CDIO_INVALID_TRACK;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
list_keys(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
unsigned int i;
|
|
Packit |
dd8086 |
for (i=0; i < i_key_bindings; i++) {
|
|
Packit |
dd8086 |
mvprintw(LINE_TRACK_PREV+i, 0, (char *) "%s", key_bindings[i]);
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
keypress_wait(p_cdio_global);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
display_tracks(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
track_t i;
|
|
Packit |
dd8086 |
int i_line=0;
|
|
Packit |
dd8086 |
int s;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (b_record) {
|
|
Packit |
dd8086 |
i_line=LINE_TRACK_PREV - 1;
|
|
Packit |
dd8086 |
for (i = i_first_track_global; i <= i_last_track; i++) {
|
|
Packit |
dd8086 |
char line[200]="";
|
|
Packit |
dd8086 |
s = cdio_audio_get_msf_seconds(&toc[i+1])
|
|
Packit |
dd8086 |
- cdio_audio_get_msf_seconds(&toc[i]);
|
|
Packit |
dd8086 |
read_subchannel(p_cdio_global);
|
|
Packit |
dd8086 |
snprintf(line, sizeof(line), "%2d %02d:%02d %s ", i,
|
|
Packit |
dd8086 |
s / CDIO_CD_SECS_PER_MIN, s % CDIO_CD_SECS_PER_MIN,
|
|
Packit |
dd8086 |
( ( sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY ||
|
|
Packit |
dd8086 |
sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ) &&
|
|
Packit |
dd8086 |
sub.track == i ) ? "->" : " |");
|
|
Packit |
dd8086 |
if (b_record) {
|
|
Packit |
dd8086 |
if ( strlen(cd_info[i].title) )
|
|
Packit |
dd8086 |
strcat(line, cd_info[i].title);
|
|
Packit |
dd8086 |
if ( strlen(cd_info[i].artist) > 0 ) {
|
|
Packit |
dd8086 |
if (strlen(cd_info[i].title))
|
|
Packit |
dd8086 |
strcat(line, " / ");
|
|
Packit |
dd8086 |
strcat(line, cd_info[i].artist);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (sub.track == i) {
|
|
Packit |
dd8086 |
attron(A_STANDOUT);
|
|
Packit |
dd8086 |
mvprintw(i_line++, 0, line);
|
|
Packit |
dd8086 |
attroff(A_STANDOUT);
|
|
Packit |
dd8086 |
} else
|
|
Packit |
dd8086 |
mvprintw(i_line++, 0, line);
|
|
Packit |
dd8086 |
clrtoeol();
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/*
|
|
Packit |
dd8086 |
* PostScript 8bit latin1 handling
|
|
Packit |
dd8086 |
* stolen from mpage output -- please don't ask me how this works...
|
|
Packit |
dd8086 |
*/
|
|
Packit |
dd8086 |
#define ENCODING_TRICKS \
|
|
Packit |
dd8086 |
"/reencsmalldict 12 dict def\n" \
|
|
Packit |
dd8086 |
"/ReEncodeSmall { reencsmalldict begin\n" \
|
|
Packit |
dd8086 |
"/newcodesandnames exch def /newfontname exch def\n" \
|
|
Packit |
dd8086 |
"/basefontname exch def\n" \
|
|
Packit |
dd8086 |
"/basefontdict basefontname findfont def\n" \
|
|
Packit |
dd8086 |
"/newfont basefontdict maxlength dict def\n" \
|
|
Packit |
dd8086 |
"basefontdict { exch dup /FID ne { dup /Encoding eq\n" \
|
|
Packit |
dd8086 |
"{ exch dup length array copy newfont 3 1 roll put }\n" \
|
|
Packit |
dd8086 |
"{ exch newfont 3 1 roll put }\n" \
|
|
Packit |
dd8086 |
"ifelse }\n" \
|
|
Packit |
dd8086 |
"{ pop pop }\n" \
|
|
Packit |
dd8086 |
"ifelse } forall\n" \
|
|
Packit |
dd8086 |
"newfont /FontName newfontname put\n" \
|
|
Packit |
dd8086 |
"newcodesandnames aload pop newcodesandnames length 2 idiv\n" \
|
|
Packit |
dd8086 |
"{ newfont /Encoding get 3 1 roll put } repeat\n" \
|
|
Packit |
dd8086 |
"newfontname newfont definefont pop end } def\n" \
|
|
Packit |
dd8086 |
"/charvec [\n" \
|
|
Packit |
dd8086 |
"026 /Scaron\n" \
|
|
Packit |
dd8086 |
"027 /Ydieresis\n" \
|
|
Packit |
dd8086 |
"028 /Zcaron\n" \
|
|
Packit |
dd8086 |
"029 /scaron\n" \
|
|
Packit |
dd8086 |
"030 /trademark\n" \
|
|
Packit |
dd8086 |
"031 /zcaron\n" \
|
|
Packit |
dd8086 |
"032 /space\n" \
|
|
Packit |
dd8086 |
"033 /exclam\n" \
|
|
Packit |
dd8086 |
"034 /quotedbl\n" \
|
|
Packit |
dd8086 |
"035 /numbersign\n" \
|
|
Packit |
dd8086 |
"036 /dollar\n" \
|
|
Packit |
dd8086 |
"037 /percent\n" \
|
|
Packit |
dd8086 |
"038 /ampersand\n" \
|
|
Packit |
dd8086 |
"039 /quoteright\n" \
|
|
Packit |
dd8086 |
"040 /parenleft\n" \
|
|
Packit |
dd8086 |
"041 /parenright\n" \
|
|
Packit |
dd8086 |
"042 /asterisk\n" \
|
|
Packit |
dd8086 |
"043 /plus\n" \
|
|
Packit |
dd8086 |
"044 /comma\n" \
|
|
Packit |
dd8086 |
"045 /minus\n" \
|
|
Packit |
dd8086 |
"046 /period\n" \
|
|
Packit |
dd8086 |
"047 /slash\n" \
|
|
Packit |
dd8086 |
"048 /zero\n" \
|
|
Packit |
dd8086 |
"049 /one\n" \
|
|
Packit |
dd8086 |
"050 /two\n" \
|
|
Packit |
dd8086 |
"051 /three\n" \
|
|
Packit |
dd8086 |
"052 /four\n" \
|
|
Packit |
dd8086 |
"053 /five\n" \
|
|
Packit |
dd8086 |
"054 /six\n" \
|
|
Packit |
dd8086 |
"055 /seven\n" \
|
|
Packit |
dd8086 |
"056 /eight\n" \
|
|
Packit |
dd8086 |
"057 /nine\n" \
|
|
Packit |
dd8086 |
"058 /colon\n" \
|
|
Packit |
dd8086 |
"059 /semicolon\n" \
|
|
Packit |
dd8086 |
"060 /less\n" \
|
|
Packit |
dd8086 |
"061 /equal\n" \
|
|
Packit |
dd8086 |
"062 /greater\n" \
|
|
Packit |
dd8086 |
"063 /question\n" \
|
|
Packit |
dd8086 |
"064 /at\n" \
|
|
Packit |
dd8086 |
"065 /A\n" \
|
|
Packit |
dd8086 |
"066 /B\n" \
|
|
Packit |
dd8086 |
"067 /C\n" \
|
|
Packit |
dd8086 |
"068 /D\n" \
|
|
Packit |
dd8086 |
"069 /E\n" \
|
|
Packit |
dd8086 |
"070 /F\n" \
|
|
Packit |
dd8086 |
"071 /G\n" \
|
|
Packit |
dd8086 |
"072 /H\n" \
|
|
Packit |
dd8086 |
"073 /I\n" \
|
|
Packit |
dd8086 |
"074 /J\n" \
|
|
Packit |
dd8086 |
"075 /K\n" \
|
|
Packit |
dd8086 |
"076 /L\n" \
|
|
Packit |
dd8086 |
"077 /M\n" \
|
|
Packit |
dd8086 |
"078 /N\n" \
|
|
Packit |
dd8086 |
"079 /O\n" \
|
|
Packit |
dd8086 |
"080 /P\n" \
|
|
Packit |
dd8086 |
"081 /Q\n" \
|
|
Packit |
dd8086 |
"082 /R\n" \
|
|
Packit |
dd8086 |
"083 /S\n" \
|
|
Packit |
dd8086 |
"084 /T\n" \
|
|
Packit |
dd8086 |
"085 /U\n" \
|
|
Packit |
dd8086 |
"086 /V\n" \
|
|
Packit |
dd8086 |
"087 /W\n" \
|
|
Packit |
dd8086 |
"088 /X\n" \
|
|
Packit |
dd8086 |
"089 /Y\n" \
|
|
Packit |
dd8086 |
"090 /Z\n" \
|
|
Packit |
dd8086 |
"091 /bracketleft\n" \
|
|
Packit |
dd8086 |
"092 /backslash\n" \
|
|
Packit |
dd8086 |
"093 /bracketright\n" \
|
|
Packit |
dd8086 |
"094 /asciicircum\n" \
|
|
Packit |
dd8086 |
"095 /underscore\n" \
|
|
Packit |
dd8086 |
"096 /quoteleft\n" \
|
|
Packit |
dd8086 |
"097 /a\n" \
|
|
Packit |
dd8086 |
"098 /b\n" \
|
|
Packit |
dd8086 |
"099 /c\n" \
|
|
Packit |
dd8086 |
"100 /d\n" \
|
|
Packit |
dd8086 |
"101 /e\n" \
|
|
Packit |
dd8086 |
"102 /f\n" \
|
|
Packit |
dd8086 |
"103 /g\n" \
|
|
Packit |
dd8086 |
"104 /h\n" \
|
|
Packit |
dd8086 |
"105 /i\n" \
|
|
Packit |
dd8086 |
"106 /j\n" \
|
|
Packit |
dd8086 |
"107 /k\n" \
|
|
Packit |
dd8086 |
"108 /l\n" \
|
|
Packit |
dd8086 |
"109 /m\n" \
|
|
Packit |
dd8086 |
"110 /n\n" \
|
|
Packit |
dd8086 |
"111 /o\n" \
|
|
Packit |
dd8086 |
"112 /p\n" \
|
|
Packit |
dd8086 |
"113 /q\n" \
|
|
Packit |
dd8086 |
"114 /r\n" \
|
|
Packit |
dd8086 |
"115 /s\n" \
|
|
Packit |
dd8086 |
"116 /t\n" \
|
|
Packit |
dd8086 |
"117 /u\n" \
|
|
Packit |
dd8086 |
"118 /v\n" \
|
|
Packit |
dd8086 |
"119 /w\n" \
|
|
Packit |
dd8086 |
"120 /x\n" \
|
|
Packit |
dd8086 |
"121 /y\n" \
|
|
Packit |
dd8086 |
"122 /z\n" \
|
|
Packit |
dd8086 |
"123 /braceleft\n" \
|
|
Packit |
dd8086 |
"124 /bar\n" \
|
|
Packit |
dd8086 |
"125 /braceright\n" \
|
|
Packit |
dd8086 |
"126 /asciitilde\n" \
|
|
Packit |
dd8086 |
"127 /.notdef\n" \
|
|
Packit |
dd8086 |
"128 /fraction\n" \
|
|
Packit |
dd8086 |
"129 /florin\n" \
|
|
Packit |
dd8086 |
"130 /quotesingle\n" \
|
|
Packit |
dd8086 |
"131 /quotedblleft\n" \
|
|
Packit |
dd8086 |
"132 /guilsinglleft\n" \
|
|
Packit |
dd8086 |
"133 /guilsinglright\n" \
|
|
Packit |
dd8086 |
"134 /fi\n" \
|
|
Packit |
dd8086 |
"135 /fl\n" \
|
|
Packit |
dd8086 |
"136 /endash\n" \
|
|
Packit |
dd8086 |
"137 /dagger\n" \
|
|
Packit |
dd8086 |
"138 /daggerdbl\n" \
|
|
Packit |
dd8086 |
"139 /bullet\n" \
|
|
Packit |
dd8086 |
"140 /quotesinglbase\n" \
|
|
Packit |
dd8086 |
"141 /quotedblbase\n" \
|
|
Packit |
dd8086 |
"142 /quotedblright\n" \
|
|
Packit |
dd8086 |
"143 /ellipsis\n" \
|
|
Packit |
dd8086 |
"144 /dotlessi\n" \
|
|
Packit |
dd8086 |
"145 /grave\n" \
|
|
Packit |
dd8086 |
"146 /acute\n" \
|
|
Packit |
dd8086 |
"147 /circumflex\n" \
|
|
Packit |
dd8086 |
"148 /tilde\n" \
|
|
Packit |
dd8086 |
"149 /oe\n" \
|
|
Packit |
dd8086 |
"150 /breve\n" \
|
|
Packit |
dd8086 |
"151 /dotaccent\n" \
|
|
Packit |
dd8086 |
"152 /perthousand\n" \
|
|
Packit |
dd8086 |
"153 /emdash\n" \
|
|
Packit |
dd8086 |
"154 /ring\n" \
|
|
Packit |
dd8086 |
"155 /Lslash\n" \
|
|
Packit |
dd8086 |
"156 /OE\n" \
|
|
Packit |
dd8086 |
"157 /hungarumlaut\n" \
|
|
Packit |
dd8086 |
"158 /ogonek\n" \
|
|
Packit |
dd8086 |
"159 /caron\n" \
|
|
Packit |
dd8086 |
"160 /lslash\n" \
|
|
Packit |
dd8086 |
"161 /exclamdown\n" \
|
|
Packit |
dd8086 |
"162 /cent\n" \
|
|
Packit |
dd8086 |
"163 /sterling\n" \
|
|
Packit |
dd8086 |
"164 /currency\n" \
|
|
Packit |
dd8086 |
"165 /yen\n" \
|
|
Packit |
dd8086 |
"166 /brokenbar\n" \
|
|
Packit |
dd8086 |
"167 /section\n" \
|
|
Packit |
dd8086 |
"168 /dieresis\n" \
|
|
Packit |
dd8086 |
"169 /copyright\n" \
|
|
Packit |
dd8086 |
"170 /ordfeminine\n" \
|
|
Packit |
dd8086 |
"171 /guillemotleft\n" \
|
|
Packit |
dd8086 |
"172 /logicalnot\n" \
|
|
Packit |
dd8086 |
"173 /hyphen\n" \
|
|
Packit |
dd8086 |
"174 /registered\n" \
|
|
Packit |
dd8086 |
"175 /macron\n" \
|
|
Packit |
dd8086 |
"176 /degree\n" \
|
|
Packit |
dd8086 |
"177 /plusminus\n" \
|
|
Packit |
dd8086 |
"178 /twosuperior\n" \
|
|
Packit |
dd8086 |
"179 /threesuperior\n" \
|
|
Packit |
dd8086 |
"180 /acute\n" \
|
|
Packit |
dd8086 |
"181 /mu\n" \
|
|
Packit |
dd8086 |
"182 /paragraph\n" \
|
|
Packit |
dd8086 |
"183 /periodcentered\n" \
|
|
Packit |
dd8086 |
"184 /cedilla\n" \
|
|
Packit |
dd8086 |
"185 /onesuperior\n" \
|
|
Packit |
dd8086 |
"186 /ordmasculine\n" \
|
|
Packit |
dd8086 |
"187 /guillemotright\n" \
|
|
Packit |
dd8086 |
"188 /onequarter\n" \
|
|
Packit |
dd8086 |
"189 /onehalf\n" \
|
|
Packit |
dd8086 |
"190 /threequarters\n" \
|
|
Packit |
dd8086 |
"191 /questiondown\n" \
|
|
Packit |
dd8086 |
"192 /Agrave\n" \
|
|
Packit |
dd8086 |
"193 /Aacute\n" \
|
|
Packit |
dd8086 |
"194 /Acircumflex\n" \
|
|
Packit |
dd8086 |
"195 /Atilde\n" \
|
|
Packit |
dd8086 |
"196 /Adieresis\n" \
|
|
Packit |
dd8086 |
"197 /Aring\n" \
|
|
Packit |
dd8086 |
"198 /AE\n" \
|
|
Packit |
dd8086 |
"199 /Ccedilla\n" \
|
|
Packit |
dd8086 |
"200 /Egrave\n" \
|
|
Packit |
dd8086 |
"201 /Eacute\n" \
|
|
Packit |
dd8086 |
"202 /Ecircumflex\n" \
|
|
Packit |
dd8086 |
"203 /Edieresis\n" \
|
|
Packit |
dd8086 |
"204 /Igrave\n" \
|
|
Packit |
dd8086 |
"205 /Iacute\n" \
|
|
Packit |
dd8086 |
"206 /Icircumflex\n" \
|
|
Packit |
dd8086 |
"207 /Idieresis\n" \
|
|
Packit |
dd8086 |
"208 /Eth\n" \
|
|
Packit |
dd8086 |
"209 /Ntilde\n" \
|
|
Packit |
dd8086 |
"210 /Ograve\n" \
|
|
Packit |
dd8086 |
"211 /Oacute\n" \
|
|
Packit |
dd8086 |
"212 /Ocircumflex\n" \
|
|
Packit |
dd8086 |
"213 /Otilde\n" \
|
|
Packit |
dd8086 |
"214 /Odieresis\n" \
|
|
Packit |
dd8086 |
"215 /multiply\n" \
|
|
Packit |
dd8086 |
"216 /Oslash\n" \
|
|
Packit |
dd8086 |
"217 /Ugrave\n" \
|
|
Packit |
dd8086 |
"218 /Uacute\n" \
|
|
Packit |
dd8086 |
"219 /Ucircumflex\n" \
|
|
Packit |
dd8086 |
"220 /Udieresis\n" \
|
|
Packit |
dd8086 |
"221 /Yacute\n" \
|
|
Packit |
dd8086 |
"222 /Thorn\n" \
|
|
Packit |
dd8086 |
"223 /germandbls\n" \
|
|
Packit |
dd8086 |
"224 /agrave\n" \
|
|
Packit |
dd8086 |
"225 /aacute\n" \
|
|
Packit |
dd8086 |
"226 /acircumflex\n" \
|
|
Packit |
dd8086 |
"227 /atilde\n" \
|
|
Packit |
dd8086 |
"228 /adieresis\n" \
|
|
Packit |
dd8086 |
"229 /aring\n" \
|
|
Packit |
dd8086 |
"230 /ae\n" \
|
|
Packit |
dd8086 |
"231 /ccedilla\n" \
|
|
Packit |
dd8086 |
"232 /egrave\n" \
|
|
Packit |
dd8086 |
"233 /eacute\n" \
|
|
Packit |
dd8086 |
"234 /ecircumflex\n" \
|
|
Packit |
dd8086 |
"235 /edieresis\n" \
|
|
Packit |
dd8086 |
"236 /igrave\n" \
|
|
Packit |
dd8086 |
"237 /iacute\n" \
|
|
Packit |
dd8086 |
"238 /icircumflex\n" \
|
|
Packit |
dd8086 |
"239 /idieresis\n" \
|
|
Packit |
dd8086 |
"240 /eth\n" \
|
|
Packit |
dd8086 |
"241 /ntilde\n" \
|
|
Packit |
dd8086 |
"242 /ograve\n" \
|
|
Packit |
dd8086 |
"243 /oacute\n" \
|
|
Packit |
dd8086 |
"244 /ocircumflex\n" \
|
|
Packit |
dd8086 |
"245 /otilde\n" \
|
|
Packit |
dd8086 |
"246 /odieresis\n" \
|
|
Packit |
dd8086 |
"247 /divide\n" \
|
|
Packit |
dd8086 |
"248 /oslash\n" \
|
|
Packit |
dd8086 |
"249 /ugrave\n" \
|
|
Packit |
dd8086 |
"250 /uacute\n" \
|
|
Packit |
dd8086 |
"251 /ucircumflex\n" \
|
|
Packit |
dd8086 |
"252 /udieresis\n" \
|
|
Packit |
dd8086 |
"253 /yacute\n" \
|
|
Packit |
dd8086 |
"254 /thorn\n" \
|
|
Packit |
dd8086 |
"255 /ydieresis\n" \
|
|
Packit |
dd8086 |
"] def"
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
ps_list_tracks(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int i,s,y,sy;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_record) return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("%%!PS-Adobe-2.0\n");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* encoding tricks */
|
|
Packit |
dd8086 |
puts(ENCODING_TRICKS);
|
|
Packit |
dd8086 |
printf("/Times /TimesLatin1 charvec ReEncodeSmall\n");
|
|
Packit |
dd8086 |
printf("/Helvetica /HelveticaLatin1 charvec ReEncodeSmall\n");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Spaces */
|
|
Packit |
dd8086 |
printf("0 setlinewidth\n");
|
|
Packit |
dd8086 |
printf(" 100 100 moveto\n");
|
|
Packit |
dd8086 |
printf(" 390 0 rlineto\n");
|
|
Packit |
dd8086 |
printf(" 0 330 rlineto\n");
|
|
Packit |
dd8086 |
printf("-390 0 rlineto\n");
|
|
Packit |
dd8086 |
printf("closepath stroke\n");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf(" 100 100 moveto\n");
|
|
Packit |
dd8086 |
printf("-16 0 rlineto\n");
|
|
Packit |
dd8086 |
printf(" 0 330 rlineto\n");
|
|
Packit |
dd8086 |
printf("422 0 rlineto\n");
|
|
Packit |
dd8086 |
printf(" 0 -330 rlineto\n");
|
|
Packit |
dd8086 |
printf("closepath stroke\n");
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Title */
|
|
Packit |
dd8086 |
printf("/TimesLatin1 findfont 24 scalefont setfont\n");
|
|
Packit |
dd8086 |
printf("120 400 moveto (%s) show\n", title);
|
|
Packit |
dd8086 |
printf("/TimesLatin1 findfont 18 scalefont setfont\n");
|
|
Packit |
dd8086 |
printf("120 375 moveto (%s) show\n", artist);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* List */
|
|
Packit |
dd8086 |
sy = 250 / i_last_track;
|
|
Packit |
dd8086 |
if (sy > 14) sy = 14;
|
|
Packit |
dd8086 |
printf("/labelfont /TimesLatin1 findfont %d scalefont def\n",sy-2);
|
|
Packit |
dd8086 |
printf("/timefont /Courier findfont %d scalefont def\n",sy-2);
|
|
Packit |
dd8086 |
y = 350;
|
|
Packit |
dd8086 |
for (i = i_first_track_global; i <= i_last_track; i++, y -= sy) {
|
|
Packit |
dd8086 |
s = cdio_audio_get_msf_seconds(&toc[i+1])
|
|
Packit |
dd8086 |
- cdio_audio_get_msf_seconds(&toc[i]);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("labelfont setfont\n");
|
|
Packit |
dd8086 |
printf("120 %d moveto (%d) show\n", y, i);
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
char line[200]="";
|
|
Packit |
dd8086 |
if ( strlen(cd_info[i].title) )
|
|
Packit |
dd8086 |
strcat(line, cd_info[i].title);
|
|
Packit |
dd8086 |
if ( strlen(cd_info[i].artist) > 0 ) {
|
|
Packit |
dd8086 |
if (strlen(cd_info[i].title))
|
|
Packit |
dd8086 |
strcat(line, " / ");
|
|
Packit |
dd8086 |
strcat(line, cd_info[i].artist);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
printf("150 %d moveto (%s) show\n", y, line);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
printf("timefont setfont\n");
|
|
Packit |
dd8086 |
printf("420 %d moveto (%2d:%02d) show\n", y,
|
|
Packit |
dd8086 |
s / CDIO_CD_SECS_PER_MIN, s % CDIO_CD_SECS_PER_MIN);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Seitenbanner */
|
|
Packit |
dd8086 |
printf("/HelveticaLatin1 findfont 12 scalefont setfont\n");
|
|
Packit |
dd8086 |
printf(" 97 105 moveto (%s: %s) 90 rotate show -90 rotate\n",
|
|
Packit |
dd8086 |
artist, title);
|
|
Packit |
dd8086 |
printf("493 425 moveto (%s: %s) -90 rotate show 90 rotate\n",
|
|
Packit |
dd8086 |
artist, title);
|
|
Packit |
dd8086 |
printf("showpage\n");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
static void
|
|
Packit |
dd8086 |
list_tracks(void)
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int i,s;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_record) return;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
printf("Title : %s\n", title);
|
|
Packit |
dd8086 |
printf("Artist: %s\n", artist);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
for (i = i_first_track_global; i <= i_last_track; i++) {
|
|
Packit |
dd8086 |
s = cdio_audio_get_msf_seconds(&toc[i+1])
|
|
Packit |
dd8086 |
- cdio_audio_get_msf_seconds(&toc[i]);
|
|
Packit |
dd8086 |
printf("%2d: %s [%d seconds]\n", i, cd_info[i].title, s);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
typedef enum {
|
|
Packit |
dd8086 |
NO_OP=0,
|
|
Packit |
dd8086 |
PLAY_CD=1,
|
|
Packit |
dd8086 |
PLAY_TRACK=2,
|
|
Packit |
dd8086 |
STOP_PLAYING=3,
|
|
Packit |
dd8086 |
EJECT_CD=4,
|
|
Packit |
dd8086 |
CLOSE_CD=5,
|
|
Packit |
dd8086 |
SET_VOLUME=6,
|
|
Packit |
dd8086 |
LIST_SUBCHANNEL=7,
|
|
Packit |
dd8086 |
LIST_KEYS=8,
|
|
Packit |
dd8086 |
LIST_TRACKS=9,
|
|
Packit |
dd8086 |
PS_LIST_TRACKS=10,
|
|
Packit |
dd8086 |
TOGGLE_PAUSE=11,
|
|
Packit |
dd8086 |
EXIT_PROGRAM=12
|
|
Packit |
dd8086 |
} cd_operation_t;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
int
|
|
Packit |
dd8086 |
main(int argc, char *argv[])
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
int c, nostop=0;
|
|
Packit |
dd8086 |
char *h;
|
|
Packit |
dd8086 |
int i_rc = 0;
|
|
Packit |
dd8086 |
cd_operation_t cd_op = NO_OP; /* operation to do in non-interactive mode */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
psz_program = strrchr(argv[0],'/');
|
|
Packit |
dd8086 |
psz_program = psz_program ? psz_program+1 : argv[0];
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
memset(&cddb_opts, 0, sizeof(cddb_opts));
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
cdio_loglevel_default = CDIO_LOG_WARN;
|
|
Packit |
dd8086 |
/* parse options */
|
|
Packit |
dd8086 |
while ( 1 ) {
|
|
Packit |
dd8086 |
if (-1 == (c = getopt(argc, argv, "acCdehkplL:sSt:vx")))
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
switch (c) {
|
|
Packit |
dd8086 |
case 'v':
|
|
Packit |
dd8086 |
b_verbose = true;
|
|
Packit |
dd8086 |
if (cdio_loglevel_default > CDIO_LOG_INFO)
|
|
Packit |
dd8086 |
cdio_loglevel_default = CDIO_LOG_INFO;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'd':
|
|
Packit |
dd8086 |
debug = 1;
|
|
Packit |
dd8086 |
if (cdio_loglevel_default > CDIO_LOG_DEBUG)
|
|
Packit |
dd8086 |
cdio_loglevel_default = CDIO_LOG_DEBUG;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'a':
|
|
Packit |
dd8086 |
auto_mode = 1;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case 'L':
|
|
Packit |
dd8086 |
i_volume_level = atoi(optarg);
|
|
Packit |
dd8086 |
cd_op = SET_VOLUME;
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case 't':
|
|
Packit |
dd8086 |
if (NULL != (h = strchr(optarg,'-'))) {
|
|
Packit |
dd8086 |
*h = 0;
|
|
Packit |
dd8086 |
start_track = atoi(optarg);
|
|
Packit |
dd8086 |
stop_track = atoi(h+1)+1;
|
|
Packit |
dd8086 |
if (0 == start_track) start_track = 1;
|
|
Packit |
dd8086 |
if (1 == stop_track) stop_track = CDIO_CDROM_LEADOUT_TRACK;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
start_track = atoi(optarg);
|
|
Packit |
dd8086 |
stop_track = start_track+1;
|
|
Packit |
dd8086 |
one_track = 1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = PLAY_TRACK;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'p':
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = PLAY_CD;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'l':
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = LIST_TRACKS;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'C':
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = CLOSE_CD;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'c':
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = PS_LIST_TRACKS;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 's':
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = STOP_PLAYING;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'S':
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = LIST_SUBCHANNEL;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'e':
|
|
Packit |
dd8086 |
b_interactive = false;
|
|
Packit |
dd8086 |
cd_op = EJECT_CD;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'k':
|
|
Packit |
dd8086 |
print_keys();
|
|
Packit |
dd8086 |
exit(1);
|
|
Packit |
dd8086 |
case 'h':
|
|
Packit |
dd8086 |
usage(psz_program);
|
|
Packit |
dd8086 |
exit(1);
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
usage(psz_program);
|
|
Packit |
dd8086 |
exit(1);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (argc > optind) {
|
|
Packit |
dd8086 |
psz_device_global = strdup(argv[optind]);
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
char **ppsz_cdda_drives=NULL;
|
|
Packit |
dd8086 |
char **ppsz_all_cd_drives = cdio_get_devices_ret(&driver_id);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!ppsz_all_cd_drives) {
|
|
Packit |
dd8086 |
fprintf(stderr, "Can't find a CD-ROM drive\n");
|
|
Packit |
dd8086 |
exit(2);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
ppsz_cdda_drives = cdio_get_devices_with_cap(ppsz_all_cd_drives,
|
|
Packit |
dd8086 |
CDIO_FS_AUDIO, false);
|
|
Packit |
dd8086 |
if (!ppsz_cdda_drives || !ppsz_cdda_drives[0]) {
|
|
Packit |
dd8086 |
fprintf(stderr, "Can't find a CD-ROM drive with a CD-DA in it\n");
|
|
Packit |
dd8086 |
cdio_free_device_list(ppsz_all_cd_drives);
|
|
Packit |
dd8086 |
exit(3);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
psz_device_global = strdup(ppsz_cdda_drives[0]);
|
|
Packit |
dd8086 |
cdio_free_device_list(ppsz_all_cd_drives);
|
|
Packit |
dd8086 |
cdio_free_device_list(ppsz_cdda_drives);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (!b_interactive) {
|
|
Packit |
dd8086 |
b_sig = true;
|
|
Packit |
dd8086 |
nostop=1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
tty_raw();
|
|
Packit |
dd8086 |
signal(SIGINT,ctrlc);
|
|
Packit |
dd8086 |
signal(SIGQUIT,ctrlc);
|
|
Packit |
dd8086 |
signal(SIGTERM,ctrlc);
|
|
Packit |
dd8086 |
signal(SIGHUP,ctrlc);
|
|
Packit |
dd8086 |
signal(SIGWINCH, sigwinch);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (CLOSE_CD != cd_op) {
|
|
Packit |
dd8086 |
/* open device */
|
|
Packit |
dd8086 |
if (b_verbose)
|
|
Packit |
dd8086 |
fprintf(stderr, "open %s... ", psz_device_global);
|
|
Packit |
dd8086 |
p_cdio_global = cdio_open (psz_device_global, driver_id);
|
|
Packit |
dd8086 |
if (!p_cdio_global && cd_op != EJECT_CD) {
|
|
Packit |
dd8086 |
cd_close(psz_device_global);
|
|
Packit |
dd8086 |
p_cdio_global = cdio_open (psz_device_global, driver_id);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (p_cdio_global && b_verbose)
|
|
Packit |
dd8086 |
fprintf(stderr,"ok\n");
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (b_interactive) {
|
|
Packit |
dd8086 |
#ifdef HAVE_CDDB
|
|
Packit |
dd8086 |
cddb_log_set_handler (cddb_log_handler);
|
|
Packit |
dd8086 |
#else
|
|
Packit |
dd8086 |
;
|
|
Packit |
dd8086 |
#endif
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
b_sig = true;
|
|
Packit |
dd8086 |
nostop=1;
|
|
Packit |
dd8086 |
if (EJECT_CD == cd_op) {
|
|
Packit |
dd8086 |
i_rc = cd_eject() ? 0 : 1;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
switch (cd_op) {
|
|
Packit |
dd8086 |
case PS_LIST_TRACKS:
|
|
Packit |
dd8086 |
case LIST_TRACKS:
|
|
Packit |
dd8086 |
case PLAY_TRACK:
|
|
Packit |
dd8086 |
read_toc(p_cdio_global);
|
|
Packit |
dd8086 |
default:
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (p_cdio_global)
|
|
Packit |
dd8086 |
switch (cd_op) {
|
|
Packit |
dd8086 |
case STOP_PLAYING:
|
|
Packit |
dd8086 |
b_cd = true;
|
|
Packit |
dd8086 |
i_rc = cd_stop(p_cdio_global) ? 0 : 1;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case EJECT_CD:
|
|
Packit |
dd8086 |
/* Should have been handled above. */
|
|
Packit |
dd8086 |
cd_eject();
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case LIST_TRACKS:
|
|
Packit |
dd8086 |
list_tracks();
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case PS_LIST_TRACKS:
|
|
Packit |
dd8086 |
ps_list_tracks();
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case PLAY_TRACK:
|
|
Packit |
dd8086 |
/* play just this one track */
|
|
Packit |
dd8086 |
if (b_record) {
|
|
Packit |
dd8086 |
printf("%s / %s\n", artist, title);
|
|
Packit |
dd8086 |
if (one_track)
|
|
Packit |
dd8086 |
printf("%s\n", cd_info[start_track].title);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
i_rc = play_track(start_track, stop_track) ? 0 : 1;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case PLAY_CD:
|
|
Packit |
dd8086 |
if (b_record)
|
|
Packit |
dd8086 |
printf("%s / %s\n", artist, title);
|
|
Packit |
dd8086 |
play_track(1,CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case SET_VOLUME:
|
|
Packit |
dd8086 |
i_rc = set_volume_level(p_cdio_global, i_volume_level);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
case LIST_SUBCHANNEL:
|
|
Packit |
dd8086 |
if (read_subchannel(p_cdio_global)) {
|
|
Packit |
dd8086 |
if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
|
|
Packit |
dd8086 |
sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
|
|
Packit |
dd8086 |
{
|
|
Packit |
dd8086 |
printf("track %2d - %02x:%02x (%02x:%02x abs) ",
|
|
Packit |
dd8086 |
sub.track, sub.rel_addr.m, sub.rel_addr.s,
|
|
Packit |
dd8086 |
sub.abs_addr.m, sub.abs_addr.s);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
printf("drive state: %s\n",
|
|
Packit |
dd8086 |
mmc_audio_state2str(sub.audio_status));
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
i_rc = 1;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case CLOSE_CD: /* Handled below */
|
|
Packit |
dd8086 |
case LIST_KEYS:
|
|
Packit |
dd8086 |
case TOGGLE_PAUSE:
|
|
Packit |
dd8086 |
case EXIT_PROGRAM:
|
|
Packit |
dd8086 |
case NO_OP:
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
else if (CLOSE_CD == cd_op) {
|
|
Packit |
dd8086 |
i_rc = (DRIVER_OP_SUCCESS == cdio_close_tray(psz_device_global, NULL))
|
|
Packit |
dd8086 |
? 0 : 1;
|
|
Packit |
dd8086 |
} else {
|
|
Packit |
dd8086 |
fprintf(stderr,"no CD in drive (%s)\n", psz_device_global);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
/* Play all tracks *unless* we have a play or paused status
|
|
Packit |
dd8086 |
already. */
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
read_subchannel(p_cdio_global);
|
|
Packit |
dd8086 |
if (sub.audio_status != CDIO_MMC_READ_SUB_ST_PAUSED &&
|
|
Packit |
dd8086 |
sub.audio_status != CDIO_MMC_READ_SUB_ST_PLAY)
|
|
Packit |
dd8086 |
play_track(1, CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
while ( !b_sig ) {
|
|
Packit |
dd8086 |
int key;
|
|
Packit |
dd8086 |
if (!b_cd) read_toc(p_cdio_global);
|
|
Packit |
dd8086 |
read_subchannel(p_cdio_global);
|
|
Packit |
dd8086 |
display_status(false);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
if (1 == select_wait(b_cd ? 1 : 5)) {
|
|
Packit |
dd8086 |
switch (key = getch()) {
|
|
Packit |
dd8086 |
case '-':
|
|
Packit |
dd8086 |
decrease_volume_level(p_cdio_global);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case '+':
|
|
Packit |
dd8086 |
increase_volume_level(p_cdio_global);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'A':
|
|
Packit |
dd8086 |
case 'a':
|
|
Packit |
dd8086 |
auto_mode = !auto_mode;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'X':
|
|
Packit |
dd8086 |
case 'x':
|
|
Packit |
dd8086 |
nostop=1;
|
|
Packit |
dd8086 |
/* fall through */
|
|
Packit |
dd8086 |
case 'Q':
|
|
Packit |
dd8086 |
case 'q':
|
|
Packit |
dd8086 |
b_sig = true;
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'E':
|
|
Packit |
dd8086 |
case 'e':
|
|
Packit |
dd8086 |
cd_eject();
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 's':
|
|
Packit |
dd8086 |
cd_stop(p_cdio_global);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'C':
|
|
Packit |
dd8086 |
case 'c':
|
|
Packit |
dd8086 |
cd_close(psz_device_global);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'L':
|
|
Packit |
dd8086 |
case 'l':
|
|
Packit |
dd8086 |
b_all_tracks = !b_all_tracks;
|
|
Packit |
dd8086 |
if (b_all_tracks)
|
|
Packit |
dd8086 |
display_tracks();
|
|
Packit |
dd8086 |
else {
|
|
Packit |
dd8086 |
i_last_display_track = CDIO_INVALID_TRACK;
|
|
Packit |
dd8086 |
display_cdinfo(p_cdio_global, i_tracks_global, i_first_track_global);
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case 'K':
|
|
Packit |
dd8086 |
case 'k':
|
|
Packit |
dd8086 |
case 'h':
|
|
Packit |
dd8086 |
case 'H':
|
|
Packit |
dd8086 |
case '?':
|
|
Packit |
dd8086 |
list_keys();
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case ' ':
|
|
Packit |
dd8086 |
case 'P':
|
|
Packit |
dd8086 |
case 'p':
|
|
Packit |
dd8086 |
toggle_pause();
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case KEY_RIGHT:
|
|
Packit |
dd8086 |
if (b_cd &&
|
|
Packit |
dd8086 |
(sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
|
|
Packit |
dd8086 |
sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY))
|
|
Packit |
dd8086 |
play_track(sub.track+1, CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
else
|
|
Packit |
dd8086 |
play_track(1,CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case KEY_LEFT:
|
|
Packit |
dd8086 |
if (b_cd &&
|
|
Packit |
dd8086 |
(sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
|
|
Packit |
dd8086 |
sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY))
|
|
Packit |
dd8086 |
play_track(sub.track-1,CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case KEY_UP:
|
|
Packit |
dd8086 |
if (b_cd && sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY)
|
|
Packit |
dd8086 |
skip(10);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case KEY_DOWN:
|
|
Packit |
dd8086 |
if (b_cd && sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY)
|
|
Packit |
dd8086 |
skip(-10);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case '1':
|
|
Packit |
dd8086 |
case '2':
|
|
Packit |
dd8086 |
case '3':
|
|
Packit |
dd8086 |
case '4':
|
|
Packit |
dd8086 |
case '5':
|
|
Packit |
dd8086 |
case '6':
|
|
Packit |
dd8086 |
case '7':
|
|
Packit |
dd8086 |
case '8':
|
|
Packit |
dd8086 |
case '9':
|
|
Packit |
dd8086 |
play_track(key - '0', CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case '0':
|
|
Packit |
dd8086 |
play_track(10, CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
case KEY_F(1):
|
|
Packit |
dd8086 |
case KEY_F(2):
|
|
Packit |
dd8086 |
case KEY_F(3):
|
|
Packit |
dd8086 |
case KEY_F(4):
|
|
Packit |
dd8086 |
case KEY_F(5):
|
|
Packit |
dd8086 |
case KEY_F(6):
|
|
Packit |
dd8086 |
case KEY_F(7):
|
|
Packit |
dd8086 |
case KEY_F(8):
|
|
Packit |
dd8086 |
case KEY_F(9):
|
|
Packit |
dd8086 |
case KEY_F(10):
|
|
Packit |
dd8086 |
case KEY_F(11):
|
|
Packit |
dd8086 |
case KEY_F(12):
|
|
Packit |
dd8086 |
case KEY_F(13):
|
|
Packit |
dd8086 |
case KEY_F(14):
|
|
Packit |
dd8086 |
case KEY_F(15):
|
|
Packit |
dd8086 |
case KEY_F(16):
|
|
Packit |
dd8086 |
case KEY_F(17):
|
|
Packit |
dd8086 |
case KEY_F(18):
|
|
Packit |
dd8086 |
case KEY_F(19):
|
|
Packit |
dd8086 |
case KEY_F(20):
|
|
Packit |
dd8086 |
play_track(key - KEY_F(1) + 11, CDIO_CDROM_LEADOUT_TRACK);
|
|
Packit |
dd8086 |
break;
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
}
|
|
Packit |
dd8086 |
if (!nostop) cd_stop(p_cdio_global);
|
|
Packit |
dd8086 |
tty_restore();
|
|
Packit |
dd8086 |
finish("bye", i_rc);
|
|
Packit |
dd8086 |
|
|
Packit |
dd8086 |
return 0; /* keep compiler happy */
|
|
Packit |
dd8086 |
}
|