HISE Logo Forum
    • Categories
    • Register
    • Login
    1. HISE
    2. Maarid Ekimmu
    3. Posts
    M
    • Profile
    • Following 0
    • Followers 0
    • Topics 2
    • Posts 14
    • Groups 0

    Posts

    Recent Best Controversial
    • RE: creating a multiband gui

      @DanH then, I will make vst available in an independent application by bringing it to the daw constructor, as soon as I learn c++ 😜

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: creating a multiband gui

      @DanH of course, ignore, just like you do. understand?

      It's a pity all this tripe does not solve the question of why there is no glitch on C++ Juce, but there is on Scriptnode, lasers, piu, piu, piu

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: creating a multiband gui

      @Lindon said in creating a multiband gui:

      If so please feel free to ignore me, and pursue your solution elsewhere.

      Do I understand correctly that the lack of response initiates trolling? Otherwise, why should I ignore anyone when they are diligently trying to help me?
      I sincerely assure you, we can kindly exchange subtleties and barbs for any length of time, moreover, I will be sincerely glad to do so.
      You're not trying to turn the topic of conversation offtop by ignoring common sense, I hope?

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: creating a multiband gui

      @Lindon and?
      I can't make any obvious sense out of your idiomatic sarcasm.

      Maybe you can point a finger at a silly boy, where is the compensation for the volume surge, which is missing in this plugin? :baby_light_skin_tone:

      #include "CrossoverProcessors.hpp"
      
      namespace {
          void processBand(BandState& band, juce::AudioBuffer<float>& buffer) {
              if (band.isMuted) {
                  buffer.clear();
              } else {
                  float* leftSamples {buffer.getWritePointer(0)};
                  float* rightSamples {buffer.getWritePointer(1)};
      
                  // Do the processing
                  if (!band.isBypassed) {
                      for (size_t index {0}; index < buffer.getNumSamples(); index++) {
                          const double mid {(leftSamples[index] + rightSamples[index]) * 0.5};
                          const double side {(rightSamples[index] - leftSamples[index]) * (band.width / 2)};
      
                          leftSamples[index] = mid - side;
                          rightSamples[index] = mid + side;
                      }
                  }
      
                  // Update the envelope
                  for (size_t index {0}; index < buffer.getNumSamples(); index++) {
                      band.env.getNextOutput(leftSamples[index] - rightSamples[index]);
                  }
              }
          }
      }
      
      namespace CrossoverProcessors {
          void prepareToPlay(CrossoverState& state, double sampleRate, int samplesPerBlock) {
              // We don't filter sidechain channels but do copy them to each buffer - so filters may need less channels than the buffers do
              for (juce::dsp::LinkwitzRileyFilter<float>& filter : state.lowpassFilters) {
                  filter.prepare({sampleRate, static_cast<juce::uint32>(samplesPerBlock), static_cast<juce::uint32>(2)});
              }
      
              for (juce::dsp::LinkwitzRileyFilter<float>& filter : state.highpassFilters) {
                  filter.prepare({sampleRate, static_cast<juce::uint32>(samplesPerBlock), static_cast<juce::uint32>(2)});
              }
      
              for (juce::dsp::LinkwitzRileyFilter<float>& filter : state.allpassFilters) {
                  filter.prepare({sampleRate, static_cast<juce::uint32>(samplesPerBlock), static_cast<juce::uint32>(2)});
              }
      
              for (juce::AudioBuffer<float>& buffer : state.buffers) {
                  buffer.setSize(2, samplesPerBlock);
              }
      
              for (BandState& band : state.bands) {
                  band.env.setSampleRate(sampleRate);
              }
      
              state.sampleRate = sampleRate;
              state.samplesPerBlock = samplesPerBlock;
          }
      
          void reset(CrossoverState& state) {
              for (juce::dsp::LinkwitzRileyFilter<float>& filter : state.lowpassFilters) {
                  filter.reset();
              }
      
              for (juce::dsp::LinkwitzRileyFilter<float>& filter : state.highpassFilters) {
                  filter.reset();
              }
      
              for (juce::dsp::LinkwitzRileyFilter<float>& filter : state.allpassFilters) {
                  filter.reset();
              }
      
              for (juce::AudioBuffer<float>& buffer : state.buffers) {
                  buffer.clear();
              }
      
              for (BandState& band : state.bands) {
                  band.env.reset();
              }
          }
      
          void processBlock(CrossoverState& state, juce::AudioBuffer<float>& buffer) {
              const size_t numCrossovers {state.bands.size() - 1};
      
              // First split everything into bands and apply the processing
              for (int crossoverNumber {0}; crossoverNumber < numCrossovers; crossoverNumber++) {
                  // We need to make a copy of the input buffer before processing
                  // lowBuffer will be lowpassed, highBuffer will be highpassed
                  juce::AudioBuffer<float>& lowBuffer = crossoverNumber == 0 ? buffer : state.buffers[crossoverNumber - 1];
                  juce::AudioBuffer<float>& highBuffer = state.buffers[crossoverNumber];
      
                  highBuffer.makeCopyOf(lowBuffer);
      
                  {
                      juce::dsp::AudioBlock<float> block(juce::dsp::AudioBlock<float>(lowBuffer).getSubsetChannelBlock(0, 2));
                      juce::dsp::ProcessContextReplacing context(block);
                      state.lowpassFilters[crossoverNumber].process(context);
      
                      // Crop the internal buffer in case the DAW has provided a buffer smaller than the specified block size in prepareToPlay
                      juce::AudioBuffer<float> lowBufferCropped(lowBuffer.getArrayOfWritePointers(), lowBuffer.getNumChannels(), buffer.getNumSamples());
                      processBand(state.bands[crossoverNumber], lowBufferCropped);
                  }
      
                  {
                      juce::dsp::AudioBlock<float> block(juce::dsp::AudioBlock<float>(highBuffer).getSubsetChannelBlock(0, 2));
                      juce::dsp::ProcessContextReplacing context(block);
                      state.highpassFilters[crossoverNumber].process(context);
      
                      // If this is the last band we need to apply the processing
                      if (crossoverNumber + 1 == numCrossovers) {
                          // Crop the internal buffer in case the DAW has provided a buffer smaller than the specified block size in prepareToPlay
                          juce::AudioBuffer<float> highBufferCropped(highBuffer.getArrayOfWritePointers(), highBuffer.getNumChannels(), buffer.getNumSamples());
                          processBand(state.bands[crossoverNumber + 1], highBufferCropped);
                      }
                  }
              }
      
              // Finally add the bands back together
              if (state.numBandsSoloed > 0 && !state.bands[0].isSoloed) {
                  buffer.clear();
              }
      
              for (int crossoverNumber {0}; crossoverNumber < numCrossovers; crossoverNumber++) {
                  // If there is another crossover after this one, we need to use an allpass to rotate the phase of the lower bands
                  if (crossoverNumber + 1 < numCrossovers) {
                      juce::dsp::AudioBlock<float> block(juce::dsp::AudioBlock<float>(buffer).getSubsetChannelBlock(0, 2));
                      juce::dsp::ProcessContextReplacing context(block);
                      state.allpassFilters[crossoverNumber].process(context);
                  }
      
                  if (state.numBandsSoloed == 0 || state.bands[crossoverNumber + 1].isSoloed) {
                      for (int channelNumber {0}; channelNumber < 2; channelNumber++) {
                          buffer.addFrom(channelNumber, 0, state.buffers[crossoverNumber], channelNumber, 0, buffer.getNumSamples());
                      }
                  }
              }
          }
      }
      
      posted in General Questions
      M
      Maarid Ekimmu
    • RE: creating a multiband gui

      @Straticah

      the link to the source of the Monster plugin is above, the name of the plugin is clickable, you can make sure it works and not find a formula for compensating the edge of each selected channel, although maybe we are blind and you will succeed?
      We also read about Linkwitz Riley, watched the Juce forums, well, it works for an open source person, without problems, miracles

      added
      the only thing that comes to my mind is to contact the developer directly, explain this situation and ask for the formula, if it exists. It will be very funny if he answers the same way the programmer answered me - there is no formula, there is nothing to compensate :beaming_face_with_smiling_eyes:

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: creating a multiband gui

      @Straticah said

      Hi, I'm offended to remind you, in the hope that Christophe will look this way. The multiband filter is broken in Hise, I could not understand the reason, I will try to consult other programmers working with Juce.
      When two segments approach each other, a parasitic burst of the signal appears. This is exactly why Christophe hung a divider on each band of the signal in his examples. Which, as it is not difficult to understand, is effective only in the static position of the segments. Trying to make them manageable, you inevitably get a parasitic spike at the output, the distance of information is unacceptable - depending on the frequency, the higher, the correspondingly greater the distance you need to block.

      1.png

      2.png

      @Christoph-Hart My friend and I recently tried to disassemble the Monster plugin trying to determine the presence of an exponential formula by which the channel could be muted, neither I nor a familiar C++ programmer found it, unfortunately. I will try to contact jd13 directly, it is surprisingly quite responsive, perhaps it will tell you why LinkwitzRaily in C++ does not give a parasitic splash, but in the script it does. Which is very strange in itself.

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: Two filters in a row, how to compensate for the signal

      no one is interested in my opinion, but I will add.
      The doctor plugin restricts hise, neither the creation nor the loading of script fx work.
      Thank God, there is BERTOM AUDIO EQ Curve Analyzer, which allows you to freely test the linear-phase result during the assembly process.
      Interestingly, logically, if you embed signal tests as modules into the hise itself, you will get a lego constructor with a professional bias? :face_with_monocle:

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: Two filters in a row, how to compensate for the signal

      @Christoph-Hart A giant thank you, it worked, although it was confusing that the main signal meter did not show signs of a working state, but as soon as I opened the effects tab, everything fell into place. What would we do without you?
      I understand that you can simply specify this in the hi_core module settings by deleting the line from the preprocessor
      JucePlugin_PreferredChannelConfigurations={0,2}?
      Thank you @d-healey πŸ‘
      And enabling the "DON'T CREATE FOLDER" parameters in the same place will disable the creation of folders in the user's profile, making the plugin offline and without presets, right?

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: Two filters in a row, how to compensate for the signal

      @Christoph-Hart I don't really hope for an answer, but what if you take pity?
      Christoph, can you tell me where to fix or what to add in the source code of hise so that the assembled plugin passes sound through itself? I set up channels and studio as an effect in projucer, but hise remains immune to sound.
      It would just make it possible to test the build of the project directly in the plugin doctor, saving me from guessing and re-building

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: Two filters in a row, how to compensate for the signal

      111.png

      Guys, I compiled only the template, it's better, but with a heavy load on the editor, there is still almost no compensation.
      I have definitely met examples of separation in linear-phase mode written in juce, I wish I could in c++, in hise it is impossible to divide linearly-phase? Or is there some other secret that I can't find as a blind man?

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: Two filters in a row, how to compensate for the signal

      @d-healey best! i'm stupid, I would never have guessed to open the examples in the examples section myself. Thanks a lot πŸ‘

      posted in General Questions
      M
      Maarid Ekimmu
    • RE: Two filters in a row, how to compensate for the signal

      @Christoph-Hart
      Templates in the documentation? https://docs.hise.audio/scriptnode/list/template/freq_split3.html
      Other than that, the rest of the pages are not visible to me.
      I honestly try to search before asking, Allpass I met with you, you mentioned in the examples to several people, but even there I could not understand the structure of the construction.
      Sorry, I read and answer with the help of auto-translation, there may be inaccuracies

      posted in General Questions
      M
      Maarid Ekimmu
    • Two filters in a row, how to compensate for the signal

      And the closer they are to each other, the stronger the signal will be in this place. Linkwitz Riley gives a similar effect, more often in reducing making dips.
      1.png
      2.png
      3.png
      4.png
      Please help, am I doing something wrong or just don't know how to compensate?

      posted in General Questions
      M
      Maarid Ekimmu
    • Frequency separation, mid\side, routing, one knob controls multiple knobs, Scriptfx

      Hello, nice to meet you, I'm a beginner, in every possible sense. In the process of learning the possibilities of Hise, I first of all encountered a strong disunity and disorganization of information about the possibilities of the program. Although in fact, I spent only three days to understand my mistakes or find answers to my questions - how?, what?, why?, and when?
      I am sharing with you the result of my training, in fact, it turned out to be a kind of collection of disparate information about the possibilities and method of signal switching, interface control, demonstration of analyzers, as the simplest and most obvious techniques.
      Undoubtedly, I am well aware that my obvious conclusions seem to be meaningless to advanced users. But believe me, as a person who spent three days searching on this forum without having any knowledge or experience behind me, I have the feeling that I have come a giant way.

      HiseSnippet 3652.3oc6c07bbaaEGqjfjk7GwNtIG5oczzCJs1Z3mK41LsYk0G1pwxdqVEGmoSiC0RHIFykbKIWKuIim3C4P5zK4ZN0buW5L8Tm1C4V9Wn+Yj+CRA.IWBRQx8CKYuxFJGxR7vC3weuG.d3GvttomaajuuqGnxh60uKBT4RvV8cBNZ8iLrb.auAsft1VAsrLQdfa0uqguOxDToxr2lTiJKNGf92O8A2xv1voMJoH.3AtVsQ20piUPRoMa7gV11aYXh1ypCSsUZrcaWm0csc6gslYgBftFserwgn6YPp1LPPk42zzJv0qUfQ.xGTYta4Z1u0QtG6DV+GX4asuMh7fHnEtgBKdKWaShESJEr9QV1lMieq8A3VoYBFLaHF7Kf6XYZMn7Dr3pTAUSzfEOpLSZya1TlmHq4IvXd4XRUXLo4BMoqAa01ypaPhDh8bQ31NAHuCLvvNqoDVWvLObA35t3Z3DrZGiGi1xC+v.MVQWP3FUUDDdu2eokvPueP0mX3UsqmaW+p+tpe4RUqt7s5cvAHu6hbNL3nk+sUEEjTtAo7O1xwz8XhogKc4aYi8TcLbpdGCOOK+koUYCTaq8Q16Z3bHoR+IbYUqdSQAgUEtA8y3Of+++YZk+HeTSjwiw5XzGW4CLr8QwBhZnVsMrIMTfWuPQexsM5zwfXUgs3xwZKrZs5z+z0EzpKnIF2R208PCOqfi5X0dKOzeYsmhs0vFbomkBCL6JfQ.5.gUODErgkeWai9gfQKb7IF7VdMKmkwHGqRXcvZdBMVgfvlcW0GErqkyggEhcjcQdAVH+UnHdllRZ38uaufrFfH0BjJxBDGpIvzZgwPa8PQVKYSrdsCVY4PgUwRSaBwJIUpRR4qjboJImuRJkpjR9JoVpRpDkVxxw1xAU8fdNsCrbcp557gNt6KQFO44ZuRa2NcccvirtAtks6gduk9RZT8.Xif0qED3Yseu.zJIESh7DiU58SoiT95HkUmmUn4INplWockT9lmb95HO5lm7nZdk1UEXdJ4qixnadJip4UZWUf4oluNp4YdwSZiiNWO1TVYYZ72xuGochLz0Mrs2GO26JoCNwsRwsfXYsf3nzBxk0BxiRKnTVKnjzBL9m64FftuyJDOwhK8rkplUzAGjqrn1xFOGXdhIof3Ulhq3zqy9HOl3.ZEwqKmdwdXwK1ylKR6PHgohtNa6XEb+tHmhxPADgi3DCVLxpvUMflVvUhRKnkMM8LK7p+K.oNR.0fGjdUiupAXjUVJixf8FCkkyn727uFCkUxnb2ebLTVMqYGgcijx0dQTV6EQY8WDkqmixez1aXDXPxiLJxIYgdbYafdBNo7vrJWDtAx+wAtcwIXNXHJnxEB6zKG0oa2AmENsOu.j9YQvSY6v9rObrkYvQIE7WabDx5viXx+ueCa21ONNg7CrriRv+WB+xl6d++vlqu2i1592ciM28Y500quZWmCIvw.a6JAQonGMApsqQ.Nil8vsC0DuLbMGC699Hupa6vZm+pFL141MRame12bB67SZDgdgP0aAWqmokabiC1+v3sprHTVVUUQQFXEf5DW5kfJRZ5h0UETkXDHQpuhhlbcIE.0MU4WCooZOXH+1ljbpIoWRyacaGSzSwkHszy.AnmFvtCIVjD4XfmvwLdSEiNhckDD698BdECY5J0j0zpqTDjkEABgveS9PHIC4SfgiDlc8gN8JCLEjFl7C5aS2H8cb8r9BLfXXC5XYZZiZ55aQVdYPse9eCWaT2VVeQ7H3u+69t+8GzgYi0+fWiNFIcVi+dCebx6V3Rfvp24KxLdqwmmiSoiqIhrWQRhF8PNs6CLQGXzyN3AYWhnmO5ivaraGCG7nbuPLJiiPTTTWQWjwYdInnpTcUIIAU0L9SwZRZx0Tzqg8m9Ms6cnkSSCO7v8f3VmEzu5PWVp3Xyw.zazJEhhA3xPzOyOGDMW7CuJY43Gw7jDzEjEvQx5iBvJUCu+UrJJRz.exDvznuzAqu8PWQN4s8aedYioetwHE9vFehCHYQyG9exFQS4FJMBWfi4+9Ox0MlKXiypX3fsnflrNd++Jrn5Eg0qqIUSTslVQtfwAbUX.2e5qm3fxe+OlKtwhzXnkEo+7+WowsfOcxmI.m00PCNuHTUUPTnthb8TnNtbLlqJnKpBxyCwhsWZnqLcaWGKW7zEdU0EXG8qv.zM51Xnu5e5K1JSKB0qqnomcPKNTRRRSTUTtVAKLc6bWX51VNhoWXJj.qsvaTw83O106w9cMZihIBCun03fZuECpoJvBaO+foDXSSrtlXMg5iMrIc1AaWMMrwhaM5Msfa3zfvIEqoNt3l7YGtcMFbSTJCv8USKiSEqUWDWawwE3TN6.t2lA3B4qlA499udZIjSRDWcAAswE4Tmbj6pCci9ErTvOb3vApsazMwVoGu0.trSkXCn4OvtbKnYzpmuK7dtdcLrwqTa1D40FawjsGWv55jUSiy3ca5Nn2oE8fyBymCBuq6wEkFRZ+SrWKwStDN+ZMMrCRcrPuZEshvngdmMXTAtDoRQuEIn2M2A+p8xEA0JZsgoPDTdHweu7QO8hVfXJD8TJE8Vhfd27NXK7kLDV3JESgPnZoP37vSK36jmY9Ug63Z1y1HH8Q3S58HAjWA1yMmb13N3Ws9r6A6T6b8GUS7ZvlVAsOJeablbrQ.3LwFitMDWFFdBoIF3bvsd3YzUe3cX5eXX+uz.9IocNDtlUZuVz4hmZqyeaildnmXgNNhn6nhuZiJyNxlpX4H0tt8H4ysiQfGYS3uy850I7r4w.kiCxlbpPUVhPle3yBjmIFQKjiI8geF+WjPQxyUhDJlQnT7yDgRYDJyJTNiPEVgJYDpxJTMivZrBqkQnFqPsLB0YEpmQXcVgCdHmntEgD7EgCzBGRDg1UCgawzgeSQ9zYRDdRe5rIB49zr9TooVe5bk4SgbeZw9T4oVe57k4SWf6SK1mpL05SuPY9zE49zh8opSs9zKUlO8xug5SmKNy33aQV7M0NgJqbtNvU9FXxMbpqGBuuLzdtMsM5uhuQmt1ncwt6aTcexIjSxl9jWKpn83cKRMVocjKbRt8TyySBe5K.av8LCbOTvwDNZI2gnnOCpr.IF6sfa32cvWH.rmB44SIBXAnvp3+CrFgfWBUFVQ6cEG+QKqoqc+tG45X0lTTXMh8Rq0wsGg2ivzmuig+dFV1jM61pmeWrMdemV3JS+xEfmcpx8nLTL+VFswwP8aZP363ZPxcqCuCUj2psGrS0rlaxnB5NQwQbCtOB9gQaj1NldgvHEro1gxJC4qfvrD4zu1.gFAjzKKAccPOpqKNhMkM81vCrrIM8pCjm1.FVmQPIazSiuNWaE1ZIeDPnCvD8TxVxuoHXS7fMSSjYHy73V.v71gALl6dwb6X4DcnuPhmCriwSiddAnL4R5G8ELH4nhWqWfaG7303uJELsFLo0tNt0v5S9STrtjPco5Ls80g0WUmdVG0D0UkEjzjAsdL53PXibXIBqJUSQSTSWTSVnlpndMpgLK7OBXrWsTcOyKyBXbPO0qy7PZAjFYdJ2OfTu2E7ZjETfPQ7yYMUYAQAxKa855J00DDivrVcbcCNBOsTbW8tjVSH7PdpqoUSQWRUWZL66AWOfvmCeg1gDE9B7BkSitHbynqEUppBXtEg..Sz+Egc7eDNBgTRpv+qC8Bmcd0jJLVw+yvF9lW+OOo+W.1omcfEnvoCBEe5MzeFlW94gGRBoR02WD22dnUoBl722JyluiDGgKKkIBmVP9AHzH9RF5NewgHW.JJPmIHokIA8hBQCuUpiGhWSbhGULOTJa.Ki0bAX3WVnTwrio0bcn5pJRRRZBZZJ5JhxB0ixTZWjOJ5VujYzSAQ4KPczhuL8zQ9U1YluI2Se13oS4Opv5OBekBOzBxYzmZjXMkLiDoEj0+jwoPuW1NHZtxz4SRdLZxExAkDMyRS1COIxICxUg3Hzb0nzIuMQCYx6nJbZM4cJvdlrf8fSHZrPZ51FBkQLtrXbkBfrv0FRAYrNaPViaAZBQhfgm9Ttl1bP8Q01XRpLi4kjRVJXk90Fk7TeRZgzX+s8e.QZaC6XC.mf8j70C.LzikAGnQB9F14x7Oy+bY.7yk4bOmCRbNGJI.KFayM.KVXtAXyDE8ka.1rQBeygyAoyWbNHcJtwCHmyANmCSabNH9pgyg3nawyMg+o1CurP1cfIEsCLF2MIjmOhfyBGmENNKbbV33rvwYgiyB2YDKbyddgEt4FOV3Nq3cKWCRBLRo3MvjIe6LGMihMe2yMrAJctkMPNYMuvrAJyYC7LI.axoadtnnubCvfQBOuwFn74K1.k4rAlKcAEtVIm9CNgfuAPH3f3c1g.ZbFA4LBxYDjyHHmmHNifbFA4LBxYDbLXD7zk.tSIVAKKOuAHH8WerWi4ET9MPdAesl1lwgWPENufSYAXSNwyyGE8ka.1BQBe0vKnx4KdAU37BlCoAksZImEDNwfuQPLnV1g.KBkT4LCxYFjyLHmYPNeQblA4LCxYFjyL3XvL3oMIbmZbCVRpdCf0veh8eMlcPEN6fudQdy3vNnJmcvWaBvlb5muPTzWtAXKFIb7XG7JonaaZmbvLVK+Wsr73FrjUK4DgvIGjSDBmHDNQHbhP3DgvIBg+SWVADgT1gKkm8Md7Obd7mvLUN8Cuds6P9OE97+4Mn1TqO8UwO0ffDC5j9zJIBmt8oZbe5ox3TlngS5SYhFdY3S049zWwy8xDMbReJU5HjF0ZX3l+uPeudsjKGKO8vxNFs8beT6vyZhrsmKPKAGG6f2jDYRxcHOWUD7D1s82wxz5QsaGQaNHecjl.cjm.cTl.cTm.cpMA5nMA5nWpN6feLhJDxVbwEzbyvyqnRLiy3o4.+e.feJ8Y.
      

      And so, in order to avoid delays, load and complex scripting, I had to organize routing by the main chain of effects, not scriptfx. Through many constructions, it was found out that the final routing of the output signal from the main circuit to the output works exclusively in channel 1 and 2, even if you connect all the channels to the output, the assembled plugin will only sound the 1.2 output. As you can see in the example, I had to collect back all the channels in 1.2 precisely because of this, if everything is connected, but not 1.2, the plugin will be silent, although in the editor itself it voices any connected channel to the output, which for example confused me a lot, I for example could not do it anywhere to find out and similar questions were unanswered.
      Managing multiple knobs with a single knob, the only clear example can be found very deeply, from the developer himself, and the example was, as far as I understood, completely different. A very very simple command, understandable to anyone who has ever programmed at all, but without an example, it is impossible to assemble it yourself or understand the logic of building a team, there is simply no documentation.
      I'm sorry I'm complaining, I understand. I would like, if it is not difficult for anyone from the readers, to express my opinion about the presented example. A person is not inherently an ideal being, I would be very happy to hear an opinion on how in reality this example can be simplified, performed in a more convenient way and possibly correct existing errors related to my obvious inexperience and ignorance of the material.
      I will be eternally grateful to you for your participation!

      posted in Presets / Scripts / Ideas
      M
      Maarid Ekimmu