Tsuyoshi TSUCHIMOTO / Mbed 2 deprecated Synthesizer

Dependencies:   mbed

Occilator.cpp

Committer:
117Florian
Date:
2016-02-09
Revision:
8:dd2da7c0c4c7
Parent:
7:a478d5cc411e
Child:
9:d2a5406650ae

File content as of revision 8:dd2da7c0c4c7:

#include "mbed.h"
#include "global.h"
#include "Occilator.h"
#include "Square.h"
#include "WT.h"
#include "Sine.h"
#include "Noise.h"
#include "Saw.h"

static long interrupt_us;
static int part_num=0;
static Occilator* part[OCCILATOR_PART_NUM];
static Ticker sTicker;
static long total_value_in_this_span;
static AnalogOut sAnalogOut(p18);
static long sMasterVolume=(1/3.3)*0x10000;

/* interrupt handler */
/*static void tick(uint32_t id);*/
static void tick();

Occilator* Occilator::getInstance(Occilator_Type type,long interrupt_us)
{
    switch(type)
    {
        case OCC_NONE:
        case OCC_SQUARE:
            return new Square(interrupt_us);

        case OCC_NOISE:
            return new Noise(interrupt_us);
            
        case OCC_SINE:
            return new Sine(interrupt_us);
            
        case OCC_SAW:
            return new Saw(interrupt_us);
        case OCC_WT:
        default:
            return new WT(interrupt_us);
        
    }
}

void Occilator::setMasterVolume(long volume)
{
    sMasterVolume=volume;
}

Occilator::Occilator(long interrupt_us)
{
    myled1=1;
    ::interrupt_us=interrupt_us;
    if(part_num==0)
    {
        sTicker.attach_us(::tick,interrupt_us);
    }
    part_num++;
    for(int i=0;i<OCCILATOR_PART_NUM;i++)
    {
        if(part[i]==NULL)
        {
            part[i]=this;
            break;
        }
    }
    
    m_Volume=0x10000;
}

Occilator::~Occilator()
{
    part_num--;
    for(int i=0;i<OCCILATOR_PART_NUM;i++)
    {
        if(part[i]==this)
        {
            part[i]=NULL;
            break;
        }
    }
    if(part_num<=0)
    {
        sTicker.detach();
    }
}

void Occilator::setOmega(long speed)
{
    m_Omega=speed;
    myled2=1;
}

void Occilator::setVolume(int volume)
{
    m_Volume=volume;
}

unsigned long Occilator::tick()
{
    m_Angle+=m_Omega;
    return 0L;
}

void ::tick()
{
    long long value=0;

    for (int i=0;i<OCCILATOR_PART_NUM;i++)
    {
        if (part[i]!=NULL)
        {
            value+=total_value_in_this_span + part[i]->tick();
        }
    }
    value = value>=0x10000 ? 0xffff : value;
    value = (sMasterVolume*value)>>16;
    sAnalogOut.write_u16(value);
    myled4=value > 0x80000000;
}