test0.c 8.68 KB
/*====================================================================
 * test0.c
 *
 * Synopsis:  This file contains a simple test for the audiotest suite
 *
 * 
 * Copyright 1993, Silicon Graphics, Inc.
 * All Rights Reserved.
 *
 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics,
 * Inc.; the contents of this file may not be disclosed to third
 * parties, copied or duplicated in any form, in whole or in part,
 * without the prior written permission of Silicon Graphics, Inc.
 *
 * RESTRICTED RIGHTS LEGEND:
 * Use, duplication or disclosure by the Government is subject to
 * restrictions as set forth in subdivision (c)(1)(ii) of the Rights
 * in Technical Data and Computer Software clause at DFARS
 * 252.227-7013, and/or in similar or successor clauses in the FAR,
 * DOD or NASA FAR Supplement. Unpublished - rights reserved under the
 * Copyright Laws of the United States.
 *====================================================================*/
#include "audiotest.h"
#include "audio.h"
#include <libaudio.h>

#define USE_START_VOICE_PARAMS

#define MAX_NOTE_REPEATS	16
#define MAX_VOICES		20
#define PLYR0_SILENT		1
#define PLYR0_NOISY		2
#define PLYR0_DONE		3
#define PLYR0_ASCENDING		1
#define PLYR0_DESCENDING	2
#define PLYR0_LEFT		3
#define PLYR0_RIGHT		4
#define PLYR0_LOUDER		5
#define PLYR0_SOFTER		6

/**** Share the heap with other test files, so have external ****/
extern ALHeap     gHeapRec;
extern u8         gHeapBuf[AUDIO_HEAP_SIZE];
extern u32        gTestDone;


/**** Prototypes and test control structure ****/
void InitTest0 (u32 subTestNum);
void StopTest0 (u32 subTestNum); 
void retraceProc (void *t);

ALMicroTime __plyr0VoiceHandler(void *node);

test_cntrl Test0 = {
    &InitTest0,      /* void *InitTest; */
    &StopTest0,      /* void *StopTest; */
    NULL,
    &retraceProc,    /* void *retraceProc */
    NULL,            /* void *retraceData */
    6                /* u32  numSubTests */
};


/**** define a player structure for my test to use. ****/
typedef struct {
    ALPlayer            node;           /* note: must be first in structure */
    ALSynth             *drvr;          /* reference to the client driver   */
    u32                 curTest;
    u8                  state;
} player0;

static player0           *plyr0;


/**** Globals unique to this test ****/
static ALBank            *gMidiBank;
static ALVoice           voice[MAX_VOICES];
static s32               voiceAlloc[MAX_VOICES];
static ALVoiceConfig     config = { 64, 0, 0 }; /* priority, fxBus, unityPitchFlag */
static f32               pitch;
static s16               vol;
static u8                pan;
static u8                fxmix = 80;
static ALMicroTime       deltaTime = 0;
static u32               timer;
static u32               direction;
static u32               maxNotes;
static u32               repeatCount;

void InitTest0 (u32 subTestNum) 
{
    ALSynConfig         c;
    u32                 bankLen;
    ALBankFile          *bankPtr;
    amConfig            amc;

    alHeapInit(&gHeapRec, gHeapBuf, sizeof(gHeapBuf));    

    /**** Load the bank file from ROM ****/
    bankLen = _midibankSegmentRomEnd - _midibankSegmentRomStart;
    bankPtr = alHeapAlloc(&gHeapRec, 1, bankLen);
    romCopy(_midibankSegmentRomStart, (char *)bankPtr, bankLen);

    alBnkfNew(bankPtr, (u8 *) _miditableSegmentRomStart);
    gMidiBank = bankPtr->bankArray[0];

    /**** Create the Audio Manager ****/
    c.maxVVoices = MAX_SYNTH_VVOICES;
    c.maxPVoices = MAX_SYNTH_PVOICES;
    c.maxUpdates = MAX_SYNTH_UPDATES;
    c.dmaproc    = 0;                  /* audio mgr will fill this in */
    c.fxType     = AL_FX_NONE; /*AL_FX_SMALLROOM; */
    c.heap       = &gHeapRec;
    
    amc.outputRate = 44100;
    amc.framesPerField = NUM_FIELDS;
    amc.maxACMDSize = MAX_RSP_CMDS;
    amCreateAudioMgr(&c, AUDIO_PRIORITY, &amc);

    /**** Set up the player, and sign in to the driver ****/
    plyr0 = alHeapAlloc(&gHeapRec,1,sizeof(player0));
    plyr0->node.next       = NULL;
    plyr0->node.clientData = plyr0;
    plyr0->drvr = &alGlobals->drvr;
    plyr0->state = PLYR0_SILENT; 
    plyr0->curTest = subTestNum;
    plyr0->node.handler = __plyr0VoiceHandler;

    switch(subTestNum )
    {
	case 0:
	    PRINTF("Test0.0:  Repeat a single note from low pitch to high.\n");
	    pitch = 0.25f;
	    pan = 64;
	    vol = 0x7000;
	    direction = PLYR0_ASCENDING;
	    maxNotes = 1;
	    break;
	case 1:
	    PRINTF("Test0.1:  Repeat a single note from left to right.\n");
	    pitch = 1.0f;
	    pan = 0;
	    vol = 0x7000;
	    direction = PLYR0_RIGHT;
	    maxNotes = 1;
	    break;
	case 2:
	    PRINTF("Test0.2:  Repeat a single note from soft to loud .\n");
	    pitch = 1.0f;
	    pan = 64;
	    vol = 0;
	    direction = PLYR0_LOUDER;
	    maxNotes = 1;
	    break;
	case 3:
	    PRINTF("Test0.3:  Repeat multiple notes from low pitch to high.\n");
	    pitch = 0.25f;
	    pan = 64;
	    vol = 0x2000;
	    direction = PLYR0_ASCENDING;
	    maxNotes = 20;
	    break;
	case 4:
	    PRINTF("Test0.4:  Repeat multiple notes from left to right.\n");
	    pitch = 1.0f;
	    pan = 0;
	    vol = 0x2000;
	    direction = PLYR0_RIGHT;
	    maxNotes = 20;

	    break;
	case 5:
	    PRINTF("Test0.5:  Repeat multiple notes from soft to loud .\n");
	    pitch = 1.0f;
	    pan = 64;
	    vol = 0;
	    direction = PLYR0_LOUDER;
	    maxNotes = 20;
	    break;
    }
    
    if(maxNotes>MAX_VOICES)
	maxNotes = MAX_VOICES;

    timer = 0; /* reset for each test */
    repeatCount = 0;

    alSynAddPlayer(plyr0->drvr, &plyr0->node);
}

void StopTest0(u32 subTestNum)
{
    alSynRemovePlayer(plyr0->drvr, &plyr0->node);
    amDestroyAM();
}

void retraceProc(void *t)
{
    /* this test doesn't do anything in the non audio thread retrace */
}

ALMicroTime __plyr0VoiceHandler(void *node)
{
    ALInstrument        *instrument;
    ALSound             *sound;
    u32                 i;


    instrument = gMidiBank->instArray[0];
    sound = instrument->soundArray[0];

    switch(plyr0->state)
    {
	case PLYR0_SILENT:
	    if(repeatCount >= MAX_NOTE_REPEATS)
		gTestDone = TRUE;
	    else
	    {
		switch(plyr0->curTest)
		{
		    case 0:
		    case 3:
			if(direction == PLYR0_ASCENDING)
			{
			    pitch *= alCents2Ratio(100);
			    if(pitch >= 2.0f)
				direction = PLYR0_DESCENDING;
			}
			else /* must be descending */
			{
			    pitch *= alCents2Ratio(-100);
			    if(pitch <= 0.0f)
			    {
				pitch = 0.0f;
				direction = PLYR0_ASCENDING;
			    }
			}
			break;
		    case 1:
		    case 4:
			if(direction == PLYR0_RIGHT)
			{
			    pan += 10;
			    if(pan >= 127)
			    {
				pan = 127;
				direction = PLYR0_LEFT;
			    }
			}
			else /* must be moving left */
			{
			    pan -= 10;
			    if(pan <= 0)
			    {
				pan = 0;
				direction = PLYR0_RIGHT;
			    }
			}
			break;
		    case 2:
			if(direction == PLYR0_LOUDER)
			{
			    vol += 4000;
			    if((u16)vol >= 0x7FFF)
			    {
				vol = 0x7FFF;
				direction = PLYR0_SOFTER;
			    }
			}
			else /* must be getting softer  */
			{
			    vol -= 0x4000;
			    if(vol <= 0)
			    {
				vol = 0;
				direction = PLYR0_LOUDER;
			    }
			}
			break;
		    case 5:
			if(direction == PLYR0_LOUDER)
			{
			    vol += 500;
			    if((u16)vol >= 0x1FFF)
			    {
				vol = 0x1FFF;
				direction = PLYR0_SOFTER;
			    }
			}
			else /* must be getting softer  */
			{
			    vol -= 500;
			    if(vol <= 0)
			    {
				vol = 0;
				direction = PLYR0_LOUDER;
			    }
			}
			break;
		}			
			    
		for( i = 0 ; i < maxNotes ; i++)
		{
                    voiceAlloc[i] = alSynAllocVoice(plyr0->drvr, &voice[i],
                                                    &config);
                    
		    if(voiceAlloc[i])
		    {

#ifdef USE_START_VOICE_PARAMS	
			alSynStartVoiceParams(plyr0->drvr, & voice[i],
                                              sound->wavetable,
					      pitch, vol, pan, fxmix,
                                              deltaTime);
#else
			alSynSetPitch(plyr0->drvr, &voice[i],pitch);
			alSynSetVol(plyr0->drvr, &voice[i],vol,0);
			alSynSetPan(plyr0->drvr, &voice[i],pan);
			alSynSetFXMix(plyr0->drvr, &voice[i],fxmix);
			alSynStartVoice(plyr0->drvr, &voice[i],
                                        sound->wavetable);
#endif
		    }
		}
		repeatCount++;
		plyr0->state = PLYR0_NOISY;
		timer = 0;
	    }
	    break;

	case  PLYR0_NOISY:
	    timer++;
	    if(timer > 20)
	    {
		for( i = 0; i < maxNotes ; i++)
		{
		    if(voiceAlloc[i])
		    {
			alSynStopVoice(plyr0->drvr, &voice[i]);
			alSynFreeVoice(plyr0->drvr, &voice[i]);
                        voiceAlloc[i] = 0;
		    }
		}
		plyr0->state = PLYR0_SILENT;
	    }
	    else if(timer > 19)
	    {
		for( i = 0; i < maxNotes ; i++)
		{
		    if(voiceAlloc[i])
			alSynSetVol(plyr0->drvr, &voice[i],0,15999);
		}
	    }
    }

    return 16000;
}