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

Thread: Dynamic Audio Connection Bug? A new one!

  1. #1
    Senior Member
    Join Date
    Dec 2015
    Posts
    183

    Dynamic Audio Connection Bug? A new one!

    Hi all,

    I'm back playing with some dynamic audio connections. The ones I used to allow swapping left/right channels work great, and are in fact working well within this very project. I've tried to add another one and...it's just not working.

    Code:
      pMixLTCANA1_0_ampLTCANAO1_0 = new AudioConnection(mixer_LTC_ANA_1, amp_LTC_AnaOut1_0); // regular LTC 
      pMixLTCANA1_0_ampLTCANAO1_0 -> disconnect();  
    
      pMixAUDANA1_0_ampLTCANAO1_0 = new AudioConnection(mixer_AUD_ANA_1, amp_LTC_AnaOut1_0); // Audio   
      pMixAUDANA1_0_ampLTCANAO1_0 -> disconnect();
    This code should create a patch, disconnect it, then do it again for a different source to the same input on an amp block. It's not working as I'm expecting it to though.

    I expect that at the end of the these 4 lines there should be two dynamic connections that are inactive. What actually happens is the first one (with the LTC comment) is active, even though it's been disconnected. Swapping the order in which these are connected (Audio first, then LTC) results in no change, LTC is still active. Commenting things out for testing shows that both connections work individually, but that nothing seems to disconnect them.

    I'm stumped. I have working dynamic connections in this very project, but these ones aren't working properly at all.

  2. #2
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    228
    Your can try using
    Code:
    delete pMixLTCANA1_0_ampLTCANAO1_0;
    Instead of disconnect
    The delete calls the AudioConnection deconstructor
    Which internally also calls disconnect

  3. #3
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    228
    You can read about using new operator at https://stackoverflow.com/questions/...tructor-called
    They say that when using "new" your should also use the "delete" operator to make sure that everything goes out of scope to avoid memory leaks.
    Otherwise i have no idea, but do really want to know.

  4. #4
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,784
    Maybe you've found a bug in the audio library? Or maybe it's just a mistake or misunderstanding with your code?

    First, please make sure you're using Teensyduino 1.53 or 1.54-beta. In Arduino, click Help > About to check the version.

    If this is a previously unknown audio library bug, I can assure you absolutely no investigation is going to happen unless you provide a small but complete test program which demonstrates the problem. The 4 lines of code you've shown aren't enough. A complete program which can be copied into Arduino and uploaded onto a Teensy to reproduce the problem is required.

    Please, do not just give me a link to a huge project. Create a relatively small test program which just demonstrates the problem.

  5. #5
    Senior Member
    Join Date
    Dec 2015
    Posts
    183
    Quote Originally Posted by manicksan View Post
    Your can try using
    Code:
    delete pMixLTCANA1_0_ampLTCANAO1_0;
    Instead of disconnect
    The delete calls the AudioConnection deconstructor
    Which internally also calls disconnect
    Thanks for the reply! Back when I was looking at this last time, I remember there was a thread that talked of a bug that deleting and recreating connections would eventually crash the system. Naturally I can't find that original thread anymore.

    Nevertheless, I tried using delete and it failed as well.

    Luckily, while trying to find that thread I found my original thread talking about this. I feel like a bit of an idiot, I should have remembered what I had seen in the past. Here's the link: https://forum.pjrc.com/threads/62166...Connection-Bug

    Basically, the issue is that you can't disconnect or delete a dynamic connection when it shares a node with a connection that isn't being disconnected or deleted. In my current case, the output node of mixer_LTC_ANA_1 goes to several places. Since I'm only trying to modify one of them, it just...doesn't seem to do anything. This is consistent with what I was seeing earlier in the year, and something I should have remembered. My apologies.

    Paul - I do still think this is a bug. I will try to come up with a simple test program that demonstrates the issue easily so you can test. I hope the basic description here makes some sense so you can at least start to understand what I'm seeing.

    Thanks!

  6. #6
    Senior Member
    Join Date
    Dec 2015
    Posts
    183
    Ok! I have come up with a test file that appears to show the issue. I don't think I can attach it directly, so here's a link to the .ino:

    https://www.dropbox.com/s/nbu17ni5ni...st_v1.ino?dl=0

    I've set up a simple system with I2S input, output, a mixer, and a sine wave generator.

    There are a few options you can comment/uncomment to test and cause the issue to appear. Surprisingly, I found that things weren't exactly as I thought they were. Start by uncommenting patchcords 1 and 2, just to check your hardware is working. Then comment them out, and you'll hear the left output toggling on and off while the right output is just off. So far this all makes sense. Now the issue:

    Uncomment patchcord 3. This lets the right side of the I2S input into a mixer, which goes into the right side of the I2S output. Suddenly the audio is constant output on both channels. I believe the audio is correctly following the left/right inputs (ie not being combined somehow).

    Comment patchcord 3 and uncomment patchcord 4. This feeds a sine wave into the same input on the mixer. Suddenly the audio is back to toggling. Just beware the sine wave noise especially if you're using headphones.

    So there we go. Please let me know if I can offer any help, further info, or anything that might let other recreate this issue!

  7. #7
    Senior Member
    Join Date
    Dec 2015
    Posts
    183
    Hi all,

    Just curious if anyone has been able to replicate what I'm seeing with these patches.

    Thanks!

  8. #8
    Junior Member
    Join Date
    Dec 2020
    Posts
    3
    jkoffman, did you ever get to the bottom of this? thanks!

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,784
    This bug never made it onto my to-investigate list, probably because the Dropbox link wasn't working. I tried again just now and it's not cooperating with my browser.

    If anyone has a Dropbox account, can you please download this code and post it here on the forum message?

  10. #10
    Junior Member
    Join Date
    Dec 2020
    Posts
    3
    Code:
    #include <Audio.h>      // Include the Teensy Audio Library
    #include <Wire.h>       // Include the Teensy I2C Library 
    #include <Metro.h>      // Include the Metro library for triggering functions based on time
    
    AudioInputI2S            audioIn;           //xy=178,263
    AudioOutputI2S           audioOut;           //xy=539,261
    AudioMixer4              mixer1;         //xy=407,264
    AudioSynthWaveformSine   sine1; 
    
    // Uncomment these to test the system (just a straight passthrough)
    //AudioConnection          patchCord1(audioIn, 0, audioOut, 0);
    //AudioConnection          patchCord2(audioIn, 1, audioOut, 1);
    
    // Uncomment this and audio will be constant
    //AudioConnection          patchCord3(audioIn, 1, mixer1, 1);
    
    // Uncomment this and audio toggles (as expected - but beware the sine noise)
    //AudioConnection          patchCord4(sine1, 0, mixer1, 1);
    
    // Leave this one connected
    AudioConnection          patchCord6(mixer1, 0, audioOut, 1);
    
    // Dynamic patchcord
    AudioConnection*     pANAI0_ANAO0;
    
    AudioControlSGTL5000     sgtl5000_1;     //xy=340,426
    // GUItool: end automatically generated code
    
    
    #define LED_HB  5 // Pin with LED for heartbeat
    
    // Variables
    int LED_HB_State = LOW;     // Var to hold state of heartbeat LED
    
    
    // Instantiate a Metro object
    Metro Int500msMetro = Metro(500);  // Set 500msMetro to return true every half second
    
    
    // Functions Below
    // ---------------
    
    void audio_in_setup()     
    {
      pANAI0_ANAO0 = new AudioConnection(audioIn, 0, audioOut, 0);
    
    // Both of the following options work (depending on the other things connected)
    //  pANAI0_ANAO0 -> disconnect();
    //  delete pANAI0_ANAO0; // -> disconnect();
    }
    
    
    // Ignore this function for now - Not used
    //void audio_in_toggle(void)  
    //{
    //  if(pANAI0_ANAO0)
    //  {    
    //    pANAI0_ANAO0 -> disconnect();
    //    Serial.println("Disconnected");
    //  }
    //  else
    //  {
    //    pANAI0_ANAO0 -> disconnect();    
    //    Serial.println("Connected");
    //  }
    //}
    
    void audio_in_disconnect(void)  
    {
        pANAI0_ANAO0 -> disconnect();
        Serial.println("Disconnected");
    }
    
    void audio_in_connect(void)  
    {
        pANAI0_ANAO0 -> connect();
        Serial.println("Connected");
    }
    
    
    void setup() {
      
      Serial.begin(115200);
      delay(500);
      Serial.printf("Starting setup...\n");
    
    
      AudioMemory(12);  // Audio memory for audio library
    
      sgtl5000_1.enable();  // Enable the audio shield
      sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); // Set the input to line in
      sgtl5000_1.volume(0.5);   // Initial volume level for headphone out
    
      audio_in_setup();
    
      sine1.amplitude(0.25);
      sine1.frequency(500);
      
      Serial.printf("Setup complete.\n");
    
    
    }
    
    void loop() {
     // 500msMetro object - a pseudo half second interrupt
      if (Int500msMetro.check() == 1) // Check if the object has passed its interval
      {
        // Heartbeat LED
        if (LED_HB_State == LOW)
        {
          LED_HB_State = HIGH;
          audio_in_connect();
        }
        else
        {
          LED_HB_State = LOW;
          audio_in_disconnect();
        }
    
        digitalWrite(LED_HB, LED_HB_State);
    
    //    audio_in_toggle();
      }
    
    }
    I copied and pasted that from the DropBox.

    Thank you!!!

  11. #11
    Senior Member wwatson's Avatar
    Join Date
    Aug 2017
    Posts
    374
    @Paul - Here is the file.
    Filename is 'DynamicPatchTest_v1.ino

    Code:
    #include <Audio.h>      // Include the Teensy Audio Library
    #include <Wire.h>       // Include the Teensy I2C Library 
    #include <Metro.h>      // Include the Metro library for triggering functions based on time
    
    AudioInputI2S            audioIn;           //xy=178,263
    AudioOutputI2S           audioOut;           //xy=539,261
    AudioMixer4              mixer1;         //xy=407,264
    AudioSynthWaveformSine   sine1; 
    
    // Uncomment these to test the system (just a straight passthrough)
    //AudioConnection          patchCord1(audioIn, 0, audioOut, 0);
    //AudioConnection          patchCord2(audioIn, 1, audioOut, 1);
    
    // Uncomment this and audio will be constant
    //AudioConnection          patchCord3(audioIn, 1, mixer1, 1);
    
    // Uncomment this and audio toggles (as expected - but beware the sine noise)
    //AudioConnection          patchCord4(sine1, 0, mixer1, 1);
    
    // Leave this one connected
    AudioConnection          patchCord6(mixer1, 0, audioOut, 1);
    
    // Dynamic patchcord
    AudioConnection*     pANAI0_ANAO0;
    
    AudioControlSGTL5000     sgtl5000_1;     //xy=340,426
    // GUItool: end automatically generated code
    
    
    #define LED_HB  5 // Pin with LED for heartbeat
    
    // Variables
    int LED_HB_State = LOW;     // Var to hold state of heartbeat LED
    
    
    // Instantiate a Metro object
    Metro Int500msMetro = Metro(500);  // Set 500msMetro to return true every half second
    
    
    // Functions Below
    // ---------------
    
    void audio_in_setup()     
    {
      pANAI0_ANAO0 = new AudioConnection(audioIn, 0, audioOut, 0);
    
    // Both of the following options work (depending on the other things connected)
    //  pANAI0_ANAO0 -> disconnect();
    //  delete pANAI0_ANAO0; // -> disconnect();
    }
    
    
    // Ignore this function for now - Not used
    //void audio_in_toggle(void)  
    //{
    //  if(pANAI0_ANAO0)
    //  {    
    //    pANAI0_ANAO0 -> disconnect();
    //    Serial.println("Disconnected");
    //  }
    //  else
    //  {
    //    pANAI0_ANAO0 -> disconnect();    
    //    Serial.println("Connected");
    //  }
    //}
    
    void audio_in_disconnect(void)  
    {
        pANAI0_ANAO0 -> disconnect();
        Serial.println("Disconnected");
    }
    
    void audio_in_connect(void)  
    {
        pANAI0_ANAO0 -> connect();
        Serial.println("Connected");
    }
    
    
    void setup() {
      
      Serial.begin(115200);
      delay(500);
      Serial.printf("Starting setup...\n");
    
    
      AudioMemory(12);  // Audio memory for audio library
    
      sgtl5000_1.enable();  // Enable the audio shield
      sgtl5000_1.inputSelect(AUDIO_INPUT_LINEIN); // Set the input to line in
      sgtl5000_1.volume(0.5);   // Initial volume level for headphone out
    
      audio_in_setup();
    
      sine1.amplitude(0.25);
      sine1.frequency(500);
      
      Serial.printf("Setup complete.\n");
    
    
    }
    
    void loop() {
     // 500msMetro object - a pseudo half second interrupt
      if (Int500msMetro.check() == 1) // Check if the object has passed its interval
      {
        // Heartbeat LED
        if (LED_HB_State == LOW)
        {
          LED_HB_State = HIGH;
          audio_in_connect();
        }
        else
        {
          LED_HB_State = LOW;
          audio_in_disconnect();
        }
    
        digitalWrite(LED_HB, LED_HB_State);
    
    //    audio_in_toggle();
      }
    
    }
    EDIT: He beat me to it

  12. #12
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,784
    Thanks. I've put this issue on my list.

  13. #13
    Senior Member
    Join Date
    Dec 2015
    Posts
    183
    Ah I am so sorry Paul! I had no idea the link wasn't working for you!

    I appreciate you looking into this when you have time! Happy to help in any way I can, I'm just not sure what to do.

    Thanks!

  14. #14
    Junior Member
    Join Date
    Dec 2020
    Posts
    3
    fyi, this is behavior related to the subject I've noticed and just tested.
    Code:
     AudioConnection*             patchCords[28];
    Then I have 5 different patch cord arrangements, lets call them A,B,C,D,E.

    I create the first patch cord arrangement, A, like this:

    Code:
    this->patchCords[0] = new AudioConnection(*this->envelope, 0, *this->mixer, 0);
    .. repeat 27 times...
    Then, when I want to switch arrangements, like to arrangement B, I do this:
    Code:
    for (int i = 0; i < 28; i++) {
        delete this->patchCords[i];    
      }
    this->patchCords[0] = new AudioConnection(*this->amplifier, 0, *this->mixer, 0)
    ...repeat 27 times...
    That tends to work fine, except, if I create the array of patch cords out of order. Example, if in arrangement C, I create the patches in this order [2], [5], [0], [1], [22] then I get some odd behavior. Arrangement C will work fine, but, if I switch from arrangement C to arrangement D, D will produces messed up audio, as if the patches are not arranged correctly. If I switch back to C, then back to D again, everything will be fine. It's only screwy the one time.

    Anyway, I'm not asking for anything, just thought I'd share in case it's helpful to anyone else. I'm thinking about not using an array for patch cords and seeing if that makes a difference. But, as long as I keep the array of patch cords created in the same numeric order I have not had any issues.

Posting Permissions

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