ERIS CORE

◆ update()

void AudioSynthWaveformhd::update ( void  )
virtual

Implements AudioStream.

Reimplemented in erisAudioSynthWaveformhd, and erisAudioSynthWaveform.

Definition at line 45 of file eris_synth_waveform.cpp.

46 {
47  audio_block_t *block;
48  int16_t *bp, *end;
49  int32_t val1, val2;
50  int16_t magnitude15;
51  uint32_t i, ph, index, index2, scale;
52  const uint32_t inc = phase_increment;
53 
55  if (magnitude == 0) {
56  phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
57  return;
58  }
59  block = allocate();
60  if (!block) {
61  phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
62  return;
63  }
64  bp = block->data;
65 
66  switch(tone_type) {
67  case WAVEFORM_SINE:
68  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
69  index = ph >> 24;
70  val1 = AudioWaveformSine[index];
71  val2 = AudioWaveformSine[index+1];
72  scale = (ph >> 8) & 0xFFFF;
73  val2 *= scale;
74  val1 *= 0x10000 - scale;
75  *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
76  ph += inc;
77  }
78  break;
79 
80  case WAVEFORM_ARBITRARY:
81  if (!arbdata) {
82  release(block);
83  phase_accumulator += inc * AUDIO_BLOCK_SAMPLES;
84  return;
85  }
86  // len = 256
87  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
88  index = ph >> 21;
89  index2 = index + 1;
90  if (index2 >= 2048) index2 = 0;
91  val1 = *(arbdata + index);
92  val2 = *(arbdata + index2);
93  scale = (ph >> 8) & 0xFFFF;
94  val2 *= scale;
95  val1 *= 0x10000 - scale;
96  *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
97  ph += inc;
98  }
99  break;
100 
101  case WAVEFORM_SQUARE:
102  magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
103  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
104  if (ph & 0x80000000) {
105  *bp++ = -magnitude15;
106  } else {
107  *bp++ = magnitude15;
108  }
109  ph += inc;
110  }
111  break;
112 
113  case WAVEFORM_BANDLIMIT_SQUARE:
114  for (int i = 0 ; i < AUDIO_BLOCK_SAMPLES ; i++)
115  {
116  uint32_t new_ph = ph + inc ;
117  int16_t val = band_limit_waveform.generate_square (new_ph, i) ;
118  *bp++ = (val * magnitude) >> 16 ;
119  ph = new_ph ;
120  }
121  break;
122 
123  case WAVEFORM_SAWTOOTH:
124  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
125  *bp++ = signed_multiply_32x16t(magnitude, ph);
126  ph += inc;
127  }
128  break;
129 
130  case WAVEFORM_SAWTOOTH_REVERSE:
131  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
132  *bp++ = signed_multiply_32x16t(0xFFFFFFFFu - magnitude, ph);
133  ph += inc;
134  }
135  break;
136 
137  case WAVEFORM_BANDLIMIT_SAWTOOTH:
138  case WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE:
139  for (i = 0 ; i < AUDIO_BLOCK_SAMPLES; i++)
140  {
141  uint32_t new_ph = ph + inc ;
142  int16_t val = band_limit_waveform.generate_sawtooth (new_ph, i) ;
143  if (tone_type == WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE)
144  *bp++ = (val * -magnitude) >> 16 ;
145  else
146  *bp++ = (val * magnitude) >> 16 ;
147  ph = new_ph ;
148  }
149  break;
150 
151  case WAVEFORM_TRIANGLE:
152  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
153  uint32_t phtop = ph >> 30;
154  if (phtop == 1 || phtop == 2) {
155  *bp++ = ((0xFFFF - (ph >> 15)) * magnitude) >> 16;
156  } else {
157  *bp++ = (((int32_t)ph >> 15) * magnitude) >> 16;
158  }
159  ph += inc;
160  }
161  break;
162 
163  case WAVEFORM_TRIANGLE_VARIABLE:
164  do {
165  uint32_t rise = 0xFFFFFFFF / (pulse_width >> 16);
166  uint32_t fall = 0xFFFFFFFF / (0xFFFF - (pulse_width >> 16));
167  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
168  if (ph < pulse_width/2) {
169  uint32_t n = (ph >> 16) * rise;
170  *bp++ = ((n >> 16) * magnitude) >> 16;
171  } else if (ph < 0xFFFFFFFF - pulse_width/2) {
172  uint32_t n = 0x7FFFFFFF - (((ph - pulse_width/2) >> 16) * fall);
173  *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
174  } else {
175  uint32_t n = ((ph + pulse_width/2) >> 16) * rise + 0x80000000;
176  *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
177  }
178  ph += inc;
179  }
180  } while (0);
181  break;
182 
183  case WAVEFORM_PULSE:
184  magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
185  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
186  if (ph < pulse_width) {
187  *bp++ = magnitude15;
188  } else {
189  *bp++ = -magnitude15;
190  }
191  ph += inc;
192  }
193  break;
194 
195  case WAVEFORM_BANDLIMIT_PULSE:
196  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++)
197  {
198  int32_t new_ph = ph + inc ;
199  int32_t val = band_limit_waveform.generate_pulse (new_ph, pulse_width, i) ;
200  *bp++ = (int16_t) ((val * magnitude) >> 16) ;
201  ph = new_ph ;
202  }
203  break;
204 
205  case WAVEFORM_SAMPLE_HOLD:
206  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
207  *bp++ = sample;
208  uint32_t newph = ph + inc;
209  if (newph < ph) {
210  sample = random(magnitude) - (magnitude >> 1);
211  }
212  ph = newph;
213  }
214  break;
215  }
217 
218  if (tone_offset) {
219  bp = block->data;
220  end = bp + AUDIO_BLOCK_SAMPLES;
221  do {
222  val1 = *bp;
223  *bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
224  } while (bp < end);
225  }
226  transmit(block, 0);
227  release(block);
228 }
static void release(audio_block_t *block)
static audio_block_t * allocate(void)
Definition: AudioStream.cpp:92
void transmit(audio_block_t *block, unsigned char index=0)
BandLimitedWaveform band_limit_waveform
const int16_t AudioWaveformSine[257]
int16_t data[AUDIO_BLOCK_SAMPLES]
Definition: AudioStream.h:78

References AudioStream::allocate(), arbdata, AudioWaveformSine, band_limit_waveform, audio_block_struct::data, magnitude, phase_accumulator, phase_increment, phase_offset, pulse_width, AudioStream::release(), sample, tone_offset, tone_type, and AudioStream::transmit().

Referenced by erisAudioSynthWaveform::update(), and erisAudioSynthWaveformhd::update().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: