home.social

#lfo — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #lfo, aggregated by home.social.

  1. Filtre by Cloudy Samples 🎛️
    16-mode contour filter, 3 LFOs, custom shapes, resizable GUI, preset system

    💻 Win/Mac (VST3/AU)
    🎁 FREE 🔗 cloudysamples.com/products/#fi

    More freeware 👉 linktr.ee/legalvst

    #freeplugin #filterplugin #modulation #lfo #resizablegui #cloudysamples #vst #audioplug

  2. Filtre by Cloudy Samples 🎛️
    16-mode contour filter, 3 LFOs, custom shapes, resizable GUI, preset system

    💻 Win/Mac (VST3/AU)
    🎁 FREE 🔗 cloudysamples.com/products/#fi

    More freeware 👉 linktr.ee/legalvst

    #freeplugin #filterplugin #modulation #lfo #resizablegui #cloudysamples #vst #audioplug

  3. Filtre by Cloudy Samples 🎛️
    16-mode contour filter, 3 LFOs, custom shapes, resizable GUI, preset system

    💻 Win/Mac (VST3/AU)
    🎁 FREE 🔗 cloudysamples.com/products/#fi

    More freeware 👉 linktr.ee/legalvst

    #freeplugin #filterplugin #modulation #lfo #resizablegui #cloudysamples #vst #audioplug

  4. Filtre by Cloudy Samples 🎛️
    16-mode contour filter, 3 LFOs, custom shapes, resizable GUI, preset system

    💻 Win/Mac (VST3/AU)
    🎁 FREE 🔗 cloudysamples.com/products/#fi

    More freeware 👉 linktr.ee/legalvst

    #freeplugin #filterplugin #modulation #lfo #resizablegui #cloudysamples #vst #audioplug

  5. Filtre by Cloudy Samples 🎛️
    16-mode contour filter, 3 LFOs, custom shapes, resizable GUI, preset system

    💻 Win/Mac (VST3/AU)
    🎁 FREE 🔗 cloudysamples.com/products/#fi

    More freeware 👉 linktr.ee/legalvst

    #freeplugin #filterplugin #modulation #lfo #resizablegui #cloudysamples #vst #audioplug

  6. Lees tip -> Mogelijk drugslab en explosieven gevonden na klap in Anna Paulowna | Politie ontdekt mogelijk drugslab en explosieven na ontploffing in Anna Paulowna. Verdachte (43) aangehouden | #AnnaPaulowna #GRIP1 #LFO #EOD #politie #Charlottaring #Drugslab #explosieven |

    hbpmedia.nl/mogelijk-drugslab-

  7. ✨ 💖💕🌹💐💖 💙💜💖🦋🌺💜🎼 🎶 🎸 Now playing

    1. Last Ninja, Palace Gardens - Ben Daglish Anthony Lees 🛍️ 🌑 🔔 48kHZ mp4a Digital version 🎹  📚 📖  🎻🎻 🎼 🎶 ✨ 💖💕🌹💐💖 💙💜💖🦋

    Digital Signal Path

    • VLC on Linux Computer
    • Digitizer (UMC22)
    • Instrument Mixer (16 channel)
    • Mixing Console Yamaha
    • Aux0 send Effect rack unit0 channel 0
    • Aux1 send Effect rack unit0 channel 1
    • Aux 0 return Master Bus channel 0
    • Aux 1 return Master Bus channel 1
    • Master faders
    • XLR output 0 1
    • Headphone Amps 0 1 (4 channel x 2)
    • 1/4" output 0 1
    • Digitizer input 0 1
    • DAW

    #NowPlaying #Music   #Last #Ninja #SID #Arpeggio #LFO #LegacyMusic #Music #Jazz #Digital

    youtube.com/watch?v=_0STbNAxRv

  8. Microrack – First Impressions

    When I first heard about the Microrack concept, I was still playing around with my own Educational DIY Synth Thing so naturally I was really interested in seeing what it would be about. That was back-end of 2024. It has taken until now to realise that from the original Kickstarter.

    Now that I have one in my possession, are are a few notes about it as I start to play.

    What Arrived

    I ordered the Synth Starter Kit and an additional Subtractive Extra Kit. This has given me the following modules:

    • 1x USB-C power module
    • 1x 3.5mm speaker/output module
    • 2x VCO/LFO
    • 2x High/Low pass VCF
    • 2x AD EG
    • 1x Noise + S/H
    • 1x Clock Counter
    • 1x Lo-Fi Delay
    • 1x Stylus Keyboard
    • 1x 830 point solderless breadboard
    • 1x pack of “premium” jumper leads

    One immediate surprise was that there was only one breadboard and now additional means to power it. The description of the Subtractive Extra Kit in the actual pledge was as follows:

    So I was expecting two breadboards and an additional set of jumper wires and whatever a “power extender” was. I’ve pinged them a message just to check I’m not missing anything.

    But in reality, as these are standard breadboards and wires, the extender is as simple as connecting the power rails together between two breadboards. In fact that isn’t even necessary if the power module is placed in the middle across both boards, as shown in my photo above. So I just added another 830 point breadboard myself and got started.

    First Use

    Before the first use, I took their advice and “primed” the solderless breadboard. I soldered up a quick “jumper pin pusher” as shown below to push into each of the power rail pin holes to ensure the modules can be inserted easily.

    My first attempt used a USB power hub and USB-C lead. The first visual impressions are great – the LEDs lighting up through the PCBs look really good and make for very pleasing visual feedback on what is going on.

    Everything worked fine to start with, when there was just an oscillator and output. But when adding the filter and second oscillator as a LFO, I soon found that certain combinations would cause a power-out. It turns out it is really easy to overload a typical USB power pack once there are a few modules running.

    I switched to a Raspberry Pi 4 USB-C power supply, which is rated at 5.1V / 3.0A. This works really well and I’ve not had any power issues since even with all modules powered up.

    It is curious that the system only uses the four power rails of the breadboard. This introduces a few limitations:

    • Modules can’t be placed absolutely anywhere – the breadboards have gaps where there are no pin holes so you have to place modules accordingly.
    • Modules have to be placed to span the middle gap, as that has no continuity in the tracks, otherwise some jumper wires are required.
    • The rails are not symmetrical – they provide +5V, -5V, +12V and GND so it is important to know which is which!

    The idea, as I understand it, is to allow prototyping of additional circuits on the breadboard itself. But for most cases, the centre blocks of pin holes are ignored.

    A basic oscillator – filter – output synth chain is easily put together and can be continuous driven or driven via CV from the stylus keyboard.

    And this was where I hit the first hints of the limitations of the choice of provided modules.

    Module Selection

    The more I think about it, the more the choice of modules for the Synth Starter Kit seems a little odd.

    When adding in the stylus keyboard, it has a GATE and CV output. CV to the oscillator is obvious. And naturally the GATE would probably be expected to go to an envelope generator.

    But there is no VCA! I have a Lo-Fi delay module and an audio output module, but no other means, as far as I can see, of applying an envelope to an amplitude.

    The clock module is also a bit of a mystery. First of all, it isn’t actually a clock but takes a clock input and uses to drive 8 GATE outputs, so to my mind that makes it a clock-driven gate sequencer. But there is nothing to generate a clock directly and I have nothing to trigger off 8 GATE outputs.

    Similarly I’m struggling at this stage to know what to do with the noise + S/H module. With no EG-driven VCA the noise outputs make little sense, and I’m not quite sure how to drive the S/H module.

    Enlightenment Dawns…

    At this point I took a proper look at the two provided “cheat sheets” that came with the system and things start to make a little more sense.

    There is a “Bass and Drum” patch that shows how to use the LFO as the clock with a reset after four steps, triggering the EG on step one and noise via the S/H on all four steps. The EG is driving the filter and you get a pretty quirky noisy pulse with a nice “pew” on every fourth step.

    I’m not entirely sure what “Jacuzzi + The Drone” was all about – that just seemed quite a few farty noises that I couldn’t get to do anything interesting (to me). I might have to give this another go later.

    “ARP Lead” shows how to use the EG as a clock source and the GATE sequencer to drive a pitch level on certain steps of the clock. It also shows how the stylus can be used to set the base pitch for the sequence.

    I’ve also played with using the clock module as a frequency divider to get a sub-octave.

    At this point, we can see how creative use of the modules starts to show how the components can come together for something interesting.

    Good Points

    The modules do seem very full-featured. The oscillator for example, has VCO and LFO modes, with three output waveforms and the option for FM. It also has an option for -5V to +5V or 0 to +5V to support full audio output or use as a CV for other modules. I’m not entirely sure I understand at this stage what all the LEDs are telling me, but I guess I’ll figure that out.

    There are some nice conventions too: blue headers for inputs, red for outputs, for example. And it is obvious some modules are designed for plugging next to each other.

    The use of jumper wires makes for very easy integration with other things, so I’m looking forward to seeing how I can hook it up to my Volca Modular and my Educational DIY Synth Thing.

    The modules are fully open sourced and documented online here: https://github.com/microrack/modules

    The PCB design is very neat and tidy and seems quite a master of minaturisation.

    The electrical specification is pretty complete with lots of features designed for robust protection when using with other devices. All provided modules have protections for shorts, reverse polarity, over and under voltage, and so on. The mechanical specification is also fully published. All details here: https://specs.microrack.org/

    In short, once you get stuck in, everything seems very well thought out.

    Conclusion

    My initial hope was for use in an educational setting, but I’m not sure the bare PCB approach would be up to that. I don’t know if there would be ESD issues, but I do think that repeatedly plugging in and out of the breadboard would eventually take its toll on the power pins. Also, I think it would be far too easy to get the power connections either shorted or mixed up, especially if creating prototype additional circuits.

    As a functioning synth for my own messing about, I’m going to have to invest in a couple more modules I think. I will need at least one mixer/VCA, and probably one of the headers-to-jacks modules too. On the main site, it still lists modules as for pre-order – I suspect that is because the Kickstarter units are still on their way to backers.

    I wasn’t originally interested in MIDI to CV or the microcontroller DIY board, as I figured those would be fairly easy to do myself. And whilst that is still the case, I’m still wondering about their addition to create more of a stand-alone setup to play with.

    It is interesting to note that there is a Eurorack mounting kit, but it is quite expensive, so I’m not sure I’m too fussed about that myself. But I might attempt to knock up some kind of 3D printed frame for housing a couple of modules. In fact, some users in the Microrack forums have done exactly that.

    On balance, this is a very well thought out kit in general terms, but I think the choice of initial modules has veered towards the “beat box” rather than actual synth, but that is perhaps just my preference. But the three sample patches, and some of the ideas starting to appear in the forums, do show the potential of even what I already have.

    At this stage, I’m looking forward to some proper playing around and I plan to digest some of the design information to see what I can do with the DIY side of the kit too.

    I haven’t talked about the audio of course. It is pretty Lo-Fi, which fits right in for me of course.

    There are already a number of videos up online from people far more knowledgeable than me, showing it in action. So I’ll leave it to those to show what it can do audio wise.

    Like many systems, I think this will reward any time spent getting to know it and what the modules can do.

    Kevin

    #envelopeGenerator #gate #lfo #microrack #vcf #vco
  9. Lees tip -> Drugslab in aanbouw ontdekt in Voorhout: vijf aanhoudingen | Drugslab in aanbouw ontdekt in Voorhout; politie doet drie instappen en arresteert vijf verdachten. Buurtbewoners krijgen advies over signalen en melden van verdachte situaties. | #aanhoudingen #criminaliteit #Drugslab #Leiden #LFO #politie #veiligheid #Voorhout |

    hbpmedia.nl/drugslab-voorhout-

  10. I've been having an LFO* morning and for some reason am going through their albums in reverse order; I listened to Sheath first, then decided to play Advance, which I'm just coming to the end of, and, well, I might as well put on Frequencies next! 😁

    *that's LFO as in the English techno group, not those 'Lyte Funky Ones'.

    #NowPlaying #LFO #ElectronicMusic #Techno #GezVarley #MarkBell

  11. I see #PolygonWindow is being re-issued. If you don't already know it is #AphexTwin's second LP, following on from Selected Ambient Works 85-92. The production is absolutely #WarpRecords in the early 90s and could easily be #LFO in places. Today it doesn't sound as abrasive and weird as it did when it was released. I recommend you stream it rather than buy it unless you must, but maybe buy something new and give your money to a new artist instead of a millionaire.

    youtube.com/watch?v=O7kPl57pXHw

  12. More #diysynth stuff. Last year, I started experimenting with #analog synthesizers and built VCO, LFO, VCA, mixer, step sequencer, 1V/oct keyboard. A month ago, I had a dream about a #synthesizer that I wanted to build. Here are the first two modules for this project: a #mixer and a #LFO. There will be more coming soon. I'm calling it "Stack Synth".
    Again, manufactured by @aislerhq
    #soldering #electronics #pcb #StackSynth

  13. my #AppleMusicReplay2024 (or “apparently I fell asleep with a Big Band playlist on, even though I never listen to Big Band”) I love to see #AceMo at number one artist, and #Sansibar too. No surprise #LFO are in there, #KenIshii too.

  14. In the first part I described the concept and basic design parameters I was looking for and then in Part 2 I looked at the detailed electronic design for a board based on the ESP32 WROOM module I have. In this part I go into detail about the code.

    • Part 1 – This introduction and high-level design principles.
    • Part 2 – Detailed design of an ESP32 based PCB.
    • Part 3 – Software design.
    • Part 4 – Mechanical assembly and final use – todo.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    The ESP32 EduMod Hacked Synth Thing

    As mentioned in the last part, the principles and code I’m using are taken from these previous posts:

    I also now have a built PCB design to make development and testing a lot easier.

    Recall the following design choices:

    • The two ESP32 DACs are the output for two envelope generators, each driven by four pots (in standard ADSR configuration), a trigger and a gate signal.
    • There are ESP32 PWM outputs for two VCOs, each with four waveforms (sine, triangle, saw, square) and an analog input (pot or CV) for frequency and amplitude.
    • ESP32 PWM outputs are also used for a LFO with rate and depth analog controls.
    • The ESP32 UART is used for MIDI in.
    • ESP32 digital IO is used for the envelope GATE and TRIGGER signals, although they are level inverted, i.e. they should be read as active LOW.

    Othe points to note:

    • There are three “native” analog inputs used for the two VCO pitch and amplitude CVs. All other pots are read via a CD4067 16-way multiplexer.
    • Software will determine how the VCO CVs interact with the potentiometers.
    • The UART RX pin will be used for MIDI and the UART TX pin will be used for one of the PWM outputs, so there will be no serial port (via USB) for diagnostic output.
    • The ESP32 is a dual core microprocessor, so the aim is to split the functionality across the two cores.

    High Level Design

    The tasks will be split as follows:

    • Core 0:
      • Runs the PWM timer at 32,768Hz (although the sample rate will be half this – more on that later).
      • Manages the PWM outputs for the two VCOs and the LFO.
    • Core 1:
      • Runs the EG timer for the DAC at 10,000 Hz.
      • Handles the reading of all the IO: “real” analog values; multiplexed analog values; digital IO.
      • Handles MIDI.

    Multicore ESP32 Arduino

    Multicore support for the ESP32 on Arduino is provided using FreeRTOS tasks. For a FreeRTOS application, the default Arduino setup()/loop() will run on core 1. However, once tasks have been created to run on the second core, the default loop is no longer used (I believe).

    FreeRTOS enables multitasking on a single CPU (core), each with its own internal priority relative to other tasks. But I’m only using it to start a single task on each core. This is achieved using the xTaskCreatePinnedToCore() function. The last parameter specifies which core to use and the 5th parameter indicates the priority – both are set to “1” as there is only a single task on each core.

    The Arduino startup code has thus been reduced to the following:

    void core0Entry (void *pvParameters);
    TaskHandle_t core0Task;
    void core1Entry (void *pvParameters);
    TaskHandle_t core1Task;

    void setup () {
    xTaskCreatePinnedToCore(core0Entry, "Core 0 Task", 4096, NULL, 1, &core0Task, 0);
    xTaskCreatePinnedToCore(core1Entry, "Core 1 Task", 2048, NULL, 1, &core1Task, 1);
    }

    void loop () {
    // No main loop here
    }

    void core0Entry (void *pvParameters) {
    Task0Setup();

    for (;;) {
    Task0Loop();
    vTaskDelay(1); // Allow FreeRTOS IDLE to maintain watchdog
    }
    }

    void core1Entry (void *pvParameters) {
    Task1Setup();

    for (;;) {
    Task1Loop();
    vTaskDelay(1); // Allow FreeRTOS IDLE to maintain watchdog
    }
    }

    I’ve simulated the setup()/loop() pattern in each of the task entry points. One thing I quickly found was that if the tasks run with no release of the processor, then FreeRTOS will fail with a watchdog error.

    This is why each task includes a vTaskDelay(1) call to allow FreeRTOS to do whatever it needs to do as part of its “idle” processing.

    The other thing to be careful of, which would be the same even in a single core application, is that the timers and their timer interrupt routines also allow some general processing time on each core. This will become important further in the discussion.

    Task 0: PWM Generation

    The essence of Task 0 is the code from ESP32 and PWM. In order to simplify things I’ve created a basic oscillator class as follows:

    class COsc {
    public:
    COsc ();
    ~COsc (void);

    void Setup (int pwmpin, int wave, bool lfo=false);
    void QuadSetup (int sinpin, int sawpin, int tripin, int squpin);
    void ScanPWM (void);
    void SetFreq (uint16_t freq, uint16_t vol=MAX_VOL);
    void SetMVolts (uint32_t mvolts, uint16_t vol=MAX_VOL);
    }

    Initially the plan was to have one instance per PWM output. The pin and required waveform is configured as part of the call to the Setup() function.

    But then I decided it would be more efficient to utilise the fact that the same index and accumulator can be used to read through each of the four wavetables, so created the idea of a “quad” oscillator. This just requires the four PWM pins to be used to be specified as part of the call to QuadSetup() and eliminates several calls into the ScanPWM function for separate oscillators.

    There are two ways to set the oscillator’s frequency output. One is to pass in the frequency directly, the other is to pass in a millivolt reading from a potentiometer based on a 1V/oct scaling. The “zero volts” frequency is preset to be 65.406Hz, i.e. C2.

    The frequency is derived from the millivolt reading using the following:

    void COsc::SetMVolts (uint32_t mvolts, uint16_t vol) {
    // Set frequency according to Volt/Oct scaling
    // Freq = baseFreq * 2 ^ (voltage)
    //
    float freq = FREQ_0V * (powf (2.0, ((float)mvolts)/1000.0));
    int f = (int)freq;
    SetFreq(f, vol);
    }

    With the default settings this class can be used for both VCO and LFO, but the lowest frequency for the LFO was just 1Hz. Consequently, I’ve added the option to specify a “LFO” setting as part of the single oscillator Setup() function. If enabled, then the oscillator runs 10x slower than default. This allows for frequencies down to 0.1Hz, but does mean that the frequency or millivolt parameters are now treated as being 10 times smaller than their values would imply.

    Note when MIDI is added into the mix, I just use the NoteOn message to change the base frequency used for the oscillators.

    The ScanPWM() function is designed to be called from the interrupt routine running at the sample rate.

    The oscillators are thus created as two Quad oscillators (one per VCO) and two single oscillators for the dual waveforms of the LFO:

    #define OSC_VCO1 0
    #define OSC_VCO2 1
    #define OSC_LFO1 2
    #define OSC_LFO2 3
    #define NUM_OSC 4
    COsc *pOsc[NUM_OSC];
    int pwmpins[NUM_OSC][4] = {
    {17,18,5,19},
    {21,22,1,23},
    {16,0,0,0},
    {13,0,0,0}
    };
    int oscwaves[NUM_OSC] = {
    OSC_WAVES, // VCO 1 (quad)
    OSC_WAVES, // VCO 2 (quad)
    OSC_TRI, // LFO
    OSC_SAW
    };

    void oscSetup() {
    for (int i=0; i<NUM_OSC; i++) {
    pOsc[i] = new COsc();
    if (oscwaves[i] == OSC_WAVES) {
    // This is a quad oscillator
    pOsc[i]->QuadSetup (pwmpins[i][0], pwmpins[i][1], pwmpins[i][2], pwmpins[i][3]);
    } else {
    // A single oscillator - these are the LFOs
    pOsc[i]->Setup (pwmpins[i][0], oscwaves[i], true);
    }
    }
    }

    The timer configuration for Task 0 is as follows:

    #define TIMER_FREQ  10000000  // 1MHz * 10 (0.1uS)
    #define TIMER_RATE 305 // 30.5 uS * 10

    Task0Timer = timerBegin(TIMER_FREQ);
    timerAttachInterrupt(Task0Timer, &Task0TimerIsr);
    timerAlarm(Task0Timer, TIMER_RATE, true, 0);

    This generates a timer interrupt running at 32,768Hz from a 10MHz timer

    However, servicing 10 PWM outputs means that there is no time remaining once interrupt processing is complete for any other operations. Consequently, I set things up so that the PWM outputs are updated in two blocks of 5, meaning that the effective sample rate for PWM purposes is actually now 16,384Hz:

    int toggle0;
    void ARDUINO_ISR_ATTR Task0TimerIsr (void) {
    toggle0 = !toggle0;
    if (toggle0) {
    pOsc[OSC_VCO1]->ScanPWM();
    pOsc[OSC_LFO1]->ScanPWM();
    } else {
    pOsc[OSC_VCO2]->ScanPWM();
    pOsc[OSC_LFO2]->ScanPWM();
    }
    }

    The main Task 0 Loop just pulls in the analog IO values that have been read as part of the processing of Task 1. These values are then used to set the frequencies of each VCO and the LFO.

    Task 0: VCO Control

    The VCO potentiometers and CV inputs have to be combined to determine the frequency and amplitude of the PWM signal.

    In terms of amplitude, I’ve chosen to use the maximum of the pot or CV input to set the amplitude of VCO 1. Note that VCO 2 has no amplitude input, although with hindsight, I could have included a pot even though I’ve run out of GPIO pins for a CV input.

    This means that the pot has to be turned fully “off” for the CV to become significant.

    In terms of setting the frequencies, I initially thought about some kind of frequency modulation, which would have been good for linking the two VCOs together, but then decided actually I wanted a more straight forward relationship between pot and CV to allow the use of the LFO or the EGs for pitch. The result is going for a simple summation of the two inputs which gives a 3 octave range (started at C2) for each of the CV and pot, but when combined could give up to a 6 octave spread of frequencies.

    When MIDI is enabled, that will set the base frequency for the summation rather than defaulting to C2. This will set the base for both VCOs, so the pots/CVs could be used for a detuning style effect.

    Note: Due to the issues with the choice of pins for the inputs, the base level of the CV input for VCO2 is floating at around 300-600mV. The default (unconnected) configuration introduces an element of detuning. If the CV inputs are not wanted, then it is recommended to connect them to GND to eliminate this effect.

    The result of taking this approach, combined with the frequency of scanning the inputs, means that if one VCO is used to set the frequency for the other, then it probably won’t track the voltages accurately enough for a smooth modulation. But it does generation quite a wacky “sample and hold” style aliasing effect, which actually I quite like.

    I could try to do something about that, but I think in reality this is a use-case where a purely analog VCO can be added via breadboard as part of the experimentation which can be driven from the PWM VCOs – that should enable a number of possibilities for more complex oscillator modulation.

    There is also some clipping at higher LFO frequencies if used as the amplitude input. This needs to be investigated to see if that is a bug in the code or handling of the CV somehow.

    It is possible that this, and the aliasing of pitch, is a consequence of the frequency of scanning the analog inputs or the speed of the analogRead() function itself – it’s pretty slow. Some investigation is required to experiment with changing the frequency of the reading or rewriting to use the ESP32 API rather than the (slower) Arduino analogRead() function (more on that later).

    Task 1: IO Scanning

    All the IO is scanned as part of Task 1’s main processing loop. This has to cover the following:

    • Real analog values from the inputs corresponding to the VCO CVs.
    • Multiplexed analog values for all the pots for the VCOs, LFO and two EGs.
    • Digital IO for the EG gates and triggers.

    I started off reading the “real” analog IO associated with the VCOs in task 0, but found that it just wasn’t being scanned frequently enough to function in any useful manner. Also, the calls to analogRead() incur some kind of processing overhead that appears to interfere with the timing of the PWM timer interrupt, leaving “blips” in the output.

    I started to think about writing a FastAnalogRead() function to use the ESP32 SDK directly rather than the Arduino analogRead() function, but before doing that moved all the IO processing over to Task 1. It turns out that this seems to work adequately so if I’ve not done that at present.

    But one consequence of this chain of thought is that I now have two sets of functions performing my own analog IO reading:

    • MuxAnalogRead()
    • FastAnalogRead()

    Which both perform in very similar ways. I’ll describe the API for MuxAnalogRead(), but the same principles were used for FastAnalogRead() too.

    void MuxSetup(void);
    void MuxLoop(bool bVoltageReading=false);
    void MuxLoopSingle (uint8_t pot, bool bVoltageReading=false);
    uint16_t MuxAnalogRead (uint8_t pot);
    uint32_t MuxAnalogReadMilliVolts (uint8_t pot);

    The two Loop functions are designed to perform the actual reading from the hardware. Loop will read all known values in a single scan. LoopSingle() will read a single pot.

    The functions MuxAnalogRead() and MuxAnalogReadMilliVolts() are used to retrieve the previously read values.

    Scanning is performed using either the standard analogRead() or the ESP32 API function analogReadMilliVolts(). This is why a bVoltageReading parameter is required as part of the two Loop functions. It would be possible to calculate one from the other for every reading, but I’ve opted not to do that in order to keep the calculations required as part of a read as minimal as possible.

    This allows the scanning of the hardware to happen on one core (in Task 1 in this case) yet be read from the other (Task 0).

    Digital IO processing just requires monitoring the trigger and gate inputs for a HIGH->LOW transition and call the appropriate triggerADSR() or gateADSR() functions as required, although there is a bit more logic required to work in the MIDI input.

    The actually scanning of IO is split over the different scans of the Task Loop as follows:

    #define S_MUX (NUM_MUX_POTS-1)
    #define S_FASTIO (S_MUX+1)
    #define S_DIGIO (S_FASTIO+1)
    #define S_ALGIO (S_DIGIO+1)
    #define S_MIDI (S_ALGIO+1)
    #define S_LAST (S_MIDI+1)
    int taskState;

    void Task1Loop(void)
    {
    if (taskState <= S_MUX) {
    // Read each MUX pot in turn
    switch (taskState) {
    case 5: // VCO 1 CV
    case 7: // VCO 2 CV
    // These are read in millivolts...
    MuxLoopSingle(taskState, true);
    break;
    default:
    // These are read as 12-bit raw 0..4095
    MuxLoopSingle(taskState, false);
    break;
    }
    }
    else if (taskState == S_FASTIO) {
    Task1FastAlgIOLoop();
    }
    else if (taskState == S_DIGIO) {
    Task1DigIOLoop();
    }
    else if (taskState == S_ALGIO) {
    Task1AlgIOLoop();
    }
    else if (taskState == S_MIDI) {
    Task1MIDILoop();
    }
    else {
    taskState = S_LAST;
    }
    taskState++;
    if (taskState >= S_LAST) {
    taskState = 0;
    }
    }

    Task 1: Envelope Generation

    The core of the envelope generation code is from ESP32 DAC Envelope Generator, but once again the code has been refactored into a class as follows:

    class CEnv {
    public:
    CEnv ();
    ~CEnv (void);

    void setADSR (int eg_a, int eg_d, int eg_s, int eg_r);
    uint8_t nextADSR (void);
    void triggerADSR (void);
    void gateADSR (bool gateOn);
    void dumpADSR (void);
    }

    One change is setting the ADSR parameters in a single call. The values are assumed to be potentiometer readings in the range 0..4095.

    Two envelope generators are created by Task 1:

    CEnv *pEnv[NUM_ENV];

    void envSetup() {
    for (int i=0; i<NUM_ENV; i++) {
    pEnv[i] = new CEnv();
    }
    }

    The nextADSR() function has to be called for each envelope generator from the timer interrupt routine.

    The timer configuration for Task 1 is as follows:

    #define TIMER_FREQ  100000  // 100kHz (0.01mS)
    #define TIMER_RATE 10 // 0.1mS

    Task1Timer = timerBegin(TIMER_FREQ);
    timerAttachInterrupt(Task1Timer, &Task1TimerIsr);
    timerAlarm(Task1Timer, TIMER_RATE, true, 0);

    This generates a 10kHz sample rate for the EGs from a 100kHz timer signal.

    Task 1: MIDI

    I’m using the standard Arduino MIDI library. There are a couple of points to note however:

    • MIDI will set the TRIGGER and GATE according to the reception of NoteOn and NoteOff messages.
    • I will need to keep track of which note is playing so that overlapping NoteOn/NoteOff messages don’t confuse the GATE handling.
    • As I’m reusing the TX pin as a PWM output, PWM initialisation must happen after MIDI initialisation, otherwise MIDI will assume the use of both RX and TX.
    • Serial MIDI by default implements “software MIDI THRU” so this needs to be disabled using setThruOff().
    • MIDI will set the base frequency used for the VCO controls, so the pot and CV will add to the MIDI frequency.

    It isn’t clear what should happen with regards to frequency on NoteOff. Here are some options:

    • Reset back to default base frequency on NoteOff (the “0V” state), but this has the disadvantage that the frequency changes as soon as the gate signal initiates the Release state of the ADSR.
    • Wait until the envelope has finished the Release stage to reset the base frequency. This seems sensible when using the EGs, but has the disadvantage that when just using MIDI to set pitch, it will not revert back immediately on “key up” – it will only revert back when the envelope is complete, which is confusing if the EG is not being used.
    • Don’t reset the base frequency, this means the note will continue on the last used frequency until a new note is played.

    I’ve opted not to reset the base frequency on the basis of: if MIDI on/off handling is required, then it will probably be using envelopes anyway. If not, then having only MIDI on setting a sustained frequency sort of makes more sense to me.

    Closing Thoughts

    The code will continue to evolve as I keep tinkering with it, but the current state can be found in the GitHub repository for the project here: https://github.com/diyelectromusic/ESP32EduModHackThing

    There are still a few quirks and things I might continue to investigate and possibly optimise. Specifically:

    • The performance for reading the “real” analog CVs for the VCOs.
    • The frequency handling with respect to MIDI.

    But in general I think it is starting to get pretty usable.

    Kevin

    https://diyelectromusic.wordpress.com/2024/05/26/educational-diy-synth-thing-part-3/

    #adsr #define #envelopeGenerator #esp32 #lfo #oscillator #vca #vco

  15. The last module of my #diysynth that I had on breadboard is now soldered to a #perfboard. It's a #LFO with triangle and square wave output, with shape #potentiometer that changes the triangle wave towards sawtooth or ramp, and the duty cycle of the square wave between 5% and 95%.
    It has two speed settings with 0.12 to 5.3 Hz, or 1/80th to 0.5 Hz frequency. I might build a second one with different capacitors for higher frequencies.
    #soldering #synthesizer #oscillator #electronics