home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Dream 59
/
CDDream59.ISO
/
BeOs
/
Sound
/
Intel
/
PPBeDevKit.ZIP
/
PLAYERPR.TAR
/
PlayerPRO
/
Source
/
Interrupt.c
< prev
next >
Wrap
Text File
|
1999-01-02
|
34KB
|
1,371 lines
/******************** ***********************/
//
// Player PRO 5.0 - DRIVER SOURCE CODE -
//
// Library Version 5.0
//
// To use with MAD Library for Mac: Symantec, CodeWarrior and MPW
//
// Antoine ROSSET
// 16 Tranchees
// 1206 GENEVA
// SWITZERLAND
//
// COPYRIGHT ANTOINE ROSSET 1996, 1997, 1998
//
// Thank you for your interest in PlayerPRO !
//
// FAX: (+41 22) 346 11 97
// PHONE: (+41 79) 203 74 62
// Internet: RossetAntoine@bluewin.ch
//
/******************** ***********************/
#include "RDriver.h"
#include "RDriverInt.h"
#ifdef _MIDIHARDWARE_
#include "OMS.h"
#endif
void SampleMIDI( Channel *curVoice, short channel, short curN, MADDriverRec *intDriver);
void ApplyFilters( MADDriverRec *intDriver);
void ApplySurround( MADDriverRec *intDriver);
/*long DoVolPanning( short whichChannel, Channel *ch, MADDriverRec *intDriver) // MAX = 64
{
// Compute Volume !
long pannValue;
long temp = ( (long) ch->vol * (long) ch->volEnv * (long) ch->volFade) /( 64L*32767L );
if( !intDriver->Active[ ch->ID]) return 0;
if( intDriver->curMusic != 0L) temp = (temp * (long) intDriver->curMusic->header->chanVol[ ch->ID]) / MAX_VOLUME;
else temp = 64;
// Compute Panning
if( whichChannel != 3)
{
pannValue = ch->pannEnv;
if( whichChannel == 1) pannValue = MAX_PANNING - pannValue;
temp = (temp * pannValue) / MAX_PANNING;
}
// Vol Global
temp = (temp * intDriver->VolGlobal) / (MAX_VOLUME + 20);
if( temp > 64) temp = 64;
return temp;
}*/
long DoVolPanning256( short whichChannel, Channel *ch, MADDriverRec *intDriver) // MAX = 256
{
// Compute Volume !
long pannValue;
long temp = ( (long) ch->vol * (long) ch->volEnv * (long) ch->volFade) /( 16L*32767L );
if( !intDriver->Active[ ch->ID]) return 0;
if( intDriver->curMusic != 0L) temp = (temp * (long) intDriver->curMusic->header->chanVol[ ch->ID]) / MAX_VOLUME;
else temp = 256;
// Compute Panning
if( whichChannel != 3)
{
pannValue = ch->pannEnv;
if( whichChannel == 1) pannValue = MAX_PANNING - pannValue;
temp = (temp * pannValue) / MAX_PANNING;
}
// Vol Global
temp = (temp * intDriver->VolGlobal) / (MAX_VOLUME + 20);
if( temp > 256) temp = 256;
return temp;
}
void MADCleanDriver( MADDriverRec *intDriver)
{
short i, x;
for( i = 0; i < MAXTRACK; i++)
{
intDriver->chan[i].ID = i;
intDriver->chan[i].begPtr = 0L;
intDriver->chan[i].maxPtr = 0L;
intDriver->chan[i].curPtr = 0L;
intDriver->chan[i].sizePtr = 0L;
intDriver->chan[i].amp = 8;
intDriver->chan[i].loopBeg = 0;
intDriver->chan[i].loopSize = 0;
intDriver->chan[i].ins = 0;
intDriver->chan[i].insOld = 0;
intDriver->chan[i].fineTune = NOFINETUNE;
intDriver->chan[i].note = 0xFF;
intDriver->chan[i].noteOld = 0xFF;
intDriver->chan[i].period = GetOldPeriod( 40, NOFINETUNE, intDriver);
intDriver->chan[i].periodOld= GetOldPeriod( 40, NOFINETUNE, intDriver);
intDriver->chan[i].vol = 64;
intDriver->chan[i].cmd = 0;
intDriver->chan[i].arg = 0;
for( x = 0; x < MAX_ARP; x++) intDriver->chan[i].arp[ x] = 0;
intDriver->chan[i].arpindex = 0;
intDriver->chan[i].arpUse = false;
intDriver->chan[i].viboffset = 0;
intDriver->chan[i].vibdepth = 0;
intDriver->chan[i].vibrate = 0;
intDriver->chan[i].vibtype = 0;
intDriver->chan[i].slide = 0;
intDriver->chan[i].pitchgoal = 0;
intDriver->chan[i].pitchrate = 0;
intDriver->chan[i].volumerate = 0;
intDriver->chan[i].samplePtr = 0L;
intDriver->chan[i].volcmd = 0L;
for( x = 0; x < 16; x++) intDriver->chan[ i].oldArg[ x] = 0;
intDriver->chan[i].KeyOn = false;
intDriver->chan[i].a = 0;
intDriver->chan[i].b = 1;
intDriver->chan[i].p = 0;
intDriver->chan[i].volEnv = 64;
intDriver->chan[i].volFade = 32767;
intDriver->chan[i].lAC = 0;
intDriver->chan[i].lastWordR = 0;
intDriver->chan[i].lastWordL = 0;
intDriver->chan[i].curLevelL = 0;
intDriver->chan[i].curLevelR = 0;
intDriver->chan[i].prevPtr = 0;
intDriver->chan[i].prevVol0 = 1;
intDriver->chan[i].prevVol1 = 1;
intDriver->chan[i].loopType = eClassicLoop;
intDriver->chan[i].pingpong = false;
intDriver->chan[i].preOff = 0xFFFFFFFF;
intDriver->chan[i].preVal2 = 0;
intDriver->chan[i].preVal2R = 0;
intDriver->chan[i].spreVal2 = 0;
intDriver->chan[i].spreVal2R = 0;
intDriver->chan[i].preVal = 0;
intDriver->chan[i].spreVal = 0;
intDriver->chan[i].RemoverWorking = false;
intDriver->chan[i].TICKREMOVESIZE = 1;
}
intDriver->BufCounter = 0; intDriver->BytesToGenerate = 0;
for( i = 0; i < MAXTRACK; i++) intDriver->TrackLineReading[ i] = true;
}
long Interpolate(long p,long p1,long p2,long v1,long v2)
{
long dp,dv,di;
if( p1 == p2) return v1;
dv=v2-v1;
dp=p2-p1;
di=p-p1;
return v1 + ((long)(di*dv) / dp);
}
long InterpolateEnv(long p, EnvRec *a,EnvRec *b)
{
if( p < a->pos) return a->val;
return(Interpolate(p,a->pos,b->pos,a->val,b->val));
}
void ProcessFadeOut( Channel *ch, MADDriverRec *intDriver)
{
if( intDriver->curMusic != 0L)
{
if( !ch->KeyOn)
{
ch->volFade -= intDriver->curMusic->fid[ ch->ins].volFade;
if( ch->volFade < 0)
{
ch->volFade = 0;
ch->loopBeg = 0;
ch->loopSize = 0;
}
}
}
}
void ProcessEnvelope( Channel *ch, MADDriverRec *intDriver)
{
long v;
InstrData *curIns;
ch->volEnv = 64;
if( ch->ins < 0) return;
if( ch->samplePtr != 0L) return;
curIns = &intDriver->curMusic->fid[ ch->ins];
if( curIns->volSize <= 0) return;
if( curIns->volType & EFON)
{
// active? -> copy variables
Byte a,b;
short p;
a=ch->a;
b=ch->b;
p=ch->p;
if( curIns->volSize == 1) // Just 1 point !
{
v = curIns->volEnv[a].val;
p = curIns->volEnv[a].pos;
}
else
{
v = InterpolateEnv( p, &curIns->volEnv[a], &curIns->volEnv[b]);
if((curIns->volType & EFSUSTAIN) && ch->KeyOn && a==curIns->volSus && p==curIns->volEnv[a].pos){
}
else{
p++;
if(p >= curIns->volEnv[b].pos)
{
a=b; b++;
if(curIns->volType & EFLOOP)
{
if(b > curIns->volEnd)
{
a=curIns->volBeg;
b=a+1;
p=curIns->volEnv[a].pos;
}
}
else
{
if(b >= curIns->volSize)
{
b--;
p--;
}
}
}
}
}
ch->a=a;
ch->b=b;
ch->p=p;
ch->volEnv = v;
}
}
void ProcessPanning( Channel *ch, MADDriverRec *intDriver)
{
long v;
InstrData *curIns;
ch->pannEnv = ch->pann;
if( ch->ins < 0) return;
if( ch->samplePtr != 0L) return;
curIns = &intDriver->curMusic->fid[ ch->ins];
if( curIns->pannSize <= 0) return;
if( curIns->pannType & EFON)
{
// active? -> copy variables
Byte aa,bb;
short pp;
aa = ch->aa;
bb = ch->bb;
pp = ch->pp;
if( curIns->pannSize == 1) // Just 1 point !
{
v = curIns->pannEnv[ aa].val;
pp = curIns->pannEnv[ aa].pos;
}
else
{
v = InterpolateEnv( pp, &curIns->pannEnv[ aa], &curIns->pannEnv[ bb]);
pp++;
if(pp >= curIns->pannEnv[bb].pos)
{
aa=bb; bb++;
if(curIns->pannType & EFLOOP)
{
if(bb > curIns->pannEnd)
{
aa=curIns->pannBeg;
bb=aa+1;
pp=curIns->pannEnv[aa].pos;
}
}
else
{
if(bb >= curIns->pannSize)
{
bb--;
pp--;
}
}
}
}
ch->aa=aa;
ch->bb=bb;
ch->pp=pp;
ch->pannEnv = v;
}
}
void StartEnvelope( Channel *ch)
{
ch->p=0;
ch->a=0;
ch->b=1;
}
void StartPanning( Channel *ch)
{
ch->pp=0;
ch->aa=0;
ch->bb=1;
}
long GetOldPeriod( short note, long c2spd, MADDriverRec *intDriver)
{
unsigned long period, n,o;
if( note == 0xFF) return 4242;
if( note == 0xFE) return 4242;
//if(!c2spd) DebugStr("\pNo c2spd");
if(!c2spd) return 4242;
if( note < 0) note = 0;
n = note%12;
o = note/12;
period = (unsigned long) ((unsigned long) ( 8363UL * ((unsigned long) intDriver->lib->mytab[ n]) ) >> o ) / (unsigned long) c2spd;
if( period == 0L) period = 7242;
return period;
// return( getlogperiod( note, c2spd));
// period = GetFreq2( getlinearperiod( note, c2spd)) * AMIGA_CLOCKFREQ2;
// return( period);
}
void ReadNote( Channel *curVoice, Cmd *theNoteCmd, MADDriverRec *intDriver)
{
Cmd intCmd = *theNoteCmd;
/********************************************/
/* EXTRA small positionning */
/********************************************/
if( intCmd.cmd == 0x0E && (intCmd.arg >> 4) == 0x0D)
{
if( intDriver->smallcounter == 0 && !curVoice->GEffect)
{
curVoice->GEffect = true;
curVoice->GPat = intDriver->Pat;
curVoice->GReader = intDriver->PartitionReader;
}
if( intDriver->smallcounter >= (intCmd.arg & 0x0F))
{
curVoice->GEffect = false; // <- Continue - Play note NOW !
}
else return; // <- Do it later
}
else curVoice->GEffect = false; // <- Continue
/********************************************/
/* Play a sample sound in priority to music */
/********************************************/
if( curVoice->samplePtr != 0L) return;
/********************************************/
/********************************************/
/* Read command and compute it */
/********************************************/
else if( intCmd.ins != 0 || (intCmd.note != 0xFF && intCmd.note != 0xFE))
{
/********************************/
/* PrÄpare les notes manquantes */
/********************************/
/********************************/
if( intCmd.note == 0xFF)
{
if( intCmd.ins == curVoice->insOld) // RESET ONLY VOLUME
{
if(intCmd.cmd != volumeE && intCmd.ins != 0)
{
if( curVoice->samp < intDriver->curMusic->fid[ intCmd.ins].numSamples)
{
sData *curData;
curData = intDriver->curMusic->sample[ intDriver->curMusic->fid[ intCmd.ins].firstSample + curVoice->samp];
curVoice->vol = curData->vol;
if( curVoice->vol > MAX_VOLUME) curVoice->vol = MAX_VOLUME;
curVoice->volFade = 32767;
}
}
}
else intCmd.note = curVoice->noteOld;
}
else curVoice->noteOld = intCmd.note;
/********************************/
if( intCmd.ins == 0) { intCmd.ins = curVoice->insOld;}
else { curVoice->insOld = intCmd.ins; }
/********************************/
if( intCmd.ins != 0 && (intCmd.note != 0xFF && intCmd.note != 0xFE))
{
sData *curData;
short ins, samp;
/**** INSTRUMENT ****/
ins = intCmd.ins - 1; if( ins >= MAXINSTRU) ins = MAXINSTRU-1;
samp = intDriver->curMusic->fid[ ins].what[ intCmd.note];
if( intDriver->DriverSettings.driverMode == MIDISoundDriver)
{
curVoice->ins = ins;
}
if( samp < intDriver->curMusic->fid[ ins].numSamples)
{
curData = intDriver->curMusic->sample[ intDriver->curMusic->fid[ ins].firstSample + samp];
curVoice->ins = ins;
curVoice->amp = curData->amp;
curVoice->stereo = curData->stereo;
curVoice->samp = samp;
curVoice->loopType= curData->loopType;
/**** RESET NOTE ****/
if( intCmd.cmd != portamentoE && intCmd.cmd != portaslideE)
{
curVoice->prevPtr = 0L;
curVoice->maxPtr = curVoice->curPtr = curVoice->begPtr = curData->data;
curVoice->maxPtr += curData->size;
curVoice->sizePtr = curData->size;
curVoice->lAC = 0;
curVoice->pingpong = false;
curVoice->preOff = 0xFFFFFFFF;
curVoice->preVal = 0;
curVoice->spreVal = 0;
curVoice->preVal2 = *curVoice->curPtr;
if( curVoice->amp == 8) curVoice->preVal2R = *(curVoice->curPtr+1);
else curVoice->preVal2R = *(curVoice->curPtr+2);
curVoice->spreVal2 = *(short*) curVoice->curPtr;
curVoice->spreVal2R = *(short*) (curVoice->curPtr+2);
if( curData->loopSize > 2)
{
curVoice->loopBeg = curData->loopBeg;
curVoice->loopSize = curData->loopSize;
curVoice->maxPtr = (Ptr) ((long) curData->data + curData->loopBeg + curData->loopSize);
}
else
{
curVoice->loopBeg = 0;
curVoice->loopSize = 0;
}
curVoice->viboffset = 0;
if(intCmd.cmd != panningE)
{
curVoice->pann = intDriver->curMusic->header->chanPan[ curVoice->ID];
if( curVoice->pann > MAX_PANNING) curVoice->pann = MAX_PANNING;
}
StartPanning( curVoice);
StartEnvelope( curVoice);
}
if(intCmd.cmd != volumeE && theNoteCmd->ins != 0)
{
curVoice->vol = curData->vol;
if( curVoice->vol > MAX_VOLUME) curVoice->vol = MAX_VOLUME;
curVoice->volFade = 32767;
}
intDriver->InstruTube[ ins] = 64;
intDriver->InstruActif[ ins] = curVoice->ID;
}
}
if( intCmd.note != 0xFF && intCmd.note != 0xFE)
{
/**** NOTE & PERIOD ****/
sData *curData;
short samp;
samp = intDriver->curMusic->fid[ curVoice->ins].what[ intCmd.note];
if( samp < intDriver->curMusic->fid[ curVoice->ins].numSamples)
{
curData = intDriver->curMusic->sample[ intDriver->curMusic->fid[ curVoice->ins].firstSample + samp];
curVoice->note = intCmd.note + curData->relNote;
curVoice->fineTune = curData->c2spd;
curVoice->KeyOn = true;
if( intCmd.cmd != portamentoE && intCmd.cmd != portaslideE)
{
curVoice->period = GetOldPeriod( curVoice->note, curVoice->fineTune, intDriver);
curVoice->periodOld = curVoice->period = (curVoice->period * (long) intDriver->FreqExt) / 80L;
}
}
/***********************/
/* Pour le MIDI Driver */
/***********************/
if( intDriver->DriverSettings.driverMode == MIDISoundDriver)
{
if( intDriver->NoteOld[ curVoice->ID] != -1)
{
NoteOff( intDriver->InstuNoOld[ curVoice->ID], intDriver->NoteOld[ curVoice->ID], intDriver->VelocityOld[ curVoice->ID], intDriver);
intDriver->NoteOld[ curVoice->ID] = -1;
}
SampleMIDI( curVoice, curVoice->ins, intCmd.note, intDriver);
intDriver->InstuNoOld[ curVoice->ID] = curVoice->ins;
intDriver->NoteOld[ curVoice->ID] = intCmd.note;
intDriver->VelocityOld[ curVoice->ID] = curVoice->vol;
}
/***********************/
}
}
else
{
curVoice->note = 0xFF;
}
/**************/
/* VOLUME */
/**************/
if( intCmd.vol != 0xFF)
{
if(intCmd.vol >= 0x10 && intCmd.vol <= 0x50)
{
curVoice->vol = intCmd.vol - 0x10;
if( curVoice->vol < MIN_VOLUME) curVoice->vol = MIN_VOLUME;
else if( curVoice->vol > MAX_VOLUME) curVoice->vol = MAX_VOLUME;
curVoice->volcmd = 0;
}
else curVoice->volcmd = intCmd.vol;
}
else curVoice->volcmd = 0;
curVoice->cmd = intCmd.cmd;
curVoice->arg = intCmd.arg;
SetUpEffect( curVoice, intDriver);
if( intCmd.ins != 0 && intCmd.note != 0xFF) intDriver->Tube[ curVoice->ID] = curVoice->vol;
/**************/
/* KEY OFF */
/**************/
if( intCmd.note == 0xFE)
{
curVoice->KeyOn = false;
if( intDriver->DriverSettings.driverMode == MIDISoundDriver)
{
if( intDriver->NoteOld[ curVoice->ID] != -1)
NoteOff( intDriver->InstuNoOld[ curVoice->ID], intDriver->NoteOld[ curVoice->ID], intDriver->VelocityOld[ curVoice->ID], intDriver);
intDriver->NoteOld[ curVoice->ID] = -1;
}
}
}
#if defined(powerc) || defined (__powerc)
void ClearDouble( register double long *a, register long xx)
{
while( xx-- > 0 ) *a++ = 0;
}
#else
void ClearDouble( register long *a, register long xx)
{
xx *=2;
while( xx-- > 0 ) *a++ = 0;
}
#endif
void ComputeReverb8( Byte *orgPtr, Byte *destPtr, long xx, long strength)
{
long temp1;
while( xx-- > 0)
{
temp1 = (*destPtr) + ((strength * (*orgPtr++ - 0x80)) / 100L); // - 0x80L
if( temp1 > 0xFF) temp1 = 0xFF; // overflow ?
else if( temp1 < 0 ) temp1 = 0;
*(destPtr)++ = temp1;
}
}
void ComputeReverb16( short *orgPtr, short *destPtr, long xx, long strength)
{
long temp1;
long valP = 0x7FFFL, valN = -0x7FFFL;
while( xx-- > 0)
{
temp1 = *destPtr + ((strength * (long) *orgPtr++) / 100L);
if( temp1 > valP) temp1 = valP; // overflow ?
else if( temp1 < valN ) temp1 = valN;
*destPtr++ = temp1;
}
}
void NoteAnalyse( MADDriverRec *intDriver)
{
long InterruptBufferSize, i, ASCBUFFERCopy;
Ptr DataPtrCopy;
long tVSYNC;
Boolean NoteReading;
long *DASCopy;
short *DASCopy8;
if( intDriver->curMusic != 0L)
{
if( intDriver->curMusic->musicUnderModification)
{ // SILENCE
long Tracks;
// if( intDriver->curMusic->header->MAD != 'MADI') DebugStr("\pError in MADI");
switch( intDriver->DriverSettings.outPutMode)
{
case PolyPhonic: Tracks = intDriver->DriverSettings.numChn; break;
default: Tracks = 2; break;
}
Tracks = 1;
switch( intDriver->DriverSettings.outPutBits)
{
case 8:
for( i = 0; i < intDriver->ASCBUFFER*Tracks; i++) intDriver->IntDataPtr[ i] = 0x80;
break;
case 16:
DASCopy8 = (short*) intDriver->IntDataPtr;
for( i = 0; i < intDriver->ASCBUFFER*Tracks*2L; i++) DASCopy8[ i] = 0;
break;
}
return;
}
}
DataPtrCopy = intDriver->IntDataPtr;
DASCopy = intDriver->DASCBuffer;
DASCopy8 = intDriver->DASCBuffer8;
ASCBUFFERCopy = intDriver->ASCBUFFER;
InterruptBufferSize = intDriver->ASCBUFFER;
while( InterruptBufferSize > 0)
{
/********************/
/* Sound Generating */
/********************/
intDriver->ASCBUFFER = intDriver->BytesToGenerate - intDriver->BufCounter;
if( intDriver->ASCBUFFER < 0) intDriver->ASCBUFFER = 0;
if( intDriver->ASCBUFFER > InterruptBufferSize) { intDriver->ASCBUFFER = InterruptBufferSize; NoteReading = false;}
else NoteReading = true;
if( intDriver->ASCBUFFER > 0)
{
GenerateSound( intDriver);
intDriver->BufCounter += intDriver->ASCBUFFER;
InterruptBufferSize -= intDriver->ASCBUFFER;
}
/**************************/
/* Note & Effect Analyser */
/**************************/
if( !NoteReading) InterruptBufferSize = -1;
else
{
NoteReading = false;
/*********/
// GEffect : extrasmallpositionning
if( intDriver->curMusic != 0L && intDriver->Reading)
{
for( i = 0; i < intDriver->curMusic->header->numChn; i++)
{
if( intDriver->chan[ i].GEffect)
{
ReadNote( &intDriver->chan[ i], GetMADCommand( intDriver->chan[ i].GReader, i, intDriver->curMusic->partition[ intDriver->chan[ i].GPat]), intDriver);
}
}
}
/*********/
// intDriver->extrasmallcounter--;
// if( intDriver->extrasmallcounter <= 0)
{
// intDriver->extrasmallcounter = EXTRASMALLCOUNTER;
intDriver->smallcounter++;
if( intDriver->smallcounter >= intDriver->speed)
{
intDriver->smallcounter = 0;
if( intDriver->curMusic != 0L)
{
for( i = 0; i < intDriver->curMusic->header->numChn; i++)
{
if( intDriver->Reading && intDriver->TrackLineReading[ i])
{
ReadNote( &intDriver->chan[ i], GetMADCommand( intDriver->PartitionReader, i, intDriver->curMusic->partition[ intDriver->Pat]), intDriver);
}
ProcessEnvelope( &intDriver->chan[ i], intDriver);
ProcessPanning( &intDriver->chan[ i], intDriver);
ProcessFadeOut( &intDriver->chan[ i], intDriver);
}
if( intDriver->Reading)
{
for( i = 0; i < MAXTRACK; i++) intDriver->TrackLineReading[ i] = true;
intDriver->PartitionReader++;
if( intDriver->PartitionReader >= intDriver->curMusic->partition[ intDriver->Pat]->header.size)
{
intDriver->PartitionReader = 0;
intDriver->endPattern = true;
if( intDriver->JumpToNextPattern)
{
intDriver->PL++;
intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
if( intDriver->speed == 1 && intDriver->PL >= intDriver->curMusic->header->numPointers)
{
intDriver->PL = 0;
intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
MADCleanDriver( intDriver);
if( !intDriver->DriverSettings.repeatMusic) intDriver->Reading = false;
intDriver->musicEnd = true;
}
}
}
}
}
}
else
{
if( intDriver->curMusic != 0L)
{
for( i = 0 ; i < intDriver->DriverSettings.numChn; i++)
{
// if( intDriver->Reading)
{
DoVolCmd( &intDriver->chan[ i], intDriver->smallcounter, intDriver);
DoEffect( &intDriver->chan[ i], intDriver->smallcounter, intDriver);
}
ProcessEnvelope( &intDriver->chan[ i], intDriver);
ProcessPanning( &intDriver->chan[ i], intDriver);
ProcessFadeOut( &intDriver->chan[ i], intDriver);
}
if( intDriver->Reading)
{
if( intDriver->smallcounter == intDriver->speed - 1)
{
if( intDriver->PL >= intDriver->curMusic->header->numPointers)
{
intDriver->PL = 0;
intDriver->Pat = intDriver->curMusic->header->oPointers[ intDriver->PL];
MADCleanDriver( intDriver);
if( !intDriver->DriverSettings.repeatMusic) intDriver->Reading = false;
intDriver->musicEnd = true;
}
}
}
}
}
}
tVSYNC = intDriver->VSYNC;
tVSYNC /= intDriver->finespeed;
tVSYNC *= 80L;
tVSYNC /= intDriver->VExt;
intDriver->BytesToGenerate += tVSYNC;
}
}
intDriver->ASCBUFFER = ASCBUFFERCopy;
intDriver->IntDataPtr = DataPtrCopy;
intDriver->DASCBuffer = DASCopy;
intDriver->DASCBuffer8 = DASCopy8;
if( intDriver->DriverSettings.MicroDelaySize)
{
switch( intDriver->DriverSettings.outPutBits)
{
case 16:
BlockMoveData( intDriver->DASCBuffer + intDriver->ASCBUFFER*2, intDriver->DASCBuffer, intDriver->MDelay*8L);
#if defined (powerc)
ClearDouble( (long double*) (intDriver->DASCBuffer + intDriver->MDelay*2L), intDriver->ASCBUFFER);
#else
ClearDouble( (long*) (intDriver->DASCBuffer + intDriver->MDelay*2L), intDriver->ASCBUFFER);
#endif
break;
case 8:
if( intDriver->MDelay % 2 != 0)
{
BlockMoveData( intDriver->DASCBuffer8 + intDriver->ASCBUFFER*2, intDriver->DASCBuffer8, 1 + intDriver->MDelay*4L);
#if defined (powerc)
ClearDouble( (long double*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), 1 + intDriver->ASCBUFFER/2);
#else
ClearDouble( (long*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), 1 + intDriver->ASCBUFFER/2);
#endif
}
else
{
BlockMoveData( intDriver->DASCBuffer8 + intDriver->ASCBUFFER*2, intDriver->DASCBuffer8, intDriver->MDelay*4L);
#if defined (powerc)
ClearDouble( (long double*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), intDriver->ASCBUFFER/2);
#else
ClearDouble( (long*) (intDriver->DASCBuffer8 + intDriver->MDelay*2L), intDriver->ASCBUFFER/2);
#endif
}
break;
}
}
//if( intDriver->DriverSettings.antiAliasing) ApplyFilters( intDriver);
if( intDriver->DriverSettings.surround) ApplySurround( intDriver);
if( intDriver->DriverSettings.Reverb && intDriver->ASCBUFFER < intDriver->RDelay)
{
if( intDriver->DriverSettings.outPutMode == DeluxeStereoOutPut)
{
switch( intDriver->DriverSettings.outPutBits)
{
case 8:
ComputeReverb8( (Byte*) intDriver->ReverbPtr, (Byte*) intDriver->IntDataPtr, intDriver->ASCBUFFER*2L, intDriver->DriverSettings.ReverbStrength);
BlockMoveData( intDriver->ReverbPtr + intDriver->ASCBUFFER*2L, intDriver->ReverbPtr, intDriver->RDelay*2L - intDriver->ASCBUFFER*2L);
BlockMoveData( intDriver->IntDataPtr, intDriver->ReverbPtr + intDriver->RDelay*2L - intDriver->ASCBUFFER*2L, intDriver->ASCBUFFER*2L);
break;
case 16:
ComputeReverb16( (short*) intDriver->ReverbPtr, (short*) intDriver->IntDataPtr, intDriver->ASCBUFFER*2L, intDriver->DriverSettings.ReverbStrength);
BlockMoveData( intDriver->ReverbPtr + intDriver->ASCBUFFER*4, intDriver->ReverbPtr, (intDriver->RDelay - intDriver->ASCBUFFER)*4);
BlockMoveData( intDriver->IntDataPtr, intDriver->ReverbPtr + intDriver->RDelay*4 - intDriver->ASCBUFFER*4, intDriver->ASCBUFFER*4);
break;
}
}
}
}
void Filter8Bit( register Byte *myPtr, MADDriverRec *intDriver)
{
long i;
i = intDriver->ASCBUFFER-1;
while( i-- > 0)
{
*myPtr -= ( *myPtr - *(myPtr + 1)) >> 1;
myPtr++;
}
}
void Filter8BitX( register Byte *myPtr, MADDriverRec *intDriver)
{
long i;
i = intDriver->ASCBUFFER-1;
while( i-- > 0)
{
*myPtr -= ( *myPtr - *(myPtr + 2)) >> 1;
myPtr += 2;
}
}
void Filter16BitX( register short *myPtr, MADDriverRec *intDriver)
{
long i;
i = intDriver->ASCBUFFER-1;
while( i-- > 0)
{
*myPtr -= ( *myPtr - *(myPtr + 2)) >> 1;
myPtr += 2;
}
/* i = intDriver->ASCBUFFER-2;
myPtr += 2;
while( i-- > 0)
{
*myPtr -= ((*myPtr - *(myPtr + 2)) + (*myPtr - *(myPtr - 2))) >> 1;
myPtr += 2;
} */
}
void ApplyFilters( MADDriverRec *intDriver)
{
switch( intDriver->DriverSettings.outPutBits)
{
case 8:
switch( intDriver->DriverSettings.outPutMode)
{
/* case MonoOutPut:
Filter8Bit( (Byte*) intDriver->IntDataPtr, intDriver);
break;
case StereoOutPut:
Filter8BitX( (Byte*) intDriver->IntDataPtr, intDriver);
Filter8BitX( (Byte*) intDriver->IntDataPtr + 1, intDriver);
break;
*/
case DeluxeStereoOutPut:
Filter8BitX( (Byte*) intDriver->IntDataPtr, intDriver);
Filter8BitX( (Byte*) intDriver->IntDataPtr + 1, intDriver);
break;
}
break;
case 16:
switch( intDriver->DriverSettings.outPutMode)
{
/* case MonoOutPut:
break;
case StereoOutPut:*/
case DeluxeStereoOutPut:
/* {
short i;
for( i = 0; i < 10; i++)
{*/
Filter16BitX( ( short*) intDriver->IntDataPtr, intDriver);
Filter16BitX( ( short*) (intDriver->IntDataPtr) + 1, intDriver);
/* }
}*/
break;
}
break;
}
}
void ApplySurround( MADDriverRec *intDriver)
{
switch( intDriver->DriverSettings.outPutBits)
{
case 8:
switch( intDriver->DriverSettings.outPutMode)
{
case DeluxeStereoOutPut:
{
long i = intDriver->ASCBUFFER;
char *data = (char*) intDriver->IntDataPtr;
while( i-- > 0)
{
*data = -1-*data;
data += 2;
}
}
break;
}
break;
case 16:
switch( intDriver->DriverSettings.outPutMode)
{
case DeluxeStereoOutPut:
{
long i = intDriver->ASCBUFFER;
short *data = (short*) intDriver->IntDataPtr;
while( i-- > 0)
{
*data = -1-*data;
data += 2;
}
}
break;
}
break;
}
}
void GenerateSound( MADDriverRec *intDriver)
{
if( intDriver->DriverSettings.driverMode == MIDISoundDriver) return;
switch( intDriver->DriverSettings.outPutBits)
{
case 8:
switch( intDriver->DriverSettings.outPutMode)
{
/* case MonoOutPut:
Play8Mono( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER;
break;
case StereoOutPut:
Play8Stereo( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER*2L;
break;
*/
case DeluxeStereoOutPut:
Play8StereoDelay( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER*2L;
intDriver->DASCBuffer8 += intDriver->ASCBUFFER*2L;
break;
case PolyPhonic:
// case MultiFiles:
Play8PolyPhonic( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER * intDriver->DriverSettings.numChn;
break;
}
break;
case 16:
switch( intDriver->DriverSettings.outPutMode)
{
/* case MonoOutPut:
Play16Mono( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER*2L;
break;
case StereoOutPut:
Play16Stereo( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER*4L;
break;
*/
case DeluxeStereoOutPut:
Play16StereoDelay( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER*4L;
intDriver->DASCBuffer += intDriver->ASCBUFFER*2L;
break;
case PolyPhonic:
// case MultiFiles:
// Play16PolyPhonic( intDriver);
intDriver->IntDataPtr += intDriver->ASCBUFFER * 2L * intDriver->DriverSettings.numChn;
break;
}
break;
}
}
EXP Boolean DirectSave( Ptr myPtr, MADDriverSettings *driverType, MADDriverRec *intDriver)
{
Ptr ptrCopy;
MADDriverSettings driverCopy;
if( intDriver == 0L) return false; //intDriver = MADGetMADDriverPtr();
if( !intDriver->Reading) return false;
/*** Copy values ***/
ptrCopy = intDriver->IntDataPtr;
if( driverType != 0L) driverCopy = intDriver->DriverSettings;
/*** Install New Values ***/
intDriver->IntDataPtr = myPtr;
if( driverType != 0L) intDriver->DriverSettings = *driverType;
/***/ /***/
/***/ /***/
/***/ /***/
NoteAnalyse( intDriver);
/***/ /***/
/***/ /***/
/***/ /***/
/*** Restore values ***/
intDriver->IntDataPtr = ptrCopy;
if( driverType != 0L) intDriver->DriverSettings = driverCopy;
if( intDriver->musicEnd == true) return false;
if( intDriver->curMusic != 0L)
{
if( intDriver->PL >= intDriver->curMusic->header->numPointers) return false;
}
return true;
}
pascal void DMAPlay ( void)
{
/*unsigned long deferredArg;
long *destPtr;
Boolean DMAPlayNow;
short *tempIntG = 0L;
Ptr myPtr;
MADDriverRec *intDriver = MADGetMADDriverPtr();
DMAPlayNow = false;
if (SND_OUT_IF0) // buffer 0 just finished
{
deferredArg = kBuf0Offset; // set offset for copy
CLEAR_SND_OUT_IF0; // clear offending bit
destPtr = ( long*) ((long) DMABufferBase + (long) deferredArg);
DMAPlayNow = true;
}
if (SND_OUT_IF1) // buffer 1 just finished
{
deferredArg = kBuf1Offset; // set offset for copy
CLEAR_SND_OUT_IF1; // clear offending bit
destPtr = ( long*) ((long) DMABufferBase + (long) deferredArg);
DMAPlayNow = true;
}
if (SND_OUT_UNDERRUN) // whoops - we underran! clear it, re-enable DMA, & vamoose
{
CLEAR_UNDERRUN_INT; // only one kind of output error
SND_OUT_DMA_ENABLE; // re-enable sound out (underrun will have stopped it)
return; // return without setting up the DeferUserFn
}
if( DMAPlayNow)
{
myPtr = intDriver->IntDataPtr;
intDriver->IntDataPtr = (Ptr) destPtr;
DISABLE_BUF_AND_UNDERRUN_INTS;
NoteAnalyse( intDriver);
ENABLE_BUF_AND_UNDERRUN_INTS;
intDriver->OscilloWavePtr = intDriver->IntDataPtr;
intDriver->IntDataPtr = myPtr;
}*/
}
#ifdef _MAC_H
Ptr GetMyDoubleBackProc()
{
return (Ptr) MyDoubleBackProc;
}
pascal void MyDoubleBackProc(SndChannelPtr chan, SndDoubleBufferPtr doubleBuffer)
{
Ptr myPtr;
MADDriverRec *intDriver;
intDriver = (MADDriverRec*) doubleBuffer->dbUserInfo[ 0];
/********************/
/** Read Notes **/
/********************/
myPtr = intDriver->IntDataPtr;
intDriver->IntDataPtr = (char*) doubleBuffer->dbSoundData;
NoteAnalyse( intDriver);
intDriver->IntDataPtr = myPtr;
intDriver->OscilloWavePtr = (char*) doubleBuffer->dbSoundData;
doubleBuffer->dbNumFrames = intDriver->ASCBUFFER;
doubleBuffer->dbFlags |= dbBufferReady;
}
/*
MADDriverRec *MODPlayMADDriver;
#if defined(powerc) || defined (__powerc)
pascal void MODPlay (VBLTaskPtr theVBLTask)
{
theVBLTask->vblCount = 1;
NoteAnalyse( MODPlayMADDriver);
}
#else
pascal long GetVBLRec( void) = 0x2E88;
void MODPlay()
{
inVBLRec *recPtr;
MADDriverRec *intDriver;
recPtr = (inVBLRec*) GetVBLRec();
intDriver = (MADDriverRec*) recPtr->VBLA5;
recPtr->VBL.vblCount = 1;
NoteAnalyse( intDriver);
}
#endif*/
#endif
/*
void BufferCopyM( MADDriverRec *intDriver)
{
Ptr srcPtr = intDriver->IntDataPtr, destPtr = *((Ptr*) ASCBase);
BlockMoveData( srcPtr, destPtr, 370L);
}
void BufferCopyS( MADDriverRec *intDriver)
{
register Ptr srcPtr = intDriver->IntDataPtr, leftPtr = *((Ptr*) ASCBase), rightPtr = *((Ptr*) ASCBase) + 0x400L;
register short x = 370;
while( x-- > 0)
{
*leftPtr++ = *srcPtr++;
*rightPtr++ = *srcPtr++;
}
}*/
#ifdef _MIDIHARDWARE_
void NoteOff(short oldIns, short oldN, short oldV, MADDriverRec *intDriver)
{
OMSMIDIPacket pack;
if( intDriver->gOutNodeRefNum == -1) return;
/*** Note - OFF ***/
pack.flags = 0; //midiMsgType + midiTimeStampCurrent + midiNoCont;
pack.len = 3;
pack.data[ 0] = 0x80 + oldIns;
pack.data[ 1] = oldN + 12;
if( oldV < 64) pack.data[ 2] = 63 + oldV;
else pack.data[ 2] = 127;
#if defined(__MWERKS__)
OMSWritePacket2( &pack, intDriver->gOutNodeRefNum, intDriver->MIDIPortRefNum);
#endif
}
void AllNoteOff( MADDriverRec *intDriver)
{
short i;
if( intDriver->gOutNodeRefNum == -1) return;
for( i = 0; i < MAXTRACK; i++)
{
if( intDriver->NoteOld[ i] != -1)
{
NoteOff( intDriver->InstuNoOld[ i], intDriver->NoteOld[ i], intDriver->VelocityOld[ i], intDriver);
intDriver->NoteOld[ i] = -1;
}
}
}
void SampleMIDI( Channel *curVoice, short channel, short curN, MADDriverRec *intDriver)
{
OMSMIDIPacket pack;
if( intDriver->gOutNodeRefNum == -1) return;
/*** Note - ON ***/
pack.flags = 0; //midiMsgType + midiTimeStampCurrent + midiNoCont;
pack.len = 3;
pack.data[ 0] = 0x90 + channel;
pack.data[ 1] = curN + 12;
if( curVoice->vol < 64) pack.data[ 2] = 63 + curVoice->vol;
else pack.data[ 2] = 127;
#if defined(__MWERKS__)
OMSWritePacket2( &pack, intDriver->gOutNodeRefNum, intDriver->MIDIPortRefNum);
#endif
}
#else
void SampleMIDI( Channel *curVoice, short channel, short curN, MADDriverRec *intDriver){};
void AllNoteOff( MADDriverRec *intDriver){};
void NoteOff(short oldIns, short oldN, short oldV, MADDriverRec *intDriver){};
#endif