This program generates sound by using FM tone generator YMF825 via SPI.
fmpart.c@0:c54d59d6fb78, 2018-01-05 (annotated)
- Committer:
- hasebems
- Date:
- Fri Jan 05 22:58:49 2018 +0000
- Revision:
- 0:c54d59d6fb78
???????????????
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
hasebems | 0:c54d59d6fb78 | 1 | // fmpart.c |
hasebems | 0:c54d59d6fb78 | 2 | #include "fmtype.h" |
hasebems | 0:c54d59d6fb78 | 3 | #include "fmpart.h" |
hasebems | 0:c54d59d6fb78 | 4 | #include "fmsd1.h" |
hasebems | 0:c54d59d6fb78 | 5 | #include "fmasgn.h" |
hasebems | 0:c54d59d6fb78 | 6 | #include "fmtone.h" |
hasebems | 0:c54d59d6fb78 | 7 | |
hasebems | 0:c54d59d6fb78 | 8 | // Prototype |
hasebems | 0:c54d59d6fb78 | 9 | static Note* getNote(Part* _this); |
hasebems | 0:c54d59d6fb78 | 10 | |
hasebems | 0:c54d59d6fb78 | 11 | // getter |
hasebems | 0:c54d59d6fb78 | 12 | unsigned char Part_cc1(Part* _this){ return _this->_cc1; } |
hasebems | 0:c54d59d6fb78 | 13 | unsigned char Part_cc7(Part* _this){ return _this->_cc7; } |
hasebems | 0:c54d59d6fb78 | 14 | unsigned short Part_pb(Part* _this){ return _this->_pbvalue; } |
hasebems | 0:c54d59d6fb78 | 15 | unsigned char Part_toneNumber(Part* _this){ return _this->_toneNumber; } |
hasebems | 0:c54d59d6fb78 | 16 | |
hasebems | 0:c54d59d6fb78 | 17 | void Part_init( Part* _this ) |
hasebems | 0:c54d59d6fb78 | 18 | { |
hasebems | 0:c54d59d6fb78 | 19 | int i; |
hasebems | 0:c54d59d6fb78 | 20 | |
hasebems | 0:c54d59d6fb78 | 21 | Asgn_init(); |
hasebems | 0:c54d59d6fb78 | 22 | Tone_init(); |
hasebems | 0:c54d59d6fb78 | 23 | |
hasebems | 0:c54d59d6fb78 | 24 | _this->_topNt = 0; |
hasebems | 0:c54d59d6fb78 | 25 | _this->_endNt = 0; |
hasebems | 0:c54d59d6fb78 | 26 | _this->_cc1 = 0; |
hasebems | 0:c54d59d6fb78 | 27 | _this->_cc7 = 100; |
hasebems | 0:c54d59d6fb78 | 28 | _this->_cc64 = 0; |
hasebems | 0:c54d59d6fb78 | 29 | _this->_pbvalue = 0x2000; |
hasebems | 0:c54d59d6fb78 | 30 | _this->_toneNumber = 0; |
hasebems | 0:c54d59d6fb78 | 31 | |
hasebems | 0:c54d59d6fb78 | 32 | for ( i=0; i<MAX_NOTE_OBJECT; i++ ){ |
hasebems | 0:c54d59d6fb78 | 33 | Note_init(&_this->_note[i]); |
hasebems | 0:c54d59d6fb78 | 34 | Note_setPart(&_this->_note[i], (void*)_this); |
hasebems | 0:c54d59d6fb78 | 35 | } |
hasebems | 0:c54d59d6fb78 | 36 | } |
hasebems | 0:c54d59d6fb78 | 37 | void Part_note( Part* _this, unsigned char note, unsigned char velocity ) |
hasebems | 0:c54d59d6fb78 | 38 | { |
hasebems | 0:c54d59d6fb78 | 39 | if ( velocity != 0 ){ |
hasebems | 0:c54d59d6fb78 | 40 | // keyon |
hasebems | 0:c54d59d6fb78 | 41 | Note* newNt = getNote(_this); |
hasebems | 0:c54d59d6fb78 | 42 | if ( Note_keyon(newNt,&_this->_tone,note,velocity) == true ){ |
hasebems | 0:c54d59d6fb78 | 43 | if ( _this->_endNt != FMNULL ){ |
hasebems | 0:c54d59d6fb78 | 44 | Note_setNextPtr( _this->_endNt,newNt ); |
hasebems | 0:c54d59d6fb78 | 45 | Note_setPrevPtr( newNt,_this->_endNt ); |
hasebems | 0:c54d59d6fb78 | 46 | } |
hasebems | 0:c54d59d6fb78 | 47 | _this->_endNt = newNt; |
hasebems | 0:c54d59d6fb78 | 48 | if ( _this->_topNt ==FMNULL ){ |
hasebems | 0:c54d59d6fb78 | 49 | _this->_topNt = newNt; |
hasebems | 0:c54d59d6fb78 | 50 | } |
hasebems | 0:c54d59d6fb78 | 51 | } |
hasebems | 0:c54d59d6fb78 | 52 | } |
hasebems | 0:c54d59d6fb78 | 53 | else { |
hasebems | 0:c54d59d6fb78 | 54 | // keyoff |
hasebems | 0:c54d59d6fb78 | 55 | Note* nt = _this->_topNt; |
hasebems | 0:c54d59d6fb78 | 56 | while( nt != 0 ){ |
hasebems | 0:c54d59d6fb78 | 57 | if (( Note_note(nt) == note ) && |
hasebems | 0:c54d59d6fb78 | 58 | ( Note_isKeyOn(nt) == true ) && |
hasebems | 0:c54d59d6fb78 | 59 | ( Note_isHeld(nt) == false )){ |
hasebems | 0:c54d59d6fb78 | 60 | if ( _this->_cc64 < 64 ){ |
hasebems | 0:c54d59d6fb78 | 61 | Note_keyoff(nt); |
hasebems | 0:c54d59d6fb78 | 62 | } |
hasebems | 0:c54d59d6fb78 | 63 | else { |
hasebems | 0:c54d59d6fb78 | 64 | Note_setHold(nt,true); |
hasebems | 0:c54d59d6fb78 | 65 | } |
hasebems | 0:c54d59d6fb78 | 66 | break; |
hasebems | 0:c54d59d6fb78 | 67 | } |
hasebems | 0:c54d59d6fb78 | 68 | nt = Note_nextPtr(nt); |
hasebems | 0:c54d59d6fb78 | 69 | } |
hasebems | 0:c54d59d6fb78 | 70 | } |
hasebems | 0:c54d59d6fb78 | 71 | } |
hasebems | 0:c54d59d6fb78 | 72 | void Part_releaseNote( Part* _this, Note* nt ) |
hasebems | 0:c54d59d6fb78 | 73 | { |
hasebems | 0:c54d59d6fb78 | 74 | Note* prevPtr = Note_prevPtr(nt); |
hasebems | 0:c54d59d6fb78 | 75 | if ( _this->_endNt == nt ){ |
hasebems | 0:c54d59d6fb78 | 76 | _this->_endNt = prevPtr; |
hasebems | 0:c54d59d6fb78 | 77 | } |
hasebems | 0:c54d59d6fb78 | 78 | if ( prevPtr != FMNULL ){ |
hasebems | 0:c54d59d6fb78 | 79 | Note_setNextPtr(prevPtr, Note_nextPtr(nt)); |
hasebems | 0:c54d59d6fb78 | 80 | } |
hasebems | 0:c54d59d6fb78 | 81 | |
hasebems | 0:c54d59d6fb78 | 82 | Note* nextPtr = Note_nextPtr(nt); |
hasebems | 0:c54d59d6fb78 | 83 | if ( _this->_topNt == nt ){ |
hasebems | 0:c54d59d6fb78 | 84 | _this->_topNt = nextPtr; |
hasebems | 0:c54d59d6fb78 | 85 | } |
hasebems | 0:c54d59d6fb78 | 86 | if ( nextPtr != FMNULL ){ |
hasebems | 0:c54d59d6fb78 | 87 | Note_setPrevPtr(nextPtr, Note_prevPtr(nt)); |
hasebems | 0:c54d59d6fb78 | 88 | } |
hasebems | 0:c54d59d6fb78 | 89 | } |
hasebems | 0:c54d59d6fb78 | 90 | void Part_cc( Part* _this, unsigned char ccnum, unsigned char value ) |
hasebems | 0:c54d59d6fb78 | 91 | { |
hasebems | 0:c54d59d6fb78 | 92 | Note* nt = _this->_topNt; |
hasebems | 0:c54d59d6fb78 | 93 | |
hasebems | 0:c54d59d6fb78 | 94 | // Limit |
hasebems | 0:c54d59d6fb78 | 95 | if (value > 127) { value = 127; } |
hasebems | 0:c54d59d6fb78 | 96 | |
hasebems | 0:c54d59d6fb78 | 97 | switch (ccnum) { |
hasebems | 0:c54d59d6fb78 | 98 | case 1: { |
hasebems | 0:c54d59d6fb78 | 99 | _this->_cc1 = value; |
hasebems | 0:c54d59d6fb78 | 100 | while ( nt != FMNULL ) { |
hasebems | 0:c54d59d6fb78 | 101 | Note_chgVibDpt(nt); |
hasebems | 0:c54d59d6fb78 | 102 | nt = Note_nextPtr(nt); |
hasebems | 0:c54d59d6fb78 | 103 | } |
hasebems | 0:c54d59d6fb78 | 104 | break; |
hasebems | 0:c54d59d6fb78 | 105 | } |
hasebems | 0:c54d59d6fb78 | 106 | case 7: { |
hasebems | 0:c54d59d6fb78 | 107 | _this->_cc7 = value; |
hasebems | 0:c54d59d6fb78 | 108 | writeSingle( REG_MASTER_VOL, (value<<1)&0xfc ); |
hasebems | 0:c54d59d6fb78 | 109 | break; |
hasebems | 0:c54d59d6fb78 | 110 | } |
hasebems | 0:c54d59d6fb78 | 111 | case 64: { |
hasebems | 0:c54d59d6fb78 | 112 | _this->_cc64 = value; |
hasebems | 0:c54d59d6fb78 | 113 | if ( value < 64 ){ |
hasebems | 0:c54d59d6fb78 | 114 | while ( nt != FMNULL ) { |
hasebems | 0:c54d59d6fb78 | 115 | if ( Note_isHeld(nt) == true ){ |
hasebems | 0:c54d59d6fb78 | 116 | Note_keyoff(nt); |
hasebems | 0:c54d59d6fb78 | 117 | } |
hasebems | 0:c54d59d6fb78 | 118 | nt = Note_nextPtr(nt); |
hasebems | 0:c54d59d6fb78 | 119 | } |
hasebems | 0:c54d59d6fb78 | 120 | } |
hasebems | 0:c54d59d6fb78 | 121 | break; |
hasebems | 0:c54d59d6fb78 | 122 | } |
hasebems | 0:c54d59d6fb78 | 123 | default: break; |
hasebems | 0:c54d59d6fb78 | 124 | } |
hasebems | 0:c54d59d6fb78 | 125 | } |
hasebems | 0:c54d59d6fb78 | 126 | void Part_pc( Part* _this, unsigned char num ) |
hasebems | 0:c54d59d6fb78 | 127 | { |
hasebems | 0:c54d59d6fb78 | 128 | Note* nt = _this->_topNt; |
hasebems | 0:c54d59d6fb78 | 129 | Note* nextNt; |
hasebems | 0:c54d59d6fb78 | 130 | |
hasebems | 0:c54d59d6fb78 | 131 | // Damp |
hasebems | 0:c54d59d6fb78 | 132 | while ( nt != FMNULL ) { |
hasebems | 0:c54d59d6fb78 | 133 | nextNt = Note_nextPtr(nt); |
hasebems | 0:c54d59d6fb78 | 134 | Note_damp(nt); |
hasebems | 0:c54d59d6fb78 | 135 | nt = nextNt; |
hasebems | 0:c54d59d6fb78 | 136 | } |
hasebems | 0:c54d59d6fb78 | 137 | |
hasebems | 0:c54d59d6fb78 | 138 | _this->_toneNumber = num; |
hasebems | 0:c54d59d6fb78 | 139 | } |
hasebems | 0:c54d59d6fb78 | 140 | void Part_pbend( Part* _this, unsigned char lsb, unsigned char msb ) |
hasebems | 0:c54d59d6fb78 | 141 | { |
hasebems | 0:c54d59d6fb78 | 142 | Note* nt = _this->_topNt; |
hasebems | 0:c54d59d6fb78 | 143 | _this->_pbvalue = (msb<<7)|(lsb&0x7f); |
hasebems | 0:c54d59d6fb78 | 144 | while ( nt != FMNULL ) { |
hasebems | 0:c54d59d6fb78 | 145 | Note_chgPit(nt); |
hasebems | 0:c54d59d6fb78 | 146 | nt = Note_nextPtr(nt); |
hasebems | 0:c54d59d6fb78 | 147 | } |
hasebems | 0:c54d59d6fb78 | 148 | } |
hasebems | 0:c54d59d6fb78 | 149 | static Note* getNote( Part* _this ) |
hasebems | 0:c54d59d6fb78 | 150 | { |
hasebems | 0:c54d59d6fb78 | 151 | int i; |
hasebems | 0:c54d59d6fb78 | 152 | Note* newNt = 0; |
hasebems | 0:c54d59d6fb78 | 153 | for ( i=0; i<MAX_NOTE_OBJECT; i++ ){ |
hasebems | 0:c54d59d6fb78 | 154 | newNt = &(_this->_note[i]); |
hasebems | 0:c54d59d6fb78 | 155 | if ( Note_isInUse(newNt) == false ){ |
hasebems | 0:c54d59d6fb78 | 156 | return newNt; |
hasebems | 0:c54d59d6fb78 | 157 | } |
hasebems | 0:c54d59d6fb78 | 158 | } |
hasebems | 0:c54d59d6fb78 | 159 | // if nothing |
hasebems | 0:c54d59d6fb78 | 160 | newNt = _this->_topNt; |
hasebems | 0:c54d59d6fb78 | 161 | Note_damp(newNt); |
hasebems | 0:c54d59d6fb78 | 162 | return newNt; |
hasebems | 0:c54d59d6fb78 | 163 | } |
hasebems | 0:c54d59d6fb78 | 164 |