Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 3 of 3

Thread: Adding sync input to the audio library

  1. #1
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin, TX
    Posts
    101

    Adding sync input to the audio library

    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!

  2. #2
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin, TX
    Posts
    101
    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();
      }
    
    }

  3. #3
    Senior Member
    Join Date
    Mar 2013
    Location
    Austin, TX
    Posts
    101
    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];

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •