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 // 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