Curses improvements. Can now show key/help and list of tracks.

This commit is contained in:
rocky
2005-03-12 16:45:44 +00:00
parent 76369d47fd
commit 6accca02b9

View File

@@ -1,5 +1,5 @@
/*
$Id: cdda-player.c,v 1.5 2005/03/12 06:02:36 rocky Exp $
$Id: cdda-player.c,v 1.6 2005/03/12 16:45:44 rocky Exp $
Copyright (C) 2005 Rocky Bernstein <rocky@panix.com>
@@ -80,6 +80,7 @@ track_t i_first_track;
track_t i_last_track;
track_t i_first_audio_track;
track_t i_last_audio_track;
track_t i_last_display_track = CDIO_INVALID_TRACK;
track_t i_tracks;
msf_t toc[CDIO_CDROM_LEADOUT_TRACK+1];
cdio_subchannel_t sub; /* subchannel last time read */
@@ -107,8 +108,9 @@ typedef enum {
STOP_PLAYING=3,
EJECT_CD=4,
CLOSE_CD=5,
LIST_TRACKS=6,
PS_LIST_TRACKS=7
LIST_KEYS=6,
LIST_TRACKS=7,
PS_LIST_TRACKS=8
} cd_operation_t;
char *psz_device=NULL;
@@ -120,6 +122,7 @@ typedef struct
{
char title[80];
char artist[80];
char length[8];
char ext_data[80];
bool b_cdtext; /* true if from CD-Text, false if from CDDB */
} cd_track_info_rec_t;
@@ -143,39 +146,50 @@ cddb_disc_t *p_cddb_disc = NULL;
int i_cddb_matches = 0;
#endif
const char key_bindings[] =
" right play / next track\n"
" left previous track\n"
" up 10 sec forward\n"
" down 10 sec back\n"
" 1-9 jump to track 1-9\n"
" 0 jump to track 10\n"
" F1-F20 jump to track 11-30\n"
"\n"
" e eject\n"
" c close tray\n"
" p, space pause / resume\n"
" s stop\n"
" q, ^C quit\n"
" x quit and continue playing\n"
" a toggle auto-mode\n";
#define MAX_KEY_STR 50
const char key_bindings[][MAX_KEY_STR] = {
" right play / next track",
" left previous track",
" up 10 sec forward",
" down 10 sec back",
" 1-9 jump to track 1-9",
" 0 jump to track 10",
" F1-F20 jump to track 11-30",
" ",
" k, h, ? show this key help",
" e eject",
" c close tray",
" p, space pause / resume",
" s stop",
" q, ^C quit",
" x quit and continue playing",
" a toggle auto-mode",
};
const unsigned int i_key_bindings = sizeof(key_bindings) / MAX_KEY_STR;
/* ---------------------------------------------------------------------- */
/* tty stuff */
#define LINE_STATUS 0
#define LINE_CDINFO 1
typedef enum {
LINE_STATUS = 0,
LINE_CDINFO = 1,
LINE_ARTIST = 3,
LINE_CDNAME = 4,
LINE_GENRE = 5,
LINE_YEAR = 6,
LINE_TRACK_PREV = 8,
LINE_TRACK_TITLE = 9,
LINE_TRACK_ARTIST = 10,
LINE_TRACK_NEXT = 11,
LINE_ACTION = 24,
LINE_LAST = 25
} track_line_t;
#define LINE_ARTIST 3
#define LINE_CDNAME 4
#define LINE_GENRE 5
#define LINE_YEAR 6
#define LINE_TRACK_A 7
#define LINE_TRACK_T 8
#define LINE_ACTION 10
#define LINE_LAST 11
static void
tty_raw()
@@ -219,36 +233,37 @@ select_wait(int sec)
/* ---------------------------------------------------------------------- */
static void
action(const char *txt)
action(const char *psz_action)
{
if (!interactive) {
if (b_verbose)
fprintf(stderr,"action: %s\n",txt);
fprintf(stderr,"action: %s\n", psz_action);
return;
}
if (txt && strlen(txt))
mvprintw(LINE_ACTION,0,"action : %-70s\n",txt);
if (psz_action && strlen(psz_action))
mvprintw(LINE_ACTION,0,"action : %s\n", psz_action);
else
mvprintw(LINE_ACTION,0,"%-79s\n","");
mvprintw(LINE_ACTION,0,"");
clrtoeol();
refresh();
}
static void inline
xperror(const char *txt)
xperror(const char *psz_msg)
{
char line[80];
if (!interactive) {
if (b_verbose) {
fprintf(stderr,"error: ");
perror(txt);
fprintf(stderr, "error: ");
perror(psz_msg);
}
return;
}
if (b_verbose) {
sprintf(line,"%s: %s",txt,strerror(errno));
sprintf(line,"%s: %s",psz_msg,strerror(errno));
mvprintw(LINE_ACTION, 0, "error : %-70s", line);
refresh();
select_wait(3);
@@ -257,10 +272,10 @@ xperror(const char *txt)
}
static void
oops(const char *txt, int rc)
oops(const char *psz_msg, int rc)
{
if(interactive) {
mvprintw(LINE_LAST, 0, "%s, exiting...\n", txt);
if (interactive) {
mvprintw(LINE_LAST, 0, "%s, exiting...\n", psz_msg);
refresh();
}
tty_restore();
@@ -279,6 +294,7 @@ cd_stop(CdIo_t *p_cdio)
{
if (b_cd && p_cdio) {
action("stop...");
i_last_audio_track = CDIO_INVALID_TRACK;
if (DRIVER_OP_SUCCESS != cdio_audio_stop(p_cdio))
xperror("stop");
}
@@ -331,7 +347,7 @@ read_subchannel(CdIo_t *p_cdio)
#define add_cddb_disc_info(format_str, field) \
if (p_cddb_disc->field) \
snprintf(field, sizeof(field)-1, format_str, p_cddb_disc->field);
snprintf(field, sizeof(field), format_str, p_cddb_disc->field);
static void
read_toc(CdIo_t *p_cdio)
@@ -354,6 +370,7 @@ read_toc(CdIo_t *p_cdio)
xperror("read toc header");
b_cd = false;
b_record = false;
i_last_display_track = CDIO_INVALID_TRACK;
} else {
b_cd = true;
data = 0;
@@ -364,21 +381,32 @@ read_toc(CdIo_t *p_cdio)
add_cddb_disc_info("%s", artist);
add_cddb_disc_info("%s", title);
add_cddb_disc_info("%s", genre);
add_cddb_disc_info("%5d", year);
add_cddb_disc_info("%4d", year);
}
#else
b_db = false;
#endif
for (i = i_first_track; i <= i_last_track+1; i++) {
int s;
if ( !cdio_get_track_msf(p_cdio, i, &(toc[i])) )
{
xperror("read toc entry");
b_cd = false;
return;
}
if ( (TRACK_FORMAT_AUDIO != cdio_get_track_format(p_cdio, i)) &&
(i != i_last_track+1) ) {
if ( TRACK_FORMAT_AUDIO == cdio_get_track_format(p_cdio, i) ) {
if (i != i_first_track)
{
s = cdio_audio_get_msf_seconds(&toc[i])
- cdio_audio_get_msf_seconds(&toc[i-1]);
snprintf(cd_info[i].length, sizeof(cd_info[0].length),
"%02d:%02d",
s / CDIO_CD_SECS_PER_MIN, s % CDIO_CD_SECS_PER_MIN);
}
} else {
if ((i != i_last_track+1) ) {
data++;
if (i == i_first_track) {
if (i == i_last_track)
@@ -387,6 +415,7 @@ read_toc(CdIo_t *p_cdio)
i_first_audio_track++;
}
}
}
get_cddb_track_info(i);
}
b_record = true;
@@ -394,6 +423,7 @@ read_toc(CdIo_t *p_cdio)
if (auto_mode && sub.audio_status != CDIO_MMC_READ_SUB_ST_PLAY)
play_track(1, CDIO_CDROM_LEADOUT_TRACK);
}
action(NULL);
display_cdinfo(p_cdio, i_tracks, i_first_track);
}
@@ -481,34 +511,59 @@ display_status()
} else if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
sprintf(line,"%2d - %02d:%02d (%02d:%02d abs) %-10s",
sprintf(line,"track %2d - %02d:%02d of %s (%02d:%02d abs) %-10s",
sub.track,
sub.rel_addr.msf.m,
sub.rel_addr.msf.s,
cd_info[sub.track].length,
sub.abs_addr.msf.m,
sub.abs_addr.msf.s,
mmc_audio_state2str(sub.audio_status));
} else {
sprintf(line,"%s", mmc_audio_state2str(sub.audio_status));
}
mvprintw(LINE_STATUS,0,"status%s: %-70s",auto_mode ? "*" : " ", line);
mvprintw(LINE_STATUS, 0, "status%s: %s",auto_mode ? "*" : " ", line);
clrtoeol();
if (b_db) {
if ((sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
if (b_db && i_last_display_track != sub.track &&
(sub.audio_status == CDIO_MMC_READ_SUB_ST_PAUSED ||
sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) &&
b_cd) {
if (strlen(cd_info[sub.track].artist))
mvprintw(LINE_TRACK_A, 0,"track artist : %-70s",
cd_info[sub.track].artist);
if (strlen(cd_info[sub.track].title))
mvprintw(LINE_TRACK_T, 0,"track title : %-70s",
cd_info[sub.track].title);
i_last_display_track = sub.track;
if (i_first_audio_track != sub.track &&
strlen(cd_info[sub.track-1].title)) {
mvprintw(LINE_TRACK_PREV, 0, "track %2d title : %s",
sub.track-1, cd_info[sub.track-1].title);
clrtoeol();
} else {
mvprintw(LINE_TRACK_PREV, 0, "%s","");
clrtoeol();
}
if (strlen(cd_info[sub.track].title)) {
mvprintw(LINE_TRACK_TITLE, 0, "track %2d title : %s",
sub.track, cd_info[sub.track].title);
clrtoeol();
}
if (strlen(cd_info[sub.track].artist)) {
mvprintw(LINE_TRACK_ARTIST, 0, "track %2d artist : %s",
sub.track, cd_info[sub.track].artist);
clrtoeol();
}
if (i_last_audio_track != sub.track &&
strlen(cd_info[sub.track+1].title)) {
mvprintw(LINE_TRACK_NEXT, 0, "track %2d title : %s",
sub.track+1, cd_info[sub.track+1].title);
clrtoeol();
} else {
mvprintw(LINE_TRACK_NEXT, 0, "%s","");
clrtoeol();
}
clrtobot();
}
refresh();
action(NULL);
}
#define add_cddb_track_info(format_str, field) \
@@ -553,10 +608,10 @@ display_cdinfo(CdIo_t *p_cdio, track_t i_tracks, track_t i_first_track)
sprintf(line+len,", audio=%u-%u", (unsigned int) i_first_audio_track,
(unsigned int) i_last_audio_track);
display_line(LINE_ARTIST, 0, "Artist : %-70s", artist);
display_line(LINE_CDNAME, 0, "CD : %-70s", title);
display_line(LINE_GENRE, 0, "Genre : %-40s", genre);
display_line(LINE_YEAR, 0, "Year : %5s", year);
display_line(LINE_ARTIST, 0, "CD Artist : %-70s", artist);
display_line(LINE_CDNAME, 0, "CD Title : %-70s", title);
display_line(LINE_GENRE, 0, "CD Genre : %-40s", genre);
display_line(LINE_YEAR, 0, "CD Year : %4s", year);
}
mvprintw(LINE_CDINFO, 0, "CD info: %-70s", line);
@@ -608,48 +663,68 @@ usage(char *prog)
}
static void
keys()
print_keys()
{
fprintf(stderr, key_bindings);
unsigned int i;
for (i=0; i < i_key_bindings; i++)
fprintf(stderr, "%s\n", key_bindings[i]);
}
static void
tracklist(void)
list_keys()
{
unsigned int i;
for (i=0; i < i_key_bindings; i++) {
mvprintw(LINE_TRACK_PREV+i, 0, "%s", key_bindings[i]);
clrtoeol();
}
{
int key;
action("press any key to continue");
key = getch();
clrtobot();
action(NULL);
i_last_display_track = CDIO_INVALID_TRACK;
}
}
static void
list_tracks(void)
{
track_t i;
int i_line=0;
int s;
if (sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY) {
printf("drive plays track %d (%02x:%02x)\n\n",
sub.track, sub.rel_addr.msf.m, sub.rel_addr.msf.s);
}
printf("%2d %02x:%02x | ", (int) i_last_track,
toc[i_last_track+1].m,
toc[i_last_track+1].s);
if (b_record)
printf("%s / %s", artist, title);
printf("\n");
printf("-----------+--------------------------------------------------\n");
if (b_record) {
i_line=LINE_TRACK_PREV;
for (i = i_first_track; i <= i_last_track; i++) {
char line[80];
s = cdio_audio_get_msf_seconds(&toc[i+1])
- cdio_audio_get_msf_seconds(&toc[i]);
printf("%2d %02d:%02d %s ", i,
sprintf(line, "%2d %02d:%02d %s ", i,
s / CDIO_CD_SECS_PER_MIN, s % CDIO_CD_SECS_PER_MIN,
(sub.audio_status == CDIO_MMC_READ_SUB_ST_PLAY &&
sub.track == i) ? "*" : "|");
if (b_record) {
if ( !strlen(cd_info[i].title) && !strlen(cd_info[i].artist) )
printf("\n");
else {
if ( strlen(cd_info[i].title) )
printf("%s\n", cd_info[i].title);
strcat(line, cd_info[i].title);
if ( strlen(cd_info[i].artist) > 0 ) {
printf(" %s %s\n",
(sub.track == i) ? "*" : "|", cd_info[i].artist);
if (strlen(cd_info[i].title))
strcat(line, " / ");
strcat(line, cd_info[i].artist);
}
}
} else
printf("\n");
mvprintw(i_line++, 0, line);
clrtoeol();
}
{
int key;
action("press any key to continue");
switch (key = getch());
i_last_display_track = CDIO_INVALID_TRACK;
clrtobot();
action(NULL);
}
}
}
@@ -909,7 +984,7 @@ tracklist(void)
static void
ps_tracklist(void)
ps_list_tracks(void)
{
int i,s,y,sy;
@@ -973,7 +1048,7 @@ ps_tracklist(void)
int
main(int argc, char *argv[])
{
int c,key,nostop=0;
int c, nostop=0;
char *h;
psz_program = strrchr(argv[0],'/');
@@ -1035,7 +1110,7 @@ main(int argc, char *argv[])
todo = EJECT_CD;
break;
case 'k':
keys();
print_keys();
exit(1);
case 'h':
usage(psz_program);
@@ -1117,11 +1192,8 @@ main(int argc, char *argv[])
/* Should have been handled above. */
cd_eject();
break;
case LIST_TRACKS:
tracklist();
break;
case PS_LIST_TRACKS:
ps_tracklist();
ps_list_tracks();
break;
case PLAY_TRACK:
/* play just this one track */
@@ -1145,6 +1217,7 @@ main(int argc, char *argv[])
}
while ( !b_sig ) {
int key;
if (!b_cd) read_toc(p_cdio);
read_subchannel(p_cdio);
display_status();
@@ -1175,6 +1248,17 @@ main(int argc, char *argv[])
case 'c':
cd_close(psz_device);
break;
case 'L':
case 'l':
list_tracks();
break;
case 'K':
case 'k':
case 'h':
case 'H':
case '?':
list_keys();
break;
case ' ':
case 'P':
case 'p':