This program generates sound by using FM tone generator YMF825 via SPI.
Diff: fmasgn.c
- Revision:
- 0:c54d59d6fb78
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/fmasgn.c Fri Jan 05 22:58:49 2018 +0000 @@ -0,0 +1,131 @@ +// fmasgn.c +#include "fmtype.h" +#include "fmasgn.h" +#include "fmvoice.h" + +// Variable +static Fmvoice _fmvc[MAX_FM_VOICE]; +static Fmvoice* _firstEmptyVc; // old +static Fmvoice* _lastEmptyVc; // new +static Fmvoice* _firstOccupiedVc; // old +static Fmvoice* _lastOccupiedVc; // new + +// Prototype +static void setToEmptyList( Fmvoice* prevVc, Fmvoice* rlsVc ); + +// setter +void Asgn_setFirstEmptyVc( Fmvoice* vc ){ _firstEmptyVc = vc; } +void Asgn_setLastEmptyVc( Fmvoice* vc ){ _lastEmptyVc = vc; } + +// getter +Fmvoice* Asgn_voice( int num ){ return &(_fmvc[num]); } +Fmvoice* Asgn_firstEmptyVc( void ){ return _firstEmptyVc; } +Fmvoice* Asgn_lastEmptyVc( void ){ return _lastEmptyVc; } + +void Asgn_init( void ) +{ + int i; + + for ( i=0; i<MAX_FM_VOICE; i++) { + Fmvoice_init(&_fmvc[i]); + } + + _firstOccupiedVc = 0; + _lastOccupiedVc = 0; + + for ( i=0; i<MAX_FM_VOICE-1; i++ ){ + Fmvoice_setVoiceNum(&_fmvc[i], i); + Fmvoice_setNextVc(&_fmvc[i], &_fmvc[i + 1]); + } + + // for No.MAX_FM_VOICE-1 + Fmvoice_setVoiceNum(&_fmvc[MAX_FM_VOICE - 1], MAX_FM_VOICE - 1); + Fmvoice_setNextVc(&_fmvc[MAX_FM_VOICE - 1], FMNULL); + + _firstEmptyVc = &_fmvc[0]; + _lastEmptyVc = &_fmvc[MAX_FM_VOICE-1]; +} +bool Asgn_chkEmpty( void ) +{ + if ( _firstEmptyVc == FMNULL ){ return false; } + else { return true; } +} +Fmvoice* Asgn_getEmptyVc( void ) +{ + if ( _firstEmptyVc != FMNULL ){ + Fmvoice* ret = _firstEmptyVc; + _firstEmptyVc = Fmvoice_nextVc(_firstEmptyVc); + if ( _lastOccupiedVc != FMNULL ){ + Fmvoice_setNextVc(_lastOccupiedVc, ret); + } + _lastOccupiedVc = ret; + if ( _firstOccupiedVc == FMNULL ){ + _firstOccupiedVc = ret; + } + return ret; + } + else { + FMASSERT(0); + return FMNULL; + } +} +void Asgn_releaseOneVc( void ) +{ + if ( _firstOccupiedVc == FMNULL ){ + FMASSERT(0); + return; + } + + // Search keyoffed Voice + Fmvoice* rlsVc = _firstOccupiedVc; + Fmvoice* prevVc = FMNULL; + while (rlsVc != FMNULL ){ + if ( Fmvoice_isKeyon(rlsVc) == false ){ + break; + } + prevVc = rlsVc; + rlsVc = Fmvoice_nextVc(rlsVc); + } + + // if no keyoffed vc, select first one. + if ( rlsVc == FMNULL ){ + rlsVc = _firstOccupiedVc; + } + + setToEmptyList(prevVc,rlsVc); +} +void Asgn_releaseParticularVc( Fmvoice* pVc ) +{ + // Search pVc & its prevVc + Fmvoice* rlsVc = _firstOccupiedVc; + Fmvoice* prevVc = FMNULL; + while ( rlsVc != FMNULL ){ + if ( pVc == rlsVc ){ + break; + } + prevVc = rlsVc; + rlsVc = Fmvoice_nextVc(rlsVc); + } + setToEmptyList(prevVc,rlsVc); +} +static void setToEmptyList( Fmvoice* prevVc, Fmvoice* rlsVc ) +{ + // Release from Occupied list + if ( rlsVc == _firstOccupiedVc ){ + _firstOccupiedVc = Fmvoice_nextVc(rlsVc); + } + if ( rlsVc == _lastOccupiedVc ){ + _lastOccupiedVc = prevVc; + } + if ( prevVc != FMNULL ){ + Fmvoice_setNextVc(prevVc, Fmvoice_nextVc(rlsVc)); + } + Fmvoice_release(rlsVc); + + // Set Empty list + Fmvoice_setNextVc(_lastEmptyVc, rlsVc); + _lastEmptyVc = rlsVc; + if ( _firstEmptyVc == FMNULL ){ + _firstEmptyVc = rlsVc; + } +}