sequence.c 4.16 KB
#include <assert.h>
#include <libaudio.h>

#include "UniversalSP.h"
#include "sequence.h"
#include "utils.h"
#include "music.h"
#include "audio.h"
#include "transport.h"


#define kMaxVolume     0x7fff

extern ALUSPlayer      *seqp;
extern ALUSeq          *seq;

extern u8              *seqPtr;
extern s32             seqNo;
extern ALSeqFile       *seqFile;

static s16             sSeqVolume = kMaxVolume;
static ALPan	       sSeqPan;
static s32             sSeqTempo;

u32                    audioState = SEQ_STOPPED;


s32
Seq_Load (ALSeqFile *file, u8 *dest, s32 number)
{
    s32 len;
    u8  *ptr;
    
    ptr = file->seqArray[number].offset;
    len = file->seqArray[number].len;

    if (len & 0x1)
        len++;

    if (len > MAX_SEQ_LENGTH)
        PRINTF("sequence %d too big!!!\n", number);
    
    romCopy (ptr, dest, len);

    return len;
}


s32
Seq_GetNumVoices (void)
{
    ALVoiceState        *vs;
    s32                 vCount = 0;
    
    for (vs = seqp->vAllocHead; vs != 0; vs = vs->next)
        vCount++;

    return vCount;
    
}


/*
  Handy routine for detecting an auto-stop condition.

  In my opinion, since this routine affects the UI state (transport state),
  it really should be a transport routine.
*/
void
Seq_CheckStatus (void)
{
    /* Detect an auto-stop condition and handle any UI actions associated with it. */
    if (seqp->state == AL_STOPPED && audioState != SEQ_STOPPED)
        Xpt_AutoStop ();
}


void
Seq_Prime (void)
{
    u32         seqLen;

    seqLen = Seq_Load(seqFile, seqPtr, seqNo);
    
    alUSNew(seq, seqPtr, seqLen);
    alUSPSetSeq(seqp, seq);
    
    PRINTF("Sequence primed\n");
}


void
Seq_Start (void)
{
    alUSPPlay(seqp);
    audioState = SEQ_PLAYING;

    PRINTF("Sequence started\n");
}


void
Seq_Stop (void)
{
    if (seqp->state == AL_PLAYING)
    {
        alUSPStop(seqp);
        PRINTF("Sequence stopped\n");
    }

    /* Always set audioState to stop since it can be called in a variety of seqp states */
    /* including AL_STOPPED state when handling an auto-stop. */
    audioState = SEQ_STOPPED;
}    
    

char
Seq_IsPlaying (void)
{
    return alUSPGetState (seqp) == AL_PLAYING;
}


/*
  Rewind the sequence to the beginning.
  Can this be called during playback?
*/
void
Seq_RTZ (void)
{
    ALUSMarker marker;
    alUSNewMarker (seq, &marker, 0);
    alUSSetLoc (seq, &marker);
}
 
 
void
Seq_SetFastTempo (void)
{
    sSeqTempo = alUSPGetTempo (seqp);
    alUSPSetTempo (seqp, sSeqTempo>>1);
}

void
Seq_SetNormalTempo (void)
{
    alUSPSetTempo (seqp, sSeqTempo);
}


void
Seq_CueBack (void)
{
    seqNo--;
    if (seqNo < 0)
        seqNo = seqFile->seqCount-1;

    Seq_Prime ();

}

void
Seq_CueForward (void)
{
    seqNo++;
    if (seqNo >= seqFile->seqCount)
        seqNo = 0;

    Seq_Prime ();
}


void
Seq_SetLoop (s32 durTicks)
{
#ifndef COMP_SEQ_PLAY
    static ALSeqMarker	startMarker, endMarker;
    s32		curTicks;

    if (durTicks == 0)
    {
	alSeqpLoop (seqp, &startMarker, &endMarker, 0);
        PRINTF("disabled loop\n");
    }
    else
    {
	curTicks = Seq_GetCurTicks ();
	alSeqNewMarker (seq, &startMarker, curTicks);
	alSeqNewMarker (seq, &endMarker, curTicks + durTicks);
	alSeqpLoop (seqp, &startMarker, &endMarker, -1);
        PRINTF("enabled loop: %d to %d\n", curTicks, curTicks + durTicks);
    }
#endif
}

s16
Seq_GetVolume (void)
{
    return sSeqVolume;
}

ALPan
Seq_GetPan (void)
{
    return sSeqPan;
}



void
Seq_AdjustVolume (char adjustUp)
{
    #define kAdjustInc	128

    if (adjustUp)
    {
	if (sSeqVolume > kMaxVolume - kAdjustInc)
	    sSeqVolume = kMaxVolume;
	else
	    sSeqVolume += kAdjustInc;
    }
    else
    {
	if (sSeqVolume < kAdjustInc)
	    sSeqVolume = 0;
	else
	    sSeqVolume -= kAdjustInc;
    }

    alUSPSetVol (seqp, sSeqVolume);
}


void
Seq_AdjustPan (char adjustUp, u8 chan)
{
    if (adjustUp)
    {
	if (sSeqPan > AL_PAN_RIGHT - 1)
	    sSeqPan = AL_PAN_RIGHT;
	else
	    sSeqPan++;
    }
    else
    {
	if (sSeqPan < AL_PAN_LEFT + 1)
	    sSeqPan = AL_PAN_LEFT;
	else
	    sSeqPan--;
    }

    alUSPSetChlPan (seqp, chan, sSeqPan);
}


ALMicroTime
Seq_GetCurUSecs (void)
{
    return seqp->curTime;
}



s32
Seq_GetCurTicks (void)
{
    return alUSGetTicks (seq);
}