AudioPlaySystem.cpp
1 #include "emuapi.h" 2 3 #ifdef HAS_SND 4 5 #include "AudioPlaySystem.h" 6 #include <Arduino.h> 7 #define SAMPLERATE AUDIO_SAMPLE_RATE_EXACT 8 #define CLOCKFREQ 985248 9 10 #ifndef CUSTOM_SND 11 PROGMEM static const short square[]={ 12 32767,32767,32767,32767, 13 32767,32767,32767,32767, 14 32767,32767,32767,32767, 15 32767,32767,32767,32767, 16 32767,32767,32767,32767, 17 32767,32767,32767,32767, 18 32767,32767,32767,32767, 19 32767,32767,32767,32767, 20 -32767,-32767,-32767,-32767, 21 -32767,-32767,-32767,-32767, 22 -32767,-32767,-32767,-32767, 23 -32767,-32767,-32767,-32767, 24 -32767,-32767,-32767,-32767, 25 -32767,-32767,-32767,-32767, 26 -32767,-32767,-32767,-32767, 27 -32767,-32767,-32767,-32767, 28 }; 29 30 PROGMEM const short noise[] { 31 -32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767, 32 -32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,-32767,32767,-32767, 33 -32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767, 34 -32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,32767,-32767,-32767,32767,32767,-32767, 35 -32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,-32767,32767,32767,-32767, 36 -32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767, 37 32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767, 38 32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, 39 32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, 40 32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,-32767,-32767, 41 32767,-32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, 42 32767,-32767,32767,-32767,-32767,32767,32767,-32767,-32767,32767,-32767,32767,32767,32767,-32767,-32767, 43 32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, 44 32767,-32767,32767,-32767,-32767,32767,32767,-32767,32767,32767,-32767,32767,-32767,32767,-32767,-32767, 45 32767,32767,-32767,-32767,-32767,32767,-32767,-32767,-32767,-32767,32767,32767,32767,32767,32767,-32767, 46 32767,-32767,32767,-32767,-32767,32767,32767,32767,32767,32767,-32767,32767,-32767,32767,-32767,-32767, 47 }; 48 49 #define NOISEBSIZE 0x100 50 51 typedef struct 52 { 53 unsigned int spos; 54 unsigned int sinc; 55 unsigned int vol; 56 } Channel; 57 58 static Channel chan[6] = { 59 {0,0,0}, 60 {0,0,0}, 61 {0,0,0}, 62 {0,0,0}, 63 {0,0,0}, 64 {0,0,0} }; 65 66 #endif 67 68 volatile bool playing = false; 69 70 71 72 73 static void snd_Reset(void) 74 { 75 #ifndef CUSTOM_SND 76 chan[0].vol = 0; 77 chan[1].vol = 0; 78 chan[2].vol = 0; 79 chan[3].vol = 0; 80 chan[4].vol = 0; 81 chan[5].vol = 0; 82 chan[0].sinc = 0; 83 chan[1].sinc = 0; 84 chan[2].sinc = 0; 85 chan[3].sinc = 0; 86 chan[4].sinc = 0; 87 chan[5].sinc = 0; 88 #endif 89 } 90 91 92 #ifdef CUSTOM_SND 93 extern "C" { 94 void SND_Process(void *sndbuffer, int sndn); 95 } 96 #endif 97 98 static void snd_Mixer(short * stream, int len ) 99 { 100 if (playing) 101 { 102 #ifdef CUSTOM_SND 103 SND_Process((void*)stream, len); 104 #else 105 int i; 106 long s; 107 len = len >> 1; 108 109 short v0=chan[0].vol; 110 short v1=chan[1].vol; 111 short v2=chan[2].vol; 112 short v3=chan[3].vol; 113 short v4=chan[4].vol; 114 short v5=chan[5].vol; 115 for (i=0;i<len;i++) 116 { 117 s =((v0*square[(chan[0].spos>>8)&0x3f])>>11); 118 s+=((v1*square[(chan[1].spos>>8)&0x3f])>>11); 119 s+=((v2*square[(chan[2].spos>>8)&0x3f])>>11); 120 s+=((v3*noise[(chan[3].spos>>8)&(NOISEBSIZE-1)])>>11); 121 s+=((v4*noise[(chan[4].spos>>8)&(NOISEBSIZE-1)])>>11); 122 s+=((v5*noise[(chan[5].spos>>8)&(NOISEBSIZE-1)])>>11); 123 *stream++ = (short)(s); 124 *stream++ = (short)(s); 125 chan[0].spos += chan[0].sinc; 126 chan[1].spos += chan[1].sinc; 127 chan[2].spos += chan[2].sinc; 128 chan[3].spos += chan[3].sinc; 129 chan[4].spos += chan[4].sinc; 130 chan[5].spos += chan[5].sinc; 131 } 132 #endif 133 } 134 } 135 136 void AudioPlaySystem::begin(void) 137 { 138 //emu_printf("AudioPlaySystem constructor"); 139 this->reset(); 140 //setSampleParameters(CLOCKFREQ, SAMPLERATE); 141 } 142 143 void AudioPlaySystem::start(void) 144 { 145 //emu_printf("allocating sound buf"); 146 playing = true; 147 } 148 149 void AudioPlaySystem::setSampleParameters(float clockfreq, float samplerate) { 150 } 151 152 void AudioPlaySystem::reset(void) 153 { 154 snd_Reset(); 155 } 156 157 void AudioPlaySystem::stop(void) 158 { 159 //__disable_irq(); 160 playing = false; 161 //__enable_irq(); 162 } 163 164 bool AudioPlaySystem::isPlaying(void) 165 { 166 return playing; 167 } 168 169 void AudioPlaySystem::update(void) { 170 audio_block_t *block; 171 172 // only update if we're playing 173 if (!playing) return; 174 175 // allocate the audio blocks to transmit 176 block = allocate(); 177 if (block == NULL) return; 178 179 snd_Mixer((short*)block->data,AUDIO_BLOCK_SAMPLES); 180 //memset( (void*)block->data, 0, AUDIO_BLOCK_SAMPLES*2); 181 182 transmit(block); 183 release(block); 184 } 185 186 void AudioPlaySystem::sound(int C, int F, int V) { 187 #ifndef CUSTOM_SND 188 if (C < 6) { 189 chan[C].vol = V; 190 chan[C].sinc = F>>1; 191 } 192 #endif 193 } 194 195 void AudioPlaySystem::step(void) { 196 } 197 #endif 198