Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 3 FirstFirst 1 2 3
Results 51 to 65 of 65

Thread: Audio System Design Tool++ update

  1. #51
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    Hi,
    * You define the array like this:
    Name:  arrayOfVoices.png
Views: 348
Size:  2.0 KB

    * static class member's value?

    * I have now included a option that is found in the rename class(tab/workspace) dialog.
    (it's opened by double clicking the tab)
    Click image for larger version. 

Name:	Rename_tab_workspace_sheet.png 
Views:	41 
Size:	12.8 KB 
ID:	24782

    I have also created a field to add extra class declarations when having inheritance.

    There is also a new object called destructor code @ special category
    this makes it possible to add additional destructor code

    * When a project is given a specific name @ settings - arduino - project name
    (and then applied/saved)
    all unique saved projects are available at the main menu (top right) - projects

    note. all projects are stored in the browser indexedDB which will be deleted when clearing the browser cache

    When exporting as a zip this zip can then be imported again (it will look for the GUI_TOOL.json inside that zip, and use that)

    * I have created a example that should mostly reassemble your example
    "On the use of a base class, consider the following:"

    Code:
    {"version":1,"settings":{"arduino":{"IOcheckAtExport":false,"Board":{"Platform":"","Board":"","Options":""}},"BiDirDataWebSocketBridge":{},"workspaces":{},"sidebar":{},"palette":{},"editor":{},"devTest":{},"IndexedDBfiles":{"testFileNames":"testFile.txt"},"NodeDefGenerator":{},"NodeDefManager":{},"NodeHelpManager":{}},"workspaces":[{"type":"tab","id":"Main","label":"SynthVoice","inputs":0,"outputs":0,"export":true,"isMain":false,"mainNameType":"tabName","mainNameExt":".ino","generateCppDestructor":false,"extraClassDeclarations":"","settings":{},"nodes":[{"id":"SynthVoice_code1","type":"Function","name":"code","comment":"private:\r\n  AudioConnection outputCord;\r\n  virtual AudioStream& getOutputStream(void) = 0;\r\npublic:\r\n  virtual ~SynthVoice(){};\r\n  virtual void noteOn(float freq, float vel, int chan=-1) = 0;\r\n  virtual void noteOn(int MIDInote, int MIDIvel, int chan=-1) = 0;\r\n  virtual void noteOff(void) = 0;\r\n  virtual bool isPlaying(void) = 0;\r\n  int connect(AudioStream& str) { return connect(str,0);}","x":140,"y":65,"z":"Main","bgColor":"#DDFFBB","wires":[]}]},{"type":"tab","id":"f061342f.9b8268","label":"WaveAndEnvVoice","inputs":0,"outputs":0,"export":true,"isMain":false,"mainNameType":"tabName","mainNameExt":".ino","generateCppDestructor":true,"extraClassDeclarations":"final : public SynthVoice","settings":{},"nodes":[{"id":"WaveAndEnvVoice_includeDef1","type":"IncludeDef","name":"\"SynthVoice.h\"","comment":"","x":240,"y":70,"z":"f061342f.9b8268","bgColor":"#DDFFBB","wires":[]},{"id":"WaveAndEnvVoice_waveform1","type":"AudioSynthWaveform","name":"wave","comment":"","x":245,"y":130,"z":"f061342f.9b8268","bgColor":"#E6E0F8","wires":[["WaveAndEnvVoice_exp env1:0"]]},{"id":"WaveAndEnvVoice_code1","type":"Function","name":"code1","comment":"private:\n  bool isNew;\n  \n  static short wave_type[4];\n  AudioStream& getOutputStream(void) {AudioStream& result {amp}; return result;};\n\npublic:  \nvoid noteOn(int MIDInote, int MIDIvel, int chan=-1){}; // don't support this\nvoid noteOn(float freq, float vel, int chan=-1)\n{\n    // ... do some stuff\n}\nvoid noteOff(void){env.noteOff();};\nbool isPlaying(void) {return env.isActive();};\n    ","x":255,"y":210,"z":"f061342f.9b8268","bgColor":"#DDFFBB","wires":[]},{"id":"WaveAndEnvVoice_constructor code1","type":"ConstructorCode","name":"constructor code","comment":"env.attack(129.2);\n// .. etc.\n\nwave_type[] = {\n    WAVEFORM_PULSE,\n    WAVEFORM_SQUARE,\n    WAVEFORM_SAWTOOTH,\n    WAVEFORM_TRIANGLE\n};","x":226,"y":274,"z":"f061342f.9b8268","bgColor":"#DDFFBB","wires":[]},{"id":"WaveAndEnvVoice_exp env1","type":"AudioEffectExpEnvelope","name":"env","comment":"","x":345,"y":130,"z":"f061342f.9b8268","bgColor":"#E6E0F8","wires":[["WaveAndEnvVoice_amp1:0"]]},{"id":"WaveAndEnvVoice_amp1","type":"AudioAmplifier","name":"amp","comment":"","x":450,"y":130,"z":"f061342f.9b8268","bgColor":"#E6E0F8","wires":[["WaveAndEnvVoice_Out1:0"]]},{"id":"WaveAndEnvVoice_Out1","type":"TabOutput","name":"Out","comment":"","x":575,"y":130,"z":"f061342f.9b8268","bgColor":"#cce6ff","wires":[]}]},{"type":"tab","id":"a6317b06.79ff28","label":"SomeOtherTopologyVoice","inputs":0,"outputs":0,"export":true,"isMain":false,"mainNameType":"tabName","mainNameExt":".ino","generateCppDestructor":true,"extraClassDeclarations":"final : public SynthVoice","settings":{},"nodes":[{"id":"SomeOtherTopologyVoice_includeDef1","type":"IncludeDef","name":"\"SynthVoice.h\"","comment":"","x":210,"y":75,"z":"a6317b06.79ff28","bgColor":"#DDFFBB","wires":[]}]},{"type":"tab","id":"32dd68c9.e73c58","label":"Main","inputs":0,"outputs":0,"export":true,"isMain":true,"mainNameType":"projectName","mainNameExt":".ino","generateCppDestructor":false,"extraClassDeclarations":"","settings":{},"nodes":[{"id":"Main_includeDef1","type":"IncludeDef","name":"\"SynthVoice.h\"","comment":"","x":190,"y":125,"z":"32dd68c9.e73c58","bgColor":"#DDFFBB","wires":[]},{"id":"Main_includeDef2","type":"IncludeDef","name":"\"WaveAndEnvVoice.h\"","comment":"","x":180,"y":165,"z":"32dd68c9.e73c58","bgColor":"#DDFFBB","wires":[]},{"id":"Main_includeDef3","type":"IncludeDef","name":"\"SomeOtherTopologyVoice.h\"","comment":"","x":170,"y":203,"z":"32dd68c9.e73c58","bgColor":"#DDFFBB","wires":[]},{"id":"Main_code1","type":"Function","name":"code2","comment":"\r\n\r\n#define POLYPHONY 12\r\nSynthVoice* voices[POLYPHONY] = {NULL};\r\n\r\nmakerFunction(void)\r\n{\r\n   voices[0] = new SomeOtherTopologyVoice;\r\n   voices[1] = new WaveAndEnvVoice;\r\n}\r\n\r\n\r\nvoid breakerFunction(int v)\r\n{\r\n  if (NULL != voices[v])\r\n  {\r\n    delete voices[v];\r\n    voices[v] = NULL;\r\n  }\r\n}\r\n\r\nvoid setup() {\r\n    \r\n}\r\n\r\nvoid loop() {\r\n    \r\n}","x":160,"y":275,"z":"32dd68c9.e73c58","bgColor":"#DDFFBB","wires":[]}]},{"type":"tab","id":"f8aa3d4.01479c","label":"ArrayOfVoicesExample","inputs":0,"outputs":0,"export":true,"isMain":false,"mainNameType":"main","mainNameExt":".ino","generateCppDestructor":true,"extraClassDeclarations":"","settings":{},"nodes":[{"id":"SynthExample_WaveAndEnvVoice1","type":"WaveAndEnvVoice","name":"waev[8]","x":261,"y":180,"z":"f8aa3d4.01479c","bgColor":"#CCFFCC","wires":[["SynthExample_mixer1:0"]]},{"id":"SynthExample_mixer1","type":"AudioMixer","name":"mixer","inputs":"1","comment":"","x":430,"y":180,"z":"f8aa3d4.01479c","bgColor":"#E6E0F8","wires":[[]]}]}],"nodeAddons":{"expEnvelope":{"isAddon":true,"label":"exp envelope","description":"","credits":"","homepage":"","url":"https://api.github.com/repos/[user]/[repository]/contents/[subpath if any]","types":{"AudioEffectExpEnvelope":{"defaults":{"name":{"value":"WaveAndEnvVoice_exp env1"},"comment":{},"color":{"value":"#E6E0F8"}},"shortName":"exp env","inputs":1,"outputs":1,"inputTypes":{"0":"i16"},"outputTypes":{"0":"i16"},"category":"effect","help":"","color":"#E6E0F8","icon":"arrow-in.png"}}}}
    }
    } is at new line to make coping easier don't forget to include it

  2. #52
    Senior Member
    Join Date
    Apr 2021
    Location
    Cambridgeshire, UK
    Posts
    253
    That's great, I think it'll be really helpful - thanks. It's so useful to have the demo JSON easy to load, makes everything very clear.

    One thing I've been struggling with (hence the delayed response) is the proper definition of static class members. I don't think your way of initialising it in the constructor is valid syntax, or "correct" C++: as I understand it static class members are common to all instantiations of a class, and rarely changed. An example is AudioStream::first_update, which is the one and only pointer to the first AudioStream object to be updated on the 2.9ms update interrupt; every AudioStream object has its own next_update which refers to the next one to update, until they're all done. In statically-defined Teensy audio systems first_update is set early in the run-time and never changed: in my dynamic version, it does get changed, but only if a new object is logically the one which should get updated first .

    However, I did find a way of doing what I want to. Here's a code object:
    Code:
    // Start of voice class manually-entered code
        void noteOn(int MIDInote, int MIDIvel, int chan=-1){};
        void noteOn(float freq, float vel, int chan=-1)
        {
          if (isNew)
            wave.begin(vel,freq,(chan<0)?WAVEFORM_SINE:(wave_type[chan&3]));
          else
          {
            wave.amplitude(vel);
            wave.frequency(freq);
          }
          env.noteOn();
          isNew = false;
        }
    
        void noteOff(void){env.noteOff();};
        bool isPlaying(void) {return env.isActive();};
    }; // terminates class
    
    static short WaveformVoice::wave_type[] = {
        WAVEFORM_SINE,
        WAVEFORM_SQUARE,
        WAVEFORM_SAWTOOTH,
        WAVEFORM_TRIANGLE // no closing brace, GUI tool puts it in
    // End of voice class manually-entered code
    You'll see I put in my own class terminator, and then defined the static class member without a closing brace, as your tool will put it in for me. It's a bit of a hack, but works OK.

  3. #53
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    Hi,

    I have now included a new node object called
    "eof code" available at the special category
    (so that no workaround is needed).

    with that you can define code that should be "outside" the class
    (the code is placed at the end of the file and after the class declaration)

    here is the json that you can import (pretty simple but I include it anyway)
    (don't forget to uncheck the replace flow checkbox)
    Code:
    [{"id":"WaveAndEnvVoice_constructor code1","type":"ConstructorCode","name":"constructor code","comment":"env.attack(129.2);\n// .. etc.","x":226,"y":274,"z":"f061342f.9b8268","bgColor":"#DDFFBB","wires":[]},{"id":"WaveAndEnvVoice_eof code1","type":"EndOfFileCode","name":"eof code","comment":"static short WaveAndEnvVoice::wave_type[] = {\n    WAVEFORM_PULSE,\n    WAVEFORM_SQUARE,\n    WAVEFORM_SAWTOOTH,\n    WAVEFORM_TRIANGLE\n};","x":251,"y":320,"z":"f061342f.9b8268","bgColor":"#DDFFBB","wires":[]}
    ]

    There is more demo examples at the "main menu" - Examples

    My own project is called "Manicken Poly Synth"
    which is a complete and working project,
    only need to download the huge wavetable instruments separately.


    /Jannik

  4. #54
    Junior Member
    Join Date
    Jun 2021
    Posts
    3
    It's fantastic works!, need informaiton about how to install it locally, i'm trying to clone from repository https://github.com/manicken/manicken.github.io, no error but seems all sidebar is blank white and unfinished loading.

  5. #55
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    Fixed now, it was a small bug.

    It was occurring when the Tool was loaded the very first time, a workaround was to refresh the page.

    But now it should(of what I have been testing) be working the very first time as well, i.e. after clearing browser cache.

    A tip for all who use this tool is to open the browser dev-tools to view the javascript console-log, when errors like this occur,
    and post the log contents in a zip,
    it can be faster for me to pinpoint specific errors.

  6. #56
    Junior Member
    Join Date
    Jun 2021
    Posts
    3
    Quote Originally Posted by manicksan View Post
    Fixed now, it was a small bug.

    It was occurring when the Tool was loaded the very first time, a workaround was to refresh the page.

    But now it should(of what I have been testing) be working the very first time as well, i.e. after clearing browser cache.

    A tip for all who use this tool is to open the browser dev-tools to view the javascript console-log, when errors like this occur,
    and post the log contents in a zip,
    it can be faster for me to pinpoint specific errors.
    I think's its working now, the problem persist when i'm using a 'private mode' browser, the suspect is IndexedDB process seems not working in private mode browser, but the original Audio System Design Tool code is working on both in normal and private mode browser, its will be great if your mod can also working in 'private mode' browser, thanks for this fantastic mods.
    Attached Files Attached Files
    Last edited by sttel; 07-30-2021 at 05:44 PM. Reason: Typo

  7. #57
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    Ok now it works in "private mode" as well

    But when using "private mode" the indexedDB functionality is not available,

    which means that the following functionalities are not available:

    * multiple project saving/loading (using browser storage)
    * loading and use node addons help

  8. #58
    Quote Originally Posted by wrightflyer View Post
    This is a work of pure genius - rather curiously Paul Stoffregen posted on Twitter over Christmas saying he should look at doing a "multi voice" audio tool and when I tweeted back about this (your older version) he wasn't aware of it but really this should become the main audio design tool that everyone uses.
    @wrightflyer What exactly would it mean to have a multi-voice audio tool? I know a lot of folks have built poly synths using the current library, myself included, that could be considered multi-voice. I'm really curious what the implications would be.

    Also, @manicksan, this is so cool! Thanks so much for sharing it. I'm excited to try it out.

  9. #59
    Junior Member
    Join Date
    Jun 2021
    Posts
    3
    Quote Originally Posted by manicksan View Post
    Ok now it works in "private mode" as well

    But when using "private mode" the indexedDB functionality is not available,

    which means that the following functionalities are not available:

    * multiple project saving/loading (using browser storage)
    * loading and use node addons help
    Ok ok, it's an excellent input for me as a beginner web programmer, still thinking the possibilities or feature to use external DB from your code to enable the IndexedDB funtion such as Redis or other tools... once more im really appreciate with your excellent works...., thanks in advance.

  10. #60
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    To answer "What exactly would it mean to have a multi-voice audio tool?"

    Also it's just more than a multi-voice audio tool now:

    * allow for complex designs to be separated into "tabs" (actually classes)
    * by using the "c++ template mixer" a array of voices can have any size without need to stack several mixers.
    * the whole design can be created directly in the tool by using code objects
    * by using a "java program" the synth can be controlled in the tool using special ui-objects (just like pure data but easier)
    this "java program" is just a web server + websocket server which makes it possible for the tool to talk to midi devices.

    * the code export contains all audio connections for the connections between "tabs"
    manually edit is not needed

    * in the export items are sorted by column
    1 4 7
    2 5 8
    3 6 9

    * plus more improvements


    Better to just describe how it's done:

    first it starts with an empty project:
    Click image for larger version. 

Name:	EmptyProject.png 
Views:	30 
Size:	12.3 KB 
ID:	25489

    to first create the voice class
    here you rename it by double click the main-tab

    second you can add and second tab by clicking the top right '+' sign
    this new tab is renamed the same way

    third switch to the Voice class
    and edit the design

    note. the input and output objects they are found in the special category

    Click image for larger version. 

Name:	VoiceClass.png 
Views:	41 
Size:	30.5 KB 
ID:	25490

    the input and output objects are just placeholders do define the inputs/outputs
    for the Voice class.

    last create the synth class
    Click image for larger version. 

Name:	SynthClass.png 
Views:	39 
Size:	15.8 KB 
ID:	25491

    the new Voice class is found in the "tabs" category

    here I'm using the "template mixer" but for designs using only 4 voices the standard mixer can be used
    then only connect the voices[4] output to the first mixer input, the tool takes care of the rest.

    This is the most basic design of what I can think of.

    Then in your main "sketch" the whole Synth can be initialized by using

    Code:
    Synth synth;

  11. #61
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    Quote Originally Posted by sttel View Post
    Ok ok, it's an excellent input for me as a beginner web programmer, still thinking the possibilities or feature to use external DB from your code to enable the IndexedDB funtion such as Redis or other tools... once more im really appreciate with your excellent works...., thanks in advance.
    I have created plugins to both Arduino IDE and VSCODE that make it possible to save/load the design by using a sketch/project stored JSON file

  12. #62
    Quote Originally Posted by manicksan View Post
    To answer "What exactly would it mean to have a multi-voice audio tool?"

    Also it's just more than a multi-voice audio tool now:

    * allow for complex designs to be separated into "tabs" (actually classes)
    * by using the "c++ template mixer" a array of voices can have any size without need to stack several mixers.
    * the whole design can be created directly in the tool by using code objects
    * by using a "java program" the synth can be controlled in the tool using special ui-objects (just like pure data but easier)
    this "java program" is just a web server + websocket server which makes it possible for the tool to talk to midi devices.
    * the code export contains all audio connections for the connections between "tabs"
    manually edit is not needed
    Wow. So you wouldn't have to repeat the code for each voice?! This sounds awesome. Looking forward to trying this out when I get home.

  13. #63
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    Update for the Node Definitions Manager Manual (i.e. adding new custom AudioObjects to the tool)

    open node def. mgr.
    Click image for larger version. 

Name:	NewType0.png 
Views:	3 
Size:	25.7 KB 
ID:	27038

    click add group
    Name:  NewType1.png
Views: 82
Size:  7.3 KB

    fill in the details
    (note there is a popup text for each of the fields describing what it is)
    Click image for larger version. 

Name:	NewType2.png 
Views:	4 
Size:	14.6 KB 
ID:	27033

    then select the new group (here I choose the UID newGroup in the prev step)
    Name:  NewType3.png
Views: 84
Size:  10.1 KB

    click add new node type
    Name:  NewType4.png
Views: 84
Size:  10.4 KB

    here the TypeName is your custom AudioObject class name
    (example AudioMixer4 is the class name for the mixer4 object)

    Specially check and change (if needed) the following json variables
    shortName, inputs, outputs,
    inputTypes and outputTypes should be removed if not used
    also note that inputs and outputs have no use if inputTypes and outputTypes are defined
    as the inputs and outputs are set from inputTypes and outputTypes if available

    if you still want to use the iotypes the syntax for inputTypes and outputTypes
    is:
    Code:
    "inputTypes": {
            "x4": "i16"
        },
    here it means there are 4 inputs
    Click image for larger version. 

Name:	NewType5.png 
Views:	2 
Size:	23.3 KB 
ID:	27036

    then you have the new AudioObject to play with
    Click image for larger version. 

Name:	NewType6.png 
Views:	6 
Size:	38.0 KB 
ID:	27037

    note you can always change the node def. afterwards
    just select the type
    make the changes and press Apply

  14. #64
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    Some updates:

    * Fixed my "Flexible" AudioMixer object (just called mixer in the mixer category)
    Now it autogenerates mixer code for every mixer variant that you use.
    that is included at the top of the generated code in both "flat" simple and class exports,
    when exporting as zip two files are generated mixers.cpp and mixers.h

    + supported at simple export
    ("flat" exports right now generates multiline code but I plan to do some one liner compact code of it)

    + don't generate code for the 4 input variant that already exists in the Audio Lib


    * Simple export can now handle arrays (only support standard Library Audio objects)

    so the following design can now be exported
    Click image for larger version. 

Name:	SimpleExportArray.png 
Views:	5 
Size:	19.4 KB 
ID:	27089

    here the junctions are only to make the design easier to follow
    and the group box is to clarify what belongs to the "voice"

    also note that I have used the "Flexible" mixer both in the voice and as the "external" main mixer.
    To use the mixer with a array the "autosize" only works if the mixer have one input.
    Also note that the maximum allowed inputs of the mixer is 255
    so if a "sourcing" array is bigger than that it will truncate at 255.
    So if you want to do a 1000 mega drone
    https://www.youtube.com/watch?v=c3wk9WWTfNs
    you have to do it like this:
    Click image for larger version. 

Name:	1000megadrone.png 
Views:	3 
Size:	9.5 KB 
ID:	27088

    note. this is however only intended for simple designs

    for bigger complex designs I recommend to use "class based export to zip"
    which will separate all the parts of the design into multiple files
    and thus make it much easier to read and maintain.

    There is also a ongoing development to make it possible for live edit and update of the design
    using OSC (Open Sound Control) transport layer.
    https://forum.pjrc.com/threads/68798...Implementation

    Documentation will be posted when that is in a more stable state
    right now I'm struggling with "class" based designs.

    * Fix code autocomplete to also scan and use Variables object nodes/blocks
    note. it will not include "globally" variables declared inside Function code objects

  15. #65
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    508
    There are some new improvements to the tool:

    * Now it only do a IO check when there is any audio objects
    also now the IO check dialog is just a warning,
    so that you can still export if you choose so.

    (the IO check setting is still there for some very rare situations)

    * Also I have make it possible to export files into a subfolder in the zip file
    There is a setting to enable that
    @ settings-arduino-"Zip file subfolder"

    the name is firstly taken from the main tab if set
    then if there is no main tab it uses the name from:
    settings-arduino-projectname

    this functionality is useful when anyone want to export complete Arduino sketches.

    * On Node-RED there is a neat feature, but caused some problems on this tool
    When a link is drawn from a object output to another object you don't actually have
    to drop the link on a port, instead you can just drop it anywhere on the 'target' node
    this did make it possible (still on the official tool, so you can try it there)
    to connect multiple signals to the first input of any object.
    this above also make it possible to drop a 'input' (when a link is drawn from a input)
    to objects not having any IO (that means all control objects)

    the all above problems are now fixed in my tool
    * you can't drop any link to any object not having any IO
    * now when a 'output' (when a link is drawn from a output)
    link is drawn it can just be dropped to a object and it will automatically add itself to the first free input
    This "auto add" feature can be turned off in settings-"Workspace/view"-Nodes-"Auto append dropped links"
    if you find it annoying

    note. the opposite is not yet possible i.e. adding a 'input'-link automatically to outputs of any node

    here is how I drop a new link to a mixer

    Click image for larger version. 

Name:	AutoAddDroppedLinks.png 
Views:	2 
Size:	6.3 KB 
ID:	27169

    note. if the second input was free (not connected to)
    then the new link would be connected to that instead of the last input

    here is a diagram showing how it could look like before
    Click image for larger version. 

Name:	AutoAddDroppedLinks_bug.png 
Views:	1 
Size:	15.8 KB 
ID:	27170

Posting Permissions

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