Expandmenu Shrunk


  • Category Archives Allgemein
  • 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

  • VCA board

    The next step ist building the Voltage controlled amplifier (VCA). For this i use the well known LM13700.
    For my Polyphonic Synth Project (PSP) I need a fully voltage controlled module with 3 inputs.

    FirstImpressionVCA
    Here a first impression(board not fully populated)

     

    Share Button

  • Update poly synth controller 25-01-2015

    I put the voltage distributor circuit  from the veroboard to the S/H board
    and added trimpots for offset compensation.

    VoltageDist sample -hold_web_small

     

    I made some measurements at the voltage outputs and saw that they
    are allways to high but the ratio seems to be okay.

    CVOutOscill_web_small

    Here a picture from the oscilloscope

    1mv/div,  0.5ms/div
    10:1 Probe

    I think i have to add a FET switch to change the circuit from Track and Hold to a real Sample and Hold circuit.

    Schematic will follow….

     Here you can here the first Chords.

     

    Share Button