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

Thread: Audio System Design Tool++ update

  1. #51
    Senior Member manicksan's Avatar
    Join Date
    Jun 2020
    Location
    Sweden
    Posts
    314
    Hi,
    * You define the array like this:
    Name:  arrayOfVoices.png
Views: 250
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:	32 
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
    141
    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
    314
    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
    314
    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
    314
    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
    314
    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:	23 
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:	30 
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:	26 
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
    314
    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.

Posting Permissions

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