Adding sync input to the audio library

Status
Not open for further replies.

john-mike

Well-known member
Hello,
I'm trying to add a sync input to the waveforms of the audio library but am having issues adding a second input.
I've succeeded in making my own effects with two inputs but there's still something I'm not getting about the objects.

Here is my test where the second input does nothing. It's just read if it exists and released.

sketch:
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

// GUItool: begin automatically generated code
AudioSynthWaveform       waveform1;      //xy=240,329
AudioSynthWaveform       waveform2;      //xy=244,396
AudioSynthWaveformSineModulated sine_fm1;       //xy=444,318
AudioMixer4              mixer1;         //xy=496,461
AudioOutputI2S           i2s1;           //xy=653,304
AudioConnection          patchCord1(waveform1, 0, sine_fm1, 0);
AudioConnection          patchCord4(waveform2, 0, sine_fm1, 1);
AudioConnection          patchCord2(sine_fm1, 0, i2s1, 0);
AudioConnection          patchCord3(sine_fm1, 0, i2s1, 1);
// GUItool: end automatically generated code


AudioControlSGTL5000     sgtl5000_1;     //xy=615.7142857142857,619.9999999999999

uint32_t prev3;

void setup() {
  AudioNoInterrupts();

  Serial.begin(9600);
  delay(500);
  Serial.println("start");


  sgtl5000_1.enable();


  sgtl5000_1.volume(.75);


  AudioMemory(50);

  waveform1.begin(1, .5, WAVEFORM_TRIANGLE);
  waveform2.begin(1, 2, WAVEFORM_TRIANGLE);

  sine_fm1.amplitude(1);
  sine_fm1.frequency(220);

  AudioInterrupts();

}

void loop() {


  if (millis() - prev3 > 100 && 1 == 1) {
    prev3 = millis();

    Serial.print(AudioProcessorUsageMax());
    Serial.print("  ");
    Serial.println(AudioMemoryUsageMax());
    AudioProcessorUsageMaxReset();
    AudioMemoryUsageMaxReset();
  }


}

In "synth_sine.h" I changed this line :

Code:
class AudioSynthWaveformSineModulated : public AudioStream
{
public:
	AudioSynthWaveformSineModulated() : AudioStream(2, inputQueueArray), magnitude(16384) {}

And here's what I added in "synth_sine.cpp" :

Code:
void AudioSynthWaveformSineModulated::update(void)
{
  audio_block_t *block, *modinput, *syncinput;
  uint32_t i, ph, inc, index, scale;
  int32_t val1, val2;
  int16_t mod, sync;

  modinput = receiveReadOnly(0);
  syncinput = receiveReadOnly(1);
  // Serial.println("a");    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  ph = phase_accumulator;
  inc = phase_increment;
  block = allocate();
  if (!block) {
    // unable to allocate memory, so we'll send nothing
    if (modinput) {
      // but if we got modulation data, update the phase
      for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
        mod = modinput->data[i];
        ph += inc + (multiply_32x32_rshift32(inc, mod << 16) << 1);
      }
      release(modinput);
    }
    else {
      ph += phase_increment * AUDIO_BLOCK_SAMPLES;
    }
    phase_accumulator = ph;
    return;
  }
  if (modinput) {

 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    if (syncinput) {
      for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
        sync = syncinput->data[i];
      }
      release(syncinput);
    }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
      index = ph >> 24;
      val1 = AudioWaveformSine[index];
      val2 = AudioWaveformSine[index + 1];
      scale = (ph >> 8) & 0xFFFF;
      val2 *= scale;
      val1 *= 0x10000 - scale;
      //block->data[i] = (((val1 + val2) >> 16) * magnitude) >> 16;
      block->data[i] = multiply_32x32_rshift32(val1 + val2, magnitude);
      // -32768 = no phase increment
      // 32767 = double phase increment
      mod = modinput->data[i];
      ph += inc + (multiply_32x32_rshift32(inc, mod << 16) << 1);
      //ph += inc + (((int64_t)inc * (mod << 16)) >> 31);
    }
    release(modinput);
  }

  else {
    ph = phase_accumulator;
    inc = phase_increment;
    for (i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
      index = ph >> 24;
      val1 = AudioWaveformSine[index];
      val2 = AudioWaveformSine[index + 1];
      scale = (ph >> 8) & 0xFFFF;
      val2 *= scale;
      val1 *= 0x10000 - scale;
      block->data[i] = (val1 + val2) >> 16;
      ph += inc;
    }
  }
  phase_accumulator = ph;
  


  transmit(block);
  release(block);
}

When uncommented "Serial.println("a");" will show up once, then it crashes.

Thanks!
 
I'm still having issues with this.

Here's another example.
I have two inputs going into code for the sine wave synth. Neither do anything they just get read and released if they are present.

It crashes if both inputs are connected. It displays the correct data for input 1 but incorrect values for 2 before crashing after 128 values. These values for 2 are always the same no matter what's happening at that input. Here's a little bit of the output:
Code:
c 0 141
c 0 141
c 1 1
c 2 0
c 3 19740
c 4 8191
c 5 0
c 6 0
c 7 19644
c 8 8191
c 9 1792
c 10 38
c 11 19470
c 12 0
c 13 0
c 13 1
c 14 -32344
c 15 0
c 16 144
c 17 144
c 18 1
c 19 0
c 20 19504
c 21 8191

It also crashes if only the first input has something patched to it. It goes to the incorrect part of the code, same as if both inputs are patched and outputs the same values as above.

If only the second input is patched it outputs the sine wave and prints the correct values.

If neither input is patched it goes to the correct part of the code and outputs the sine correctly.



In synth_waveform.h the only line to change is
Code:
  AudioSynthWaveform(void) : AudioStream(2, inputQueueArray) {}


syth_waveform.cpp
Code:
#include "synth_waveform.h"
#include "arm_math.h"
#include "utility/dspinst.h"
#include "arduino.h"

void AudioSynthWaveform::update(void)
{
  audio_block_t *block, *control1, *control2;
  short *bp, *end;
  int32_t val1, val2, val3,c1,c2;
  uint32_t index, index2, scale;
  int16_t mod;


  if (tone_amp == 0) return;

  block = allocate();
  if (block) {
    bp = block->data;

    control1 = receiveReadOnly(0);
    control2 = receiveReadOnly(1);


      if (control1) {
        if (control2) {
         // Serial.println("s1");

          for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {

            c1 = control1->data[i];
            c2 = control2->data[i];

            Serial.print("c ");

            Serial.print(c1);
            Serial.print(" ");

            Serial.println(c2);

            // Calculate interpolated sin
            index = tone_phase >> 23;
            val1 = AudioWaveformSine[index];
            val2 = AudioWaveformSine[index + 1];
            scale = (tone_phase >> 7) & 0xFFFF;
            val2 *= scale;
            val1 *= 0xFFFF - scale;
            val3 = (val1 + val2) >> 16;
            *bp++ = (short)((val3 * tone_amp) >> 15);

            // phase and incr are both unsigned 32-bit fractions
            tone_phase += tone_incr;
            // If tone_phase has overflowed, truncate the top bit
            if (tone_phase & 0x80000000)tone_phase &= 0x7fffffff;
          }
          release(control2);

        }

        else {
          //Serial.println("s2");

          for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {

            c1 = control1->data[i];
            Serial.print("c1 ");
            Serial.println(c1);

            // Calculate interpolated sin
            index = tone_phase >> 23;
            val1 = AudioWaveformSine[index];
            val2 = AudioWaveformSine[index + 1];
            scale = (tone_phase >> 7) & 0xFFFF;
            val2 *= scale;
            val1 *= 0xFFFF - scale;
            val3 = (val1 + val2) >> 16;
            *bp++ = (short)((val3 * tone_amp) >> 15);

            // phase and incr are both unsigned 32-bit fractions
            tone_phase += tone_incr;
            // If tone_phase has overflowed, truncate the top bit
            if (tone_phase & 0x80000000)tone_phase &= 0x7fffffff;
          }
        }

        release(control1);

      }

      else {
        if (control2) {
        //  Serial.println("s3");

          for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {

            c2 = control2->data[i];
            Serial.print("c2 ");
            Serial.println(c2);


            // Calculate interpolated sin
            index = tone_phase >> 23;
            val1 = AudioWaveformSine[index];
            val2 = AudioWaveformSine[index + 1];
            scale = (tone_phase >> 7) & 0xFFFF;
            val2 *= scale;
            val1 *= 0xFFFF - scale;
            val3 = (val1 + val2) >> 16;
            *bp++ = (short)((val3 * tone_amp) >> 15);

            // phase and incr are both unsigned 32-bit fractions
            tone_phase += tone_incr;
            // If tone_phase has overflowed, truncate the top bit
            if (tone_phase & 0x80000000)tone_phase &= 0x7fffffff;
          }
          release(control2);
        }


        else {
         // Serial.println("s4");

          for (int i = 0; i < AUDIO_BLOCK_SAMPLES; i++) {
            // Calculate interpolated sin
            index = tone_phase >> 23;
            val1 = AudioWaveformSine[index];
            val2 = AudioWaveformSine[index + 1];
            scale = (tone_phase >> 7) & 0xFFFF;
            val2 *= scale;
            val1 *= 0xFFFF - scale;
            val3 = (val1 + val2) >> 16;
            *bp++ = (short)((val3 * tone_amp) >> 15);

            // phase and incr are both unsigned 32-bit fractions
            tone_phase += tone_incr;
            // If tone_phase has overflowed, truncate the top bit
            if (tone_phase & 0x80000000)tone_phase &= 0x7fffffff;
          }    
        }
      }

  }

  transmit(block, 0);
  release(block);

}


sketch
Code:
#include <Audio.h>
#include <Wire.h>
#include <SPI.h>
#include <SD.h>
#include <SerialFlash.h>

AudioSynthWaveformSine   sine2;          //xy=45,311
AudioSynthWaveformSine   sine1;          //xy=127,41
AudioSynthWaveform       waveform1;      //xy=307,314
AudioOutputPT8211        pt8211_1;       //xy=858,307

//AudioConnection          patchCord3(sine1, 0, waveform1, 0);
//AudioConnection          patchCord4(sine2, 0, waveform1, 1);

AudioConnection          patchCord1(waveform1, 0, pt8211_1, 0);
AudioConnection          patchCord2(waveform1, 0, pt8211_1, 1);

// GUItool: end automatically generated code

uint32_t cm, prev[4];

#include "wave_tables.h"


void setup() {
  AudioNoInterrupts();
  delay(1000);

  AudioMemory(10);

  sine1.amplitude(1);
  sine1.frequency(.2);

  sine2.amplitude(.1);
  sine2.frequency(.5);

  waveform1.begin(1, 120, WAVEFORM_SINE);


  AudioInterrupts();

  Serial.print(AudioProcessorUsageMax());
  Serial.print(" ");
  Serial.println(AudioMemoryUsageMax());
  
}


void loop() {


   cm = millis();

  if (cm - prev[0] > 200) {
    prev[0] = cm;

    Serial.print(AudioProcessorUsageMax());
    Serial.print(" ");
    Serial.println(AudioMemoryUsageMax());

    Serial.println(" ");

    AudioProcessorUsageMaxReset();
    AudioMemoryUsageMaxReset();
  }

}
 
Ok!
Looks like I didn't look through the .h carefully and see that the array size of inputQueueArray needs to be increased too.

So then then there are two changes to audio_waveform.h
Code:
  AudioSynthWaveform(void) : AudioStream(2, inputQueueArray) {}

//and in the private declarations:
  audio_block_t *inputQueueArray[2];
 
Status
Not open for further replies.
Back
Top