ERIS CORE

◆ update()

void AudioSynthWaveformModulated2k::update ( void  )
virtual

Implements AudioStream.

Reimplemented in erisAudioSynthWaveformModulated2k, and erisAudioSynthWaveformModulated.

Definition at line 239 of file eris_synth_waveform.cpp.

240 {
241  audio_block_t *block, *moddata, *shapedata;
242  int16_t *bp, *end;
243  int32_t val1, val2;
244  int16_t magnitude15;
245  uint32_t i, ph, index, index2, scale, priorphase;
246  const uint32_t inc = phase_increment;
247 
248  moddata = receiveReadOnly(0);
249  shapedata = receiveReadOnly(1);
250 
251  // Pre-compute the phase angle for every output sample of this update
252  ph = phase_accumulator;
253  priorphase = phasedata[AUDIO_BLOCK_SAMPLES-1];
254  if (moddata && modulation_type == 0) {
255  // Frequency Modulation
256  bp = moddata->data;
257  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
258  int32_t n = (*bp++) * modulation_factor; // n is # of octaves to mod
259  int32_t ipart = n >> 27; // 4 integer bits
260  n &= 0x7FFFFFF; // 27 fractional bits
261  #ifdef IMPROVE_EXPONENTIAL_ACCURACY
262  // exp2 polynomial suggested by Stefan Stenzel on "music-dsp"
263  // mail list, Wed, 3 Sep 2014 10:08:55 +0200
264  int32_t x = n << 3;
265  n = multiply_accumulate_32x32_rshift32_rounded(536870912, x, 1494202713);
266  int32_t sq = multiply_32x32_rshift32_rounded(x, x);
267  n = multiply_accumulate_32x32_rshift32_rounded(n, sq, 1934101615);
268  n = n + (multiply_32x32_rshift32_rounded(sq,
269  multiply_32x32_rshift32_rounded(x, 1358044250)) << 1);
270  n = n << 1;
271  #else
272  // exp2 algorithm by Laurent de Soras
273  // https://www.musicdsp.org/en/latest/Other/106-fast-exp2-approximation.html
274  n = (n + 134217728) << 3;
275 
276  n = multiply_32x32_rshift32_rounded(n, n);
277  n = multiply_32x32_rshift32_rounded(n, 715827883) << 3;
278  n = n + 715827882;
279  #endif
280  uint32_t scale = n >> (14 - ipart);
281  uint64_t phstep = (uint64_t)inc * scale;
282  uint32_t phstep_msw = phstep >> 32;
283  if (phstep_msw < 0x7FFE) {
284  ph += phstep >> 16;
285  } else {
286  ph += 0x7FFE0000;
287  }
288  phasedata[i] = ph;
289  }
290  release(moddata);
291  } else if (moddata) {
292  // Phase Modulation
293  bp = moddata->data;
294  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
295  // more than +/- 180 deg shift by 32 bit overflow of "n"
296  uint32_t n = ((uint32_t)(*bp++)) * modulation_factor;
297  phasedata[i] = ph + n;
298  ph += inc;
299  }
300  release(moddata);
301  } else {
302  // No Modulation Input
303  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
304  phasedata[i] = ph;
305  ph += inc;
306  }
307  }
308  phase_accumulator = ph;
309 
310  // If the amplitude is zero, no output, but phase still increments properly
311  if (magnitude == 0) {
312  if (shapedata) release(shapedata);
313  return;
314  }
315  block = allocate();
316  if (!block) {
317  if (shapedata) release(shapedata);
318  return;
319  }
320  bp = block->data;
321 
322  // Now generate the output samples using the pre-computed phase angles
323  switch(tone_type) {
324  case WAVEFORM_SINE:
325  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
326  ph = phasedata[i];
327  index = ph >> 24;
328  val1 = AudioWaveformSine[index];
329  val2 = AudioWaveformSine[index+1];
330  scale = (ph >> 8) & 0xFFFF;
331  val2 *= scale;
332  val1 *= 0x10000 - scale;
333  *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
334  }
335  break;
336 
337  case WAVEFORM_ARBITRARY:
338  if (!arbdata) {
339  release(block);
340  if (shapedata) release(shapedata);
341  return;
342  }
343  // len = 256
344  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
345  ph = phasedata[i];
346  index = ph >> 21;//ERIS CORE -- change from 24 (256 sample) to 21 (2048 samples)
347  index2 = index + 1;
348  if (index2 >= 2048) index2 = 0;
349  val1 = *(arbdata + index);
350  val2 = *(arbdata + index2);
351  scale = (ph >> 8) & 0xFFFF;
352  val2 *= scale;
353  val1 *= 0x10000 - scale;
354  *bp++ = multiply_32x32_rshift32(val1 + val2, magnitude);
355  }
356  break;
357 
358  case WAVEFORM_PULSE:
359  if (shapedata) {
360  magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
361  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
362  uint32_t width = ((shapedata->data[i] + 0x8000) & 0xFFFF) << 16;
363  if (phasedata[i] < width) {
364  *bp++ = magnitude15;
365  } else {
366  *bp++ = -magnitude15;
367  }
368  }
369  break;
370  } // else fall through to orginary square without shape modulation
371 
372  case WAVEFORM_SQUARE:
373  magnitude15 = signed_saturate_rshift(magnitude, 16, 1);
374  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
375  if (phasedata[i] & 0x80000000) {
376  *bp++ = -magnitude15;
377  } else {
378  *bp++ = magnitude15;
379  }
380  }
381  break;
382 
383  case WAVEFORM_BANDLIMIT_PULSE:
384  if (shapedata)
385  {
386  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++)
387  {
388  uint32_t width = ((shapedata->data[i] + 0x8000) & 0xFFFF) << 16;
389  int32_t val = band_limit_waveform.generate_pulse (phasedata[i], width, i) ;
390  *bp++ = (int16_t) ((val * magnitude) >> 16) ;
391  }
392  break;
393  } // else fall through to orginary square without shape modulation
394 
395  case WAVEFORM_BANDLIMIT_SQUARE:
396  for (i = 0 ; i < AUDIO_BLOCK_SAMPLES ; i++)
397  {
398  int32_t val = band_limit_waveform.generate_square (phasedata[i], i) ;
399  *bp++ = (int16_t) ((val * magnitude) >> 16) ;
400  }
401  break;
402 
403  case WAVEFORM_SAWTOOTH:
404  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
405  *bp++ = signed_multiply_32x16t(magnitude, phasedata[i]);
406  }
407  break;
408 
409  case WAVEFORM_SAWTOOTH_REVERSE:
410  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
411  *bp++ = signed_multiply_32x16t(0xFFFFFFFFu - magnitude, phasedata[i]);
412  }
413  break;
414 
415  case WAVEFORM_BANDLIMIT_SAWTOOTH:
416  case WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE:
417  for (i = 0 ; i < AUDIO_BLOCK_SAMPLES ; i++)
418  {
419  int16_t val = band_limit_waveform.generate_sawtooth (phasedata[i], i) ;
420  val = (int16_t) ((val * magnitude) >> 16) ;
421  *bp++ = tone_type == WAVEFORM_BANDLIMIT_SAWTOOTH_REVERSE ? (int16_t) -val : (int16_t) +val ;
422  }
423  break;
424 
425  case WAVEFORM_TRIANGLE_VARIABLE:
426  if (shapedata) {
427  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
428  uint32_t width = (shapedata->data[i] + 0x8000) & 0xFFFF;
429  uint32_t rise = 0xFFFFFFFF / width;
430  uint32_t fall = 0xFFFFFFFF / (0xFFFF - width);
431  uint32_t halfwidth = width << 15;
432  uint32_t n;
433  ph = phasedata[i];
434  if (ph < halfwidth) {
435  n = (ph >> 16) * rise;
436  *bp++ = ((n >> 16) * magnitude) >> 16;
437  } else if (ph < 0xFFFFFFFF - halfwidth) {
438  n = 0x7FFFFFFF - (((ph - halfwidth) >> 16) * fall);
439  *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
440  } else {
441  n = ((ph + halfwidth) >> 16) * rise + 0x80000000;
442  *bp++ = (((int32_t)n >> 16) * magnitude) >> 16;
443  }
444  ph += inc;
445  }
446  break;
447  } // else fall through to orginary triangle without shape modulation
448 
449  case WAVEFORM_TRIANGLE:
450  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
451  ph = phasedata[i];
452  uint32_t phtop = ph >> 30;
453  if (phtop == 1 || phtop == 2) {
454  *bp++ = ((0xFFFF - (ph >> 15)) * magnitude) >> 16;
455  } else {
456  *bp++ = (((int32_t)ph >> 15) * magnitude) >> 16;
457  }
458  }
459  break;
460  case WAVEFORM_SAMPLE_HOLD:
461  for (i=0; i < AUDIO_BLOCK_SAMPLES; i++) {
462  ph = phasedata[i];
463  if (ph < priorphase) { // does not work for phase modulation
464  sample = random(magnitude) - (magnitude >> 1);
465  }
466  priorphase = ph;
467  *bp++ = sample;
468  }
469  break;
470  }
471 
472  if (tone_offset) {
473  bp = block->data;
474  end = bp + AUDIO_BLOCK_SAMPLES;
475  do {
476  val1 = *bp;
477  *bp++ = signed_saturate_rshift(val1 + tone_offset, 16, 0);
478  } while (bp < end);
479  }
480  if (shapedata) release(shapedata);
481  transmit(block, 0);
482  release(block);
483 }
static void release(audio_block_t *block)
static audio_block_t * allocate(void)
Definition: AudioStream.cpp:92
audio_block_t * receiveReadOnly(unsigned int index=0)
void transmit(audio_block_t *block, unsigned char index=0)
BandLimitedWaveform band_limit_waveform
uint32_t phasedata[AUDIO_BLOCK_SAMPLES]
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, modulation_factor, modulation_type, phase_accumulator, phase_increment, phasedata, AudioStream::receiveReadOnly(), AudioStream::release(), sample, tone_offset, tone_type, and AudioStream::transmit().

Referenced by erisAudioSynthWaveformModulated::update(), and erisAudioSynthWaveformModulated2k::update().

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