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

Thread: Dynamic Audio Connections

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

    Dynamic Audio Connections

    Hi all,

    Since my mixer object is a bit stalled for the moment, I'm looking to try out dynamically changeable connections to accomplish some of what I was going for. I know this is possible, I'm just not finding a ton of examples online, and I want to make sure I'm not going about this the wrong way.

    I saw an example from an old forum post that defines connections at the start like this:

    Code:
    AudioConnection * DynamicPatchCord1;
    Then in the setup the connection is created like this:
    Code:
    DynamicPatchCord1 = new AudioConnection(*input1, 0, *mixer1, 0);
    then connects and disconnects them like this:

    Code:
    DynamicPatchCord1->connect();
    DynamicPatchCord1->disconnect();
    I have some questions (I know you're shocked). First off, can I define the connection initially like the gui does (in this case AudioConnection DynamicPatchCord1(input1, 0, mixer, 0), then connect/disconnect as needed? Or is it better to leave the definition of what the connection is to the code so it can be modified while the program runs?

    I saw on another post a passing reference to .connect() and .disconnect(), but I haven't seen it used. Does anyone have any code that shows this method in use?

    Thank you!

  2. #2
    Senior Member
    Join Date
    Mar 2019
    Location
    Hoboken, New Jersey, USA
    Posts
    101
    I just do "new AudioConnection(...), like you show. You don't have to call ->connect(). If you don't need it, just "delete". It disconnects.
    Having them "pre-made" is a pain, as you need to give each a new name.

    I just have an std::list of connections, add all of them to connect things, then delete them when done and make new ones.
    Then you don't have to keep track of them and they don't use memory if not connected.

    In the header:
    std::list<AudioConnection*> _cords;

    In CPP file:
    void AudioBoard::setupMixers() {
    // Connect 4 input mixers to 2 output mixers
    _cords.push_back(new AudioConnection(_mixer1, 0, _outMixer1, 0));
    _cords.push_back(new AudioConnection(_mixer1, 0, _outMixer2, 0));
    _cords.push_back(new AudioConnection(_mixer2, 0, _outMixer1, 1));
    _cords.push_back(new AudioConnection(_mixer2, 0, _outMixer2, 1));
    _cords.push_back(new AudioConnection(_mixer3, 0, _outMixer1, 2));
    _cords.push_back(new AudioConnection(_mixer3, 0, _outMixer2, 2));
    _cords.push_back(new AudioConnection(_mixer4, 0, _outMixer1, 3));
    _cords.push_back(new AudioConnection(_mixer4, 0, _outMixer2, 3));

    // 2 (stereo) output mixers go to the audio output
    _cords.push_back(new AudioConnection(_outMixer1, 0, _audioOutput, 0));
    _cords.push_back(new AudioConnection(_outMixer2, 0, _audioOutput, 1));
    }

    To disconnect:
    for(auto cord : _cords)
    delete cord;
    _cords.clear();

    Then you can connect what you need again.

  3. #3
    Senior Member
    Join Date
    Dec 2015
    Posts
    103
    Hi Andy, thank you for the reply!

    I understand what you're doing on a basic level, but I'm not that experienced with c++ so I'll need to study it a bit further.

    In my case, I want to basically be able to select between one of two outputs connected to the input of another block. Do you think it would be better to create two connections (but disconnect them) so I can just connect/disconnect, or completely disconnect and reassign each time? Or does disconnect break the relationship anyway and I'd have to reassign each time?

    Thank you!

  4. #4
    Senior Member
    Join Date
    Mar 2019
    Location
    Hoboken, New Jersey, USA
    Posts
    101
    Any way will work.
    You define the connecting points when you create the connection and can only connect/disconnect later. You cannot change the points of an existing connection.
    If you delete/create a new connection each time, like in my example, you can define new points and connect.

    Spend a couple of hours on C++ basics, like constructor/destructor and new/delete, and it all will be clear.
    You'll need it anyway.

    You can do the same in .ino file, just define the "std::list<AudioConnection*> _cords;" at the top and add "#include <list>" before that.

  5. #5
    Senior Member
    Join Date
    Feb 2017
    Posts
    397
    Quote Originally Posted by jkoffman View Post
    In my case, I want to basically be able to select between one of two outputs connected to the input of another block.
    You seem to be trying to solve a non-existent problem. Why don't you just use a Mixer block? That's what it's for.

  6. #6
    Senior Member
    Join Date
    Dec 2015
    Posts
    103
    Quote Originally Posted by Andy Belov View Post
    Any way will work.
    You define the connecting points when you create the connection and can only connect/disconnect later. You cannot change the points of an existing connection.
    If you delete/create a new connection each time, like in my example, you can define new points and connect.
    Interesting. I will do some experiments to see if I am allowed to have two connections that technically conflict, but aren't both active at the same time.


    Spend a couple of hours on C++ basics, like constructor/destructor and new/delete, and it all will be clear.
    You'll need it anyway.

    You can do the same in .ino file, just define the "std::list<AudioConnection*> _cords;" at the top and add "#include <list>" before that.
    That's my plan. I do have a bit extra time now....

    Thank you!

  7. #7
    Senior Member
    Join Date
    Dec 2015
    Posts
    103
    Quote Originally Posted by gfvalvo View Post
    You seem to be trying to solve a non-existent problem. Why don't you just use a Mixer block? That's what it's for.
    In my attempt to simplify what I'm doing, I haven't fully explained the issue. The better analogy would be that I'm making a phase reverse. So it's two sources, and two destinations. sometimes I want 1-1 and 2-2, and sometimes it will be 1-2 and 2-1.

    To do this with mixers will use two mixers for each input, and in my case that would mean like 10-12 mixers. I had been trying to make a mixer with 2 outputs so that I could eventually make a 2x2 audio router, but I haven't been able to get it to work without glitching. I'll keep plugging away at that, but for the moment I'm pretty stuck.

    I think reconfiguring the connections between my blocks is a good alternative solution. I'm going to do some experiments today and see what I can do!

  8. #8
    Junior Member
    Join Date
    May 2020
    Posts
    3
    Hi, long time listener, first time poster. I've been having success with the type of code proposed above, but cannot do something similar with dynamic AudioStream instances. After deleting the connections, if I attempt to delete the streams, I get a variety of symptoms (audio dropping from a single channel, crashing) which prevent me from moving forward with my project. Looking at the core code, it appears that AudioStream instances are entered into a list:

    Code:
    			// add to a simple list, for update_all
    			// TODO: replace with a proper data flow analysis in update_all
    			if (first_update == NULL) {
    				first_update = this;
    			} else {
    				AudioStream *p;
    				for (p=first_update; p->next_update; p = p->next_update) ;
    				p->next_update = this;
    			}
    and never removed. Presumably this is what is causing the effects I'm seeing, but I'm new to the core code and might be making some bad assumptions.

    Is there some reason why it would be unsafe to remove AudioStream instances from that list if they are deleted? The utter lack of a destructor for the class seems conspicuous, but it's not obvious to me. Potential race condition with audio interrupt code? Although presumably creating new AudioStream objects would have the same potential race condition. Anyway, please let me know if any of that sounds familiar... and thanks a lot!

  9. #9
    Senior Member
    Join Date
    Mar 2019
    Location
    Hoboken, New Jersey, USA
    Posts
    101
    My answer in two words: forget it.

    I've spent maybe a week trying to create/delete effects and connections between them dynamically and gave up. It works for 2 or 3 times, then the poor little thing (Teensy) pretends it's not there.
    Memory leaks, stray pointers? Who cares. It just doesn't work.

    Just yesterday I started to move it all back to static connections with connect/disconnect thing. Still working on it.
    So, if you need to create and connect things (effects and connections) only once, you can use "new" for anything.
    If you try to delete/new it more than twice - you are on your own.

    To be honest, we get spoiled here. We think it it takes C++ syntax, it's as good as Linux. It's not.
    Please prove me wrong.

    Still, (I stand up and drink to that) Teensy is the best thing on this infected planet.
    Can't wait for the 4.1

  10. #10
    Junior Member
    Join Date
    May 2020
    Posts
    3
    Quote Originally Posted by Andy Belov View Post
    My answer in two words: forget it.

    I've spent maybe a week trying to create/delete effects and connections between them dynamically and gave up. It works for 2 or 3 times, then the poor little thing (Teensy) pretends it's not there.
    Memory leaks, stray pointers? Who cares. It just doesn't work.

    Just yesterday I started to move it all back to static connections with connect/disconnect thing. Still working on it.
    So, if you need to create and connect things (effects and connections) only once, you can use "new" for anything.
    If you try to delete/new it more than twice - you are on your own.

    To be honest, we get spoiled here. We think it it takes C++ syntax, it's as good as Linux. It's not.
    Please prove me wrong.

    Still, (I stand up and drink to that) Teensy is the best thing on this infected planet.
    Can't wait for the 4.1
    Hi,

    Just to clarify, did you try modifying the core library AudioStream code at all in your investigations? That's where I'm going next before I admit defeat.

    Thanks!

  11. #11
    Senior Member
    Join Date
    Mar 2019
    Location
    Hoboken, New Jersey, USA
    Posts
    101
    @sockmonkey
    Didn't touch the library and not going to.
    I just need to get by to make my guitar and keyboard effects thingy to work and start making it.
    Maybe later I'll take a look at the whole audio library and see how it works.

    If you find something there we can fix, please share.

  12. #12
    Junior Member
    Join Date
    May 2020
    Posts
    3
    Quote Originally Posted by Andy Belov View Post
    @sockmonkey
    Didn't touch the library and not going to.
    I just need to get by to make my guitar and keyboard effects thingy to work and start making it.
    Maybe later I'll take a look at the whole audio library and see how it works.

    If you find something there we can fix, please share.
    Got it, thanks for the clarification. I'll let you know how my experiments work out.

Posting Permissions

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