Expandmenu Shrunk


  • STM32F4 Envelope Generator & LFO

    After writing the common programs for LED blinking, fading etc,
    i started porting my Envelope Generator to my new developing platform.

    STM32 DISCO
    STM32F Discovery Board with MIDI interface

    I used the two built in 12bit DACs to generate the CVs. The update rate is 1ms.

     

    This is dual ADSR configuration
    This is dual ADSR configuration

    This envelope is triggerd by one Gate signal and the attack Rate is controlled by the NoteOn velocity.

     

    ADSR and sine LFO
    ADSR and sine LFO
    ADSR and tri LFO
    ADSR and tri LFO

    The LFOs are DDS based implementations with 12Bit resolution and a tablesize of 256 elements.

     

    Process Time with no optimization O0
    Process Time with no optimization O0

    Generating the two EGs lasts 2µs with no compiler optimizations -O0

    Process Time with no optimization O3
    Process Time with no optimization O3

    With full optimization -O3 it’s only 1 µs

     

    Share Button

  • First Software Envelope Generator

    This is my first software based Envelope Generator (ADSR).
    For better debugging and testing i have implemented this on my PC with VisualStudio.

    Here my uncommented source code and a simple test:

    #include "stdafx.h"
    #include <stdio.h> 
    
    // Max Level of the Attack Phase
    #define MAXVALUE 100
    
    //Envelope States
    enum {idle,attack, decay, sustain, release};
    
    //Parameters
    volatile int A_Rate = 50;
    volatile int D_Rate = 20;
    volatile int S_Level = 60;
    volatile int R_Rate = 10;
    
    volatile int State = idle;
    volatile int SumAttack = 0;
    volatile int DiffDecay = MAXVALUE;
    volatile int DiffRelease;
    volatile int ZEIT = 0;
    volatile int Env_Out =0;
    
    int CalcEnvelope(int Gate);
    
    //Calculates a simple ADSR Envelope
    int CalcEnvelope(int Gate)
    {
        switch(State) {
    
            case IDLE:
            
            #ifdef DEBUG_0
                printf("Idle\n");
            #endif
            
            if(Gate == 1)
            {
                State = ATTACK;
            }
            break;
    
            case ATTACK:
            
            #ifdef DEBUG_0
                printf("Attack\n");
            #endif
            
            if(Gate == 0)
            {
                State = RELEASE;
                DiffRelease = Env_Out;
            }
            else
            {
                SumAttack+=A_Rate;
                if(SumAttack >= MAXVALUE)
                {
                    SumAttack = MAXVALUE;
                    State = DECAY;
                }
                Env_Out = SumAttack;
            }
            break;
    
            case DECAY:
            
            #ifdef DEBUG_0
                printf("Decay\n");
            #endif
            
            if(Gate == 0)
            {
                State = RELEASE;
                DiffRelease = Env_Out;
            }
            else
            {
                DiffDecay-=D_Rate;
                if(DiffDecay > S_Level)
                {
                    
                    Env_Out = DiffDecay;
                }
                else
                {
                    Env_Out = S_Level;
                    State = SUSTAIN;
                }
                
                
            }
            
            break;
    
            case SUSTAIN:
            
            #ifdef DEBUG_0
                printf("Sustain\n");
            #endif
            
            if(Gate == 0)
            {
                State = RELEASE;
                DiffRelease= S_Level;
                DiffDecay = MAXVALUE;
            }
            break;
    
            case RELEASE:
            
            #ifdef DEBUG_0
                printf("Release\n");
            #endif
            
            if(Gate == 0)
            {
                DiffRelease-=R_Rate;
                if(DiffRelease > 0 )
                {
                    
                    Env_Out = DiffRelease;
                }
                else
                {
                    State= IDLE;
                    Env_Out = 0;
                    DiffRelease = 0;
                    DiffDecay = 0;
                    SumAttack = 0;
                }
    
            }
            else
            {
                State=ATTACK;
                SumAttack = Env_Out;
            }
            break;
    
            default:
            
            #ifdef DEBUG_0
                printf("default\n");
            #endif
            
            ;
                
        }
        return Env_out;
    }
    
        
    
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    
    
        printf("-------------------------------------------------------------------\n");
        printf("A_Rate= %d, D_Rate= %d, S_Level= %d, R_Rate= %d \n\n",A_Rate,D_Rate,S_Level,R_Rate);
    
        printf("-------------------------------------------------------------------\n");
        printf("Time--Gate--Value---State\n");
        for(int i=0;i<10;i++)
        {
            printf("%03d   On    %03d     ",ZEIT, CalcEnvelope(1));
            ZEIT++;
        }
    
    
        for(int i=0;i<3;i++)
        {
            printf("%03d   Off   %03d     ",ZEIT, CalcEnvelope(0));
            ZEIT++;
        }
    
    
        for(int i=0;i<10;i++)
        {
            printf("%03d   On    %03d     ",ZEIT, CalcEnvelope(1));
            ZEIT++;
        }
    
    
        for(int i=0;i<10;i++)
        {
            printf("%03d   Off   %03d     ",ZEIT, CalcEnvelope(0));
            ZEIT++;
        }
    
    
        for(int i=0;i<2;i++)
        {
            printf("%03d   On    %03d     ",ZEIT, CalcEnvelope(1));
            ZEIT++;
        }
    
        for(int i=0;i<10;i++)
        {
            printf("%03d   Off   %03d     ",ZEIT, CalcEnvelope(0));
            ZEIT++;
        }
    
        getchar();
        return 0;
    }
    

    This is the console Output:
    Envelope_test1
    The test shows a key down with an retrigger in the release phase (time013) followed by a complete run (finished at030) then you see a aborted attack phase (time035).

    Update 26.08.2015

    First tests with my controller board ATMEGA 32, 8Mhz LTC2756 18Bit DA

    Made some changes in the coding.

     

    MAXVALUE=262144 A_Rate = 1000 D_Rate = 500 S_Level= 131072 R_Rate = 250 Update Rate: 1ms Oscilloscope Setting: 200ms/cm
    MAXVALUE=262144
    A_Rate = 1000
    D_Rate = 500
    S_Level= 131072
    R_Rate = 250
    Update Rate: 1ms
    Oscilloscope Setting: 200ms/cm

     

    MAXVALUE=262144 A_Rate = 10000 D_Rate = 500 S_Level= 131072 R_Rate = 250 Update Rate: 1ms Oscilloscope Setting: 50ms/cm
    MAXVALUE=262144
    A_Rate = 10000
    D_Rate = 500
    S_Level= 131072
    R_Rate = 250
    Update Rate: 1ms
    Oscilloscope Setting: 50ms/cm

     

    MAXVALUE=262144 A_Rate = 100000 D_Rate = 500 S_Level= 131072 R_Rate = 250 Update Rate: 1ms Oscilloscope Setting: 1ms/cm
    MAXVALUE=262144
    A_Rate = 100000
    D_Rate = 500
    S_Level= 131072
    R_Rate = 250
    Update Rate: 1ms
    Oscilloscope Setting: 1ms/cm

     

    UPDATE 27.08.2015

    Fixed The MAXVALUE Problem Set this value to (2^18) -1

    MAXVALUE=262143 A_Rate = 1000 D_Rate = 500 S_Level= 131072 R_Rate = 250 Update Rate: 1ms Oscilloscope Setting: 200ms/cm
    MAXVALUE=262143
    A_Rate = 1000
    D_Rate = 500
    S_Level= 131072
    R_Rate = 250
    Update Rate: 1ms
    Oscilloscope Setting: 200ms/cm
    Share Button

  • Midi- Keyboard Controller

    The “Brain” is a Atmel ATMega32 microcontroller.

    Controller step1
    ATMega32 based “Brain”

    Lower board with voltage regulator µC and later the MIDI connector.

     

    Controller step2
    second floor for the display

    The upper board is for the display and some switches.

     

    Controller1_web
    Controller board with display

    First test.

     

    Short introduction of the Midi- Keyboard Controller
    http://youtu.be/WbaWY7JQ8yg

    Here the 2. part of the MIDI- keyboardcontroller which shows the whole Setup on the workbench.
    http://youtu.be/90V15MwvQas

    Here is the 3. part where i try to explain how to create the control voltages in a polyphonic Synthesizer.
    https://youtu.be/0WTKVwBKnBE

    Here is the 4. part of the series. I show a very simple implementation of a polyphonic synthesizer.
    http://youtu.be/tIK13oolDLs

     

     

     

     

     

     

     

    Share Button