This program generates sound by using FM tone generator YMF825 via SPI.

Dependencies:   microbit

Committer:
hasebems
Date:
Fri Jan 05 22:58:49 2018 +0000
Revision:
0:c54d59d6fb78
???????????????

Who changed what in which revision?

UserRevisionLine numberNew contents of line
hasebems 0:c54d59d6fb78 1 // fmasgn.c
hasebems 0:c54d59d6fb78 2 #include "fmtype.h"
hasebems 0:c54d59d6fb78 3 #include "fmasgn.h"
hasebems 0:c54d59d6fb78 4 #include "fmvoice.h"
hasebems 0:c54d59d6fb78 5
hasebems 0:c54d59d6fb78 6 // Variable
hasebems 0:c54d59d6fb78 7 static Fmvoice _fmvc[MAX_FM_VOICE];
hasebems 0:c54d59d6fb78 8 static Fmvoice* _firstEmptyVc; // old
hasebems 0:c54d59d6fb78 9 static Fmvoice* _lastEmptyVc; // new
hasebems 0:c54d59d6fb78 10 static Fmvoice* _firstOccupiedVc; // old
hasebems 0:c54d59d6fb78 11 static Fmvoice* _lastOccupiedVc; // new
hasebems 0:c54d59d6fb78 12
hasebems 0:c54d59d6fb78 13 // Prototype
hasebems 0:c54d59d6fb78 14 static void setToEmptyList( Fmvoice* prevVc, Fmvoice* rlsVc );
hasebems 0:c54d59d6fb78 15
hasebems 0:c54d59d6fb78 16 // setter
hasebems 0:c54d59d6fb78 17 void Asgn_setFirstEmptyVc( Fmvoice* vc ){ _firstEmptyVc = vc; }
hasebems 0:c54d59d6fb78 18 void Asgn_setLastEmptyVc( Fmvoice* vc ){ _lastEmptyVc = vc; }
hasebems 0:c54d59d6fb78 19
hasebems 0:c54d59d6fb78 20 // getter
hasebems 0:c54d59d6fb78 21 Fmvoice* Asgn_voice( int num ){ return &(_fmvc[num]); }
hasebems 0:c54d59d6fb78 22 Fmvoice* Asgn_firstEmptyVc( void ){ return _firstEmptyVc; }
hasebems 0:c54d59d6fb78 23 Fmvoice* Asgn_lastEmptyVc( void ){ return _lastEmptyVc; }
hasebems 0:c54d59d6fb78 24
hasebems 0:c54d59d6fb78 25 void Asgn_init( void )
hasebems 0:c54d59d6fb78 26 {
hasebems 0:c54d59d6fb78 27 int i;
hasebems 0:c54d59d6fb78 28
hasebems 0:c54d59d6fb78 29 for ( i=0; i<MAX_FM_VOICE; i++) {
hasebems 0:c54d59d6fb78 30 Fmvoice_init(&_fmvc[i]);
hasebems 0:c54d59d6fb78 31 }
hasebems 0:c54d59d6fb78 32
hasebems 0:c54d59d6fb78 33 _firstOccupiedVc = 0;
hasebems 0:c54d59d6fb78 34 _lastOccupiedVc = 0;
hasebems 0:c54d59d6fb78 35
hasebems 0:c54d59d6fb78 36 for ( i=0; i<MAX_FM_VOICE-1; i++ ){
hasebems 0:c54d59d6fb78 37 Fmvoice_setVoiceNum(&_fmvc[i], i);
hasebems 0:c54d59d6fb78 38 Fmvoice_setNextVc(&_fmvc[i], &_fmvc[i + 1]);
hasebems 0:c54d59d6fb78 39 }
hasebems 0:c54d59d6fb78 40
hasebems 0:c54d59d6fb78 41 // for No.MAX_FM_VOICE-1
hasebems 0:c54d59d6fb78 42 Fmvoice_setVoiceNum(&_fmvc[MAX_FM_VOICE - 1], MAX_FM_VOICE - 1);
hasebems 0:c54d59d6fb78 43 Fmvoice_setNextVc(&_fmvc[MAX_FM_VOICE - 1], FMNULL);
hasebems 0:c54d59d6fb78 44
hasebems 0:c54d59d6fb78 45 _firstEmptyVc = &_fmvc[0];
hasebems 0:c54d59d6fb78 46 _lastEmptyVc = &_fmvc[MAX_FM_VOICE-1];
hasebems 0:c54d59d6fb78 47 }
hasebems 0:c54d59d6fb78 48 bool Asgn_chkEmpty( void )
hasebems 0:c54d59d6fb78 49 {
hasebems 0:c54d59d6fb78 50 if ( _firstEmptyVc == FMNULL ){ return false; }
hasebems 0:c54d59d6fb78 51 else { return true; }
hasebems 0:c54d59d6fb78 52 }
hasebems 0:c54d59d6fb78 53 Fmvoice* Asgn_getEmptyVc( void )
hasebems 0:c54d59d6fb78 54 {
hasebems 0:c54d59d6fb78 55 if ( _firstEmptyVc != FMNULL ){
hasebems 0:c54d59d6fb78 56 Fmvoice* ret = _firstEmptyVc;
hasebems 0:c54d59d6fb78 57 _firstEmptyVc = Fmvoice_nextVc(_firstEmptyVc);
hasebems 0:c54d59d6fb78 58 if ( _lastOccupiedVc != FMNULL ){
hasebems 0:c54d59d6fb78 59 Fmvoice_setNextVc(_lastOccupiedVc, ret);
hasebems 0:c54d59d6fb78 60 }
hasebems 0:c54d59d6fb78 61 _lastOccupiedVc = ret;
hasebems 0:c54d59d6fb78 62 if ( _firstOccupiedVc == FMNULL ){
hasebems 0:c54d59d6fb78 63 _firstOccupiedVc = ret;
hasebems 0:c54d59d6fb78 64 }
hasebems 0:c54d59d6fb78 65 return ret;
hasebems 0:c54d59d6fb78 66 }
hasebems 0:c54d59d6fb78 67 else {
hasebems 0:c54d59d6fb78 68 FMASSERT(0);
hasebems 0:c54d59d6fb78 69 return FMNULL;
hasebems 0:c54d59d6fb78 70 }
hasebems 0:c54d59d6fb78 71 }
hasebems 0:c54d59d6fb78 72 void Asgn_releaseOneVc( void )
hasebems 0:c54d59d6fb78 73 {
hasebems 0:c54d59d6fb78 74 if ( _firstOccupiedVc == FMNULL ){
hasebems 0:c54d59d6fb78 75 FMASSERT(0);
hasebems 0:c54d59d6fb78 76 return;
hasebems 0:c54d59d6fb78 77 }
hasebems 0:c54d59d6fb78 78
hasebems 0:c54d59d6fb78 79 // Search keyoffed Voice
hasebems 0:c54d59d6fb78 80 Fmvoice* rlsVc = _firstOccupiedVc;
hasebems 0:c54d59d6fb78 81 Fmvoice* prevVc = FMNULL;
hasebems 0:c54d59d6fb78 82 while (rlsVc != FMNULL ){
hasebems 0:c54d59d6fb78 83 if ( Fmvoice_isKeyon(rlsVc) == false ){
hasebems 0:c54d59d6fb78 84 break;
hasebems 0:c54d59d6fb78 85 }
hasebems 0:c54d59d6fb78 86 prevVc = rlsVc;
hasebems 0:c54d59d6fb78 87 rlsVc = Fmvoice_nextVc(rlsVc);
hasebems 0:c54d59d6fb78 88 }
hasebems 0:c54d59d6fb78 89
hasebems 0:c54d59d6fb78 90 // if no keyoffed vc, select first one.
hasebems 0:c54d59d6fb78 91 if ( rlsVc == FMNULL ){
hasebems 0:c54d59d6fb78 92 rlsVc = _firstOccupiedVc;
hasebems 0:c54d59d6fb78 93 }
hasebems 0:c54d59d6fb78 94
hasebems 0:c54d59d6fb78 95 setToEmptyList(prevVc,rlsVc);
hasebems 0:c54d59d6fb78 96 }
hasebems 0:c54d59d6fb78 97 void Asgn_releaseParticularVc( Fmvoice* pVc )
hasebems 0:c54d59d6fb78 98 {
hasebems 0:c54d59d6fb78 99 // Search pVc & its prevVc
hasebems 0:c54d59d6fb78 100 Fmvoice* rlsVc = _firstOccupiedVc;
hasebems 0:c54d59d6fb78 101 Fmvoice* prevVc = FMNULL;
hasebems 0:c54d59d6fb78 102 while ( rlsVc != FMNULL ){
hasebems 0:c54d59d6fb78 103 if ( pVc == rlsVc ){
hasebems 0:c54d59d6fb78 104 break;
hasebems 0:c54d59d6fb78 105 }
hasebems 0:c54d59d6fb78 106 prevVc = rlsVc;
hasebems 0:c54d59d6fb78 107 rlsVc = Fmvoice_nextVc(rlsVc);
hasebems 0:c54d59d6fb78 108 }
hasebems 0:c54d59d6fb78 109 setToEmptyList(prevVc,rlsVc);
hasebems 0:c54d59d6fb78 110 }
hasebems 0:c54d59d6fb78 111 static void setToEmptyList( Fmvoice* prevVc, Fmvoice* rlsVc )
hasebems 0:c54d59d6fb78 112 {
hasebems 0:c54d59d6fb78 113 // Release from Occupied list
hasebems 0:c54d59d6fb78 114 if ( rlsVc == _firstOccupiedVc ){
hasebems 0:c54d59d6fb78 115 _firstOccupiedVc = Fmvoice_nextVc(rlsVc);
hasebems 0:c54d59d6fb78 116 }
hasebems 0:c54d59d6fb78 117 if ( rlsVc == _lastOccupiedVc ){
hasebems 0:c54d59d6fb78 118 _lastOccupiedVc = prevVc;
hasebems 0:c54d59d6fb78 119 }
hasebems 0:c54d59d6fb78 120 if ( prevVc != FMNULL ){
hasebems 0:c54d59d6fb78 121 Fmvoice_setNextVc(prevVc, Fmvoice_nextVc(rlsVc));
hasebems 0:c54d59d6fb78 122 }
hasebems 0:c54d59d6fb78 123 Fmvoice_release(rlsVc);
hasebems 0:c54d59d6fb78 124
hasebems 0:c54d59d6fb78 125 // Set Empty list
hasebems 0:c54d59d6fb78 126 Fmvoice_setNextVc(_lastEmptyVc, rlsVc);
hasebems 0:c54d59d6fb78 127 _lastEmptyVc = rlsVc;
hasebems 0:c54d59d6fb78 128 if ( _firstEmptyVc == FMNULL ){
hasebems 0:c54d59d6fb78 129 _firstEmptyVc = rlsVc;
hasebems 0:c54d59d6fb78 130 }
hasebems 0:c54d59d6fb78 131 }