/ MCUME_teensy / teensypce / AudioPlaySystem.cpp
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  static void snd_Reset(void)
 72  {
 73  #ifndef CUSTOM_SND 
 74    chan[0].vol = 0;
 75    chan[1].vol = 0;
 76    chan[2].vol = 0;
 77    chan[3].vol = 0;
 78    chan[4].vol = 0;
 79    chan[5].vol = 0;
 80    chan[0].sinc = 0;
 81    chan[1].sinc = 0;
 82    chan[2].sinc = 0;
 83    chan[3].sinc = 0;
 84    chan[4].sinc = 0;
 85    chan[5].sinc = 0;
 86  #endif
 87  }
 88  
 89  
 90  #ifdef CUSTOM_SND 
 91  //extern "C" {
 92  void SND_Process(void *sndbuffer, int sndn);
 93  //}
 94  #endif
 95  
 96  
 97  FASTRUN void AudioPlaySystem::snd_Mixer(short *  stream, int len )
 98  {
 99    if (playing) 
100    {
101  #ifdef CUSTOM_SND
102      SND_Process((void*)stream, len);
103  #else
104      int i;
105      long s;     
106      len = len >> 1;   
107      short v0=chan[0].vol;
108      short v1=chan[1].vol;
109      short v2=chan[2].vol;
110      short v3=chan[3].vol;
111      short v4=chan[4].vol;
112      short v5=chan[5].vol;
113      for (i=0;i<len;i++)
114      {
115        s =((v0*square[(chan[0].spos>>8)&0x3f])>>11);
116        s+=((v1*square[(chan[1].spos>>8)&0x3f])>>11);
117        s+=((v2*square[(chan[2].spos>>8)&0x3f])>>11);
118        s+=((v3*noise[(chan[3].spos>>8)&(NOISEBSIZE-1)])>>11);
119        s+=((v4*noise[(chan[4].spos>>8)&(NOISEBSIZE-1)])>>11);
120        s+=((v5*noise[(chan[5].spos>>8)&(NOISEBSIZE-1)])>>11);         
121        *stream++ = (short)(s);
122        *stream++ = (short)(s);
123        chan[0].spos += chan[0].sinc;
124        chan[1].spos += chan[1].sinc;
125        chan[2].spos += chan[2].sinc;
126        chan[3].spos += chan[3].sinc;  
127        chan[4].spos += chan[4].sinc;  
128        chan[5].spos += chan[5].sinc;  
129      }
130  #endif         
131    }
132  }
133    
134  void AudioPlaySystem::begin(void)
135  {
136    this->reset();
137  }
138  
139  void AudioPlaySystem::start(void)
140  {
141  #ifndef HAS_T4_VGA
142    AudioMemory(16);
143  #endif  
144    playing = true;  
145  }
146  
147  void AudioPlaySystem::setSampleParameters(float clockfreq, float samplerate) {
148  }
149  
150  void AudioPlaySystem::reset(void)
151  {
152    snd_Reset();
153  }
154  
155  void AudioPlaySystem::stop(void)
156  {
157    //__disable_irq();
158    playing = false;  
159    //__enable_irq();
160  }
161  
162  bool AudioPlaySystem::isPlaying(void) 
163  { 
164    return playing; 
165  }
166  
167  #ifndef HAS_T4_VGA
168  void AudioPlaySystem::update(void) {
169    audio_block_t *block;
170  
171    // only update if we're playing
172    if (!playing) return;
173  
174    // allocate the audio blocks to transmit
175    block = allocate();
176    if (block == NULL) return;
177  
178    snd_Mixer((short*)block->data,AUDIO_BLOCK_SAMPLES);
179    //memset( (void*)block->data, 0, AUDIO_BLOCK_SAMPLES*2);
180  
181    transmit(block);
182    release(block);
183  }
184  #endif
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