1
0
Files
irix-657m-src/eoe/cmd/cdplayer/cue.c
2022-09-29 17:59:04 +03:00

333 lines
8.5 KiB
C

/*
* cue.c
*
* Description:
* Routines that implement fast forward and rewind for the CD Audio
* tool
*
* History:
* rogerc 11/06/90 Created
*/
#include <X11/Intrinsic.h>
#include <Xm/Xm.h>
#include "cdaudio.h"
#include "program.h"
#include "client.h"
#include "cue.h"
#include "display.h"
#define CUEINTERVAL 10
#define CUEQUANTUM 1
/*
* void ff_arm( Widget w, CLIENTDATA *clientp, XmAnyCallbackStruct *call_data )
*
* Description:
* Set up the time out function for fast-forwarding
*
* Parameters:
* w The fast forward button
* clientp Client data
* call_data ignored
*/
void ff_arm( Widget w, CLIENTDATA *clientp, XmAnyCallbackStruct *call_data )
{
if (clientp->skipping && clientp->pauseid) {
XtRemoveTimeOut( clientp->pauseid );
clientp->pauseid = 0;
clientp->skipping = 0;
/*
* Need more up to date status than clientp->status
*/
CDgetstatus( clientp->cdplayer, clientp->status );
if ((clientp->status->state == CD_PAUSED ||
clientp->status->state == CD_STILL) &&
CDtogglepause( clientp->cdplayer ))
clientp->status->state = CD_PLAYING;
}
if (clientp->status->state == CD_PLAYING) {
XtRemoveTimeOut( clientp->updateid );
clientp->updateid = 0;
clientp->ffid = XtAddTimeOut( CUEINTERVAL, ff, clientp );
clientp->cueing = 1;
CDtogglepause( clientp->cdplayer );
}
}
/*
* void ff_disarm( Widget w, CLIENTDATA *clientp,
* XmAnyCallbackStruct *call_data )
*
* Description:
* Remove the fast-forwarding time out function, thereby ending the
* fast forward action
*
* Parameters:
* w The fast forward button
* clientp Client data
* call_data ignored
*/
void ff_disarm( Widget w, CLIENTDATA *clientp, XmAnyCallbackStruct *call_data )
{
CDTRACKINFO info;
int sec;
if (clientp->ffid ) {
XtRemoveTimeOut( clientp->ffid );
clientp->ffid = 0;
if (clientp->cueing) {
if (clientp->play_mode == PLAYMODE_NORMAL) {
CDgettrackinfo( clientp->cdplayer,
clientp->status->track, &info );
sec = (info.start_min + clientp->status->min) * 60
+ info.start_sec + clientp->status->sec;
CDplayabs( clientp->cdplayer, sec / 60, sec % 60, 0, 1 );
}
else
CDplaytrackabs( clientp->cdplayer,
clientp->status->track, clientp->status->min,
clientp->status->sec, 0, 1 );
clientp->cueing = 0;
}
}
clientp->update_func( clientp, 0 );
}
/*
* void ff( CLIENTDATA *clientp, XtIntervalId *id )
*
* Description:
* Perform one slice of the fast forwarding. what we do is skip ahead
* CUEQUANTUM seconds every CUEINTERVAL milliseconds, and play little
* snippets of the CD
*
* Parameters:
* clientp Client data
* id id of this time out
*/
void ff( CLIENTDATA *clientp, XtIntervalId *id )
{
CDTRACKINFO info;
int min, sec, tmin, tsec, lmin, lsec;
register CDSTATUS *status = clientp->status;
/*
* Fast forwarded to the end of the disc
*/
if (status->state == CD_READY)
return;
sec = status->sec + status->min * 60;
sec += CUEQUANTUM;
min = sec / 60;
sec %= 60;
CDgettrackinfo( clientp->cdplayer, status->track, &info );
if (min > info.total_min || (min == info.total_min &&
sec > info.total_sec)) {
if (clientp->play_mode == PLAYMODE_NORMAL &&
status->track < status->last) {
status->track++;
status->min = 0;
status->sec = 0;
CDgettrackinfo( clientp->cdplayer, status->track, &info );
status->abs_min = info.start_min;
status->abs_sec = info.start_sec;
}
else if ((clientp->play_mode == PLAYMODE_PROGRAM ||
clientp->play_mode == PLAYMODE_SHUFFLE) &&
clientp->program->current < clientp->program->num_tracks - 1) {
status->track = clientp->program->
tracks[++(clientp->program->current)];
CDgettrackinfo( clientp->cdplayer, status->track, &info );
status->abs_min = info.start_min;
status->abs_sec = info.start_sec;
status->min = 0;
status->sec = 0;
}
else {
clientp->play_mode == PLAYMODE_NORMAL ?
CDstop( clientp->cdplayer ):
program_stop( clientp->cdplayer, clientp->program );
clientp->cueing = 0;
clientp->repeat = 0;
CDgetstatus( clientp->cdplayer, status );
set_status_bitmap( status->state );
}
}
else {
status->min = min;
status->sec = sec;
/*
* Absolute time
*/
sec = status->abs_sec + status->abs_min * 60;
sec += CUEQUANTUM;
status->abs_min = sec / 60;
status->abs_sec = sec % 60;
}
draw_display( clientp );
clientp->ffid = XtAddTimeOut( CUEINTERVAL, ff, clientp );
}
/*
* void
* rew_arm( Widget w, CLIENTDATA *clientp, XmAnyCallbackStruct *call_data )
*
* Description:
* Set up the rewind time out function, which gets rewind going.
*
* Parameters:
* w The rewind button
* clientp Client data
* call_data ignored
*/
void rew_arm( Widget w, CLIENTDATA *clientp, XmAnyCallbackStruct *call_data )
{
if (clientp->skipping && clientp->pauseid) {
XtRemoveTimeOut( clientp->pauseid );
clientp->pauseid = 0;
clientp->skipping = 0;
/*
* Need more up to date status than clientp->status
*/
CDgetstatus( clientp->cdplayer, clientp->status );
if ((clientp->status->state == CD_PAUSED ||
clientp->status->state == CD_STILL) &&
CDtogglepause( clientp->cdplayer ))
clientp->status->state = CD_PLAYING;
}
if (clientp->status->state == CD_PLAYING) {
clientp->rewid = XtAddTimeOut( CUEINTERVAL, rew, clientp );
clientp->cueing = 1;
CDtogglepause( clientp->cdplayer );
}
}
/*
* void rew_disarm( Widget w, CLIENTDATA *clientp,
* XmAnyCallbackStruct *call_data )
*
* Description:
* Remove the rewind time out, which stops the rewind action
*
* Parameters:
* w The rewind button
* clientp Client data
* call_data ignored
*/
void rew_disarm( Widget w, CLIENTDATA *clientp, XmAnyCallbackStruct *call_data )
{
CDTRACKINFO info;
int sec;
if (clientp->rewid) {
XtRemoveTimeOut( clientp->rewid );
clientp->rewid = 0;
if (clientp->cueing) {
if (clientp->play_mode == PLAYMODE_NORMAL) {
CDgettrackinfo( clientp->cdplayer,
clientp->status->track, &info );
sec = (info.start_min + clientp->status->min) * 60
+ info.start_sec + clientp->status->sec;
CDplayabs( clientp->cdplayer, sec / 60, sec % 60, 0, 1 );
}
else
CDplaytrackabs( clientp->cdplayer,
clientp->status->track, clientp->status->min,
clientp->status->sec, 0, 1 );
clientp->cueing = 0;
}
}
}
/*
* void rew( CLIENTDATA *clientp, XtIntervalId *id )
*
* Description:
* Perform the rewind action. The way this is done is we go back
* CUEQUANTUM seconds every CUEINTERVAL milliseconds, and play a little
* bit of the CD
*
* Parameters:
* clientp Client data
* id time out id
*/
void rew( CLIENTDATA *clientp, XtIntervalId *id )
{
CDTRACKINFO info;
register CDSTATUS *status = clientp->status;
int min, sec;
if (status->state != CD_PLAYING)
return;
sec = status->sec + status->min * 60;
sec -= CUEQUANTUM;
min = sec / 60;
sec %= 60;
CDgettrackinfo( clientp->cdplayer, status->track, &info );
if (sec < 0) {
if (clientp->play_mode == PLAYMODE_NORMAL &&
status->track > status->first) {
status->track--;
CDgettrackinfo( clientp->cdplayer, status->track,
&info );
status->min = info.total_min;
status->sec = info.total_sec;
sec = (info.start_min + info.total_min) * 60 + info.start_sec
+ info.total_sec;
status->abs_min = sec / 60;
status->abs_sec = sec % 60;
}
else if ((clientp->play_mode == PLAYMODE_PROGRAM ||
clientp->play_mode == PLAYMODE_SHUFFLE) &&
clientp->program->current > 0) {
status->track = clientp->program->
tracks[--(clientp->program->current)];
CDgettrackinfo( clientp->cdplayer,
status->track, &info );
status->min = info.total_min;
status->sec = info.total_sec;
sec = (info.start_min + info.total_min) * 60 + info.start_sec
+ info.total_sec;
status->abs_min = sec / 60;
}
else {
clientp->play_mode == PLAYMODE_NORMAL ?
CDstop( clientp->cdplayer ):
program_stop( clientp->cdplayer, clientp->program );
clientp->cueing = 0;
clientp->repeat = 0;
CDgetstatus( clientp->cdplayer, status );
set_status_bitmap( status->state );
}
}
else {
status->min = min;
status->sec = sec;
sec = status->abs_sec + status->abs_min * 60;
sec -= CUEQUANTUM;
status->abs_min = sec / 60;
status->abs_sec = sec % 60;
}
draw_display( clientp );
clientp->rewid = XtAddTimeOut( CUEINTERVAL, rew, clientp );
}