view Source/ClassicAmbiDec.cpp @ 12:87dc3d84c120

Addressed the load program defaults over user settings 'feature'. Removed isChild on objects that are added before the frame creation since a)they're always there and b) doesn't write to all displays present.
author martinm_home <martin.morrell@eecs.qmul.ac.uk>
date Thu, 27 Sep 2012 23:29:16 +0100
parents
children
line wrap: on
line source
#ifndef __ClassicAmbiDec__
#include "ClassicAmbiDec.h"
#endif
//C++ Headers
#include <stdio.h>
#include <string.h>
#include <cmath>

//GUI Headers
#include "aeffguieditor.h"


//-----------------------------------------------------------------------------
ClassicAmbiDecProgram::ClassicAmbiDecProgram()
{
    
}



//-----------------------------------------------------------------------------
ClassicAmbiDec::ClassicAmbiDec (audioMasterCallback audioMaster)
: AudioEffectX (audioMaster, kNumPrograms, kNumParameters)
{	
    
    
    //Set the number of input and output channels
	setNumInputs (4);	// 4 Channel Classic B-Format Input
	setNumOutputs (MAX_CHANNELS);	// MAX_CHANNELS 5.1 Output
    
    //Initially set the number of inputs and outputs incase (set|get)SpeakerArrangement isn't called
    numberInputs=4;
    numberOutputs=MAX_CHANNELS;
    allocateArrangement (&myInputArrangement, 4);
    myInputArrangement->type = kSpeakerArr31Cine;
    
	setUniqueID ('MMca');
    canDoubleReplacing(); //Plugin can use process double replacing
    canProcessReplacing(); //Plugin can use process replacing
    noTail ();
    
    bool bit64 = setProcessPrecision(kVstProcessPrecision64);
    if (bit64==true) {
        bits=64;
    }
    else{
        bits=32;
    }
    

    //  Declare any variables to their default values
    fMode = 0.f;
    fWidth = 0.5f;
    fPattern = 0.5f;
    fRotate = 0.5f;
    fTilt = 0.5f;
	fTumble = 0.5f;
	fZoom = 0.5f;
	fZoomMethod = 0.f;
	fRearVerb = 0.f;
	fHiVerb = 0.f;
    fCentrePattern =0.5f;
    fCentreGain = 0.75f;
    fSubGain = 0.75f;
    fFc = 5.0f/11.0f;
    fSurroundMode = 0.f;
    fSurroundPattern = 0.5;
    fSurroundWidth = 2.f/3.f;
    fSurroundGain = 0.75f;
    fDecoderMode = 0.f;
    fChannelOrder = 1.f;

    myDecoder.Fs = sampleRate;
    myDecoder.filterCoefs();
    
    
    programs_20 = new ClassicAmbiDecProgram[kNumParameters];
    programs_21 = new ClassicAmbiDecProgram[kNumParameters];
    programs_40 = new ClassicAmbiDecProgram[kNumParameters];
    programs_50 = new ClassicAmbiDecProgram[kNumParameters];
    programs_51 = new ClassicAmbiDecProgram[kNumParameters];

    //Initailise all the programs
    //Stereo Mode
        //Name
        vst_strncpy (programs_20[0].name, "Stereo XY Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_20[1].name, "Stereo MS Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_20[2].name, "Stereo Blumlein Fig8s",kVstMaxProgNameLen);
        vst_strncpy (programs_20[3].name, "Stereo XY with 'Verb",kVstMaxProgNameLen);
        vst_strncpy (programs_20[4].name, "Stereo MS with 'Verb",kVstMaxProgNameLen);
        //Mode
        programs_20[0].mode = 0.f;
        programs_20[1].mode = 1.f;
        programs_20[2].mode = 0.f;
        programs_20[3].mode = 0.f;
        programs_20[4].mode = 1.f;
        //Width
        programs_20[0].width = (1.f/3.f);
        programs_20[1].width = (1.f/3.f);
        programs_20[2].width = 0.5f;
        programs_20[3].width = (1.f/3.f);
        programs_20[4].width = (1.f/3.f);
        //Pattern
        programs_20[0].pattern = 0.5f;
        programs_20[1].pattern = 0.5f;
        programs_20[2].pattern = 0.f;
        programs_20[3].pattern = 0.5f;
        programs_20[4].pattern = 0.5f;
        //RearVerb
        programs_20[0].rearVerb = 0.f;
        programs_20[1].rearVerb = 0.f;
        programs_20[2].rearVerb = 0.f;
        programs_20[3].rearVerb = 0.75f;
        programs_20[4].rearVerb = 0.75f;
        //HiVerb
        programs_20[0].hiVerb = 0.f;
        programs_20[1].hiVerb = 0.f;
        programs_20[2].hiVerb = 0.f;
        programs_20[3].hiVerb = 0.25f;
        programs_20[4].hiVerb = 0.25f;
    
    
    //2.1 Mode
        //Name
        vst_strncpy (programs_21[0].name, "2.1 XY Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_21[1].name, "2.1 MS Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_21[2].name, "2.1 Blumlein Fig8s",kVstMaxProgNameLen);
        vst_strncpy (programs_21[3].name, "2.1 XY with 'Verb",kVstMaxProgNameLen);
        vst_strncpy (programs_21[4].name, "2.1 MS with 'Verb",kVstMaxProgNameLen);
        //Mode
        programs_21[0].mode = 0.f;
        programs_21[1].mode = 1.f;
        programs_21[2].mode = 0.f;
        programs_21[3].mode = 0.f;
        programs_21[4].mode = 1.f;
        //Width
        programs_21[0].width = (1.f/3.f);
        programs_21[1].width = (1.f/3.f);
        programs_21[2].width = 0.5f;
        programs_21[3].width = (1.f/3.f);
        programs_21[4].width = (1.f/3.f);
        //Pattern
        programs_21[0].pattern = 0.5f;
        programs_21[1].pattern = 0.5f;
        programs_21[2].pattern = 0.f;
        programs_21[3].pattern = 0.5f;
        programs_21[4].pattern = 0.5f;
        //RearVerb
        programs_21[0].rearVerb = 0.f;
        programs_21[1].rearVerb = 0.f;
        programs_21[2].rearVerb = 0.f;
        programs_21[3].rearVerb = 0.75f;
        programs_21[4].rearVerb = 0.75f;
        //HiVerb
        programs_21[0].hiVerb = 0.f;
        programs_21[1].hiVerb = 0.f;
        programs_21[2].hiVerb = 0.f;
        programs_21[3].hiVerb = 0.25f;
        programs_21[4].hiVerb = 0.25f;
        //SubGain
        programs_21[0].subGain = 0.75f;
        programs_21[1].subGain = 0.75f;
        programs_21[2].subGain = 0.75f;
        programs_21[3].subGain = 0.75f;
        programs_21[4].subGain = 0.75f;
        //FC
        programs_21[0].fc = 5.0f/11.0f;
        programs_21[1].fc = 5.0f/11.0f;
        programs_21[2].fc = 5.0f/11.0f;
        programs_21[3].fc = 5.0f/11.0f;
        programs_21[4].fc = 5.0f/11.0f;
    
    
    
    //Quad Mode
        //Name
        vst_strncpy (programs_40[0].name, "Quad XY Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_40[1].name, "Quad MS Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_40[2].name, "Quad Blumlein Fig8s",kVstMaxProgNameLen);
        vst_strncpy (programs_40[3].name, "Quad XY with MS",kVstMaxProgNameLen);
        vst_strncpy (programs_40[4].name, "Quad MS with XY",kVstMaxProgNameLen);
        //Mode
        programs_40[0].mode = 0.f;
        programs_40[1].mode = 1.f;
        programs_40[2].mode = 0.f;
        programs_40[3].mode = 0.f;
        programs_40[4].mode = 1.f;
        //Width
        programs_40[0].width = (1.f/3.f);
        programs_40[1].width = (1.f/3.f);
        programs_40[2].width = 0.5f;
        programs_40[3].width = (1.f/3.f);
        programs_40[4].width = (1.f/3.f);
        //Pattern
        programs_40[0].pattern = 0.5f;
        programs_40[1].pattern = 0.5f;
        programs_40[2].pattern = 0.f;
        programs_40[3].pattern = 0.5f;
        programs_40[4].pattern = 0.5f;
        //Surround Mode
        programs_40[0].surroundMode = 0.f;
        programs_40[1].surroundMode = 1.f;
        programs_40[2].surroundMode = 0.f;
        programs_40[3].surroundMode = 1.f;
        programs_40[4].surroundMode = 0.f;
        //Surround Width
        programs_40[0].surroundWidth = (5.5f/9.f);
        programs_40[1].surroundWidth = (5.5f/9.f);
        programs_40[2].surroundWidth = 0.5f;
        programs_40[3].surroundWidth = (5.5f/9.f);
        programs_40[4].surroundWidth = (5.5f/9.f);
        //Surround Pattern
        programs_40[0].surroundPattern = 0.5;
        programs_40[1].surroundPattern = 0.5;
        programs_40[2].surroundPattern = 0.0;
        programs_40[0].surroundPattern = 0.25;
        programs_40[0].surroundPattern = 0.75;
        //Surround Gain
        programs_40[0].surroundGain = 0.75f;
        programs_40[1].surroundGain = 0.75f;
        programs_40[2].surroundGain = 0.75f;
        programs_40[3].surroundGain = 0.75f;
        programs_40[4].surroundGain = 0.75f;

    
    //5.0 Mode
        //Name
        vst_strncpy (programs_50[0].name, "5.0 XY Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_50[1].name, "5.0 MS Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_50[2].name, "5.0 Blumlein Fig8s",kVstMaxProgNameLen);
        vst_strncpy (programs_50[3].name, "5.0 Heller et. al. 1",kVstMaxProgNameLen);
        vst_strncpy (programs_50[4].name, "5.0 Heller et. al. 2",kVstMaxProgNameLen);
        //Mode
        programs_50[0].mode = 0.f;
        programs_50[1].mode = 1.f;
        programs_50[2].mode = 0.f;
        //Width
        programs_50[0].width = (1.f/3.f);
        programs_50[1].width = (1.f/3.f);
        programs_50[2].width = 0.5f;
        //Pattern
        programs_50[0].pattern = 0.5f;
        programs_50[1].pattern = 0.5f;
        programs_50[2].pattern = 0.f;
        //Centre Pattern
        programs_50[0].centrePattern = 0.5f;
        programs_50[1].centrePattern = 0.5f;
        programs_50[2].centrePattern = 0.0f;
        //Centre Gain
        programs_50[0].centreGain = 0.75f;
        programs_50[1].centreGain = 0.75f;
        programs_50[2].centreGain = 0.75f;
        //Surround Mode
        programs_50[0].surroundMode = 0.f;
        programs_50[1].surroundMode = 1.f;
        programs_50[2].surroundMode = 0.f;
        //Surround Width
        programs_50[0].surroundWidth = (5.5f/9.f);
        programs_50[1].surroundWidth = (5.5f/9.f);
        programs_50[2].surroundWidth = 0.5f;
        //Surround Pattern
        programs_50[0].surroundPattern = 0.5;
        programs_50[1].surroundPattern = 0.5;
        programs_50[2].surroundPattern = 0.0;
        //Surround Gain
        programs_50[0].surroundGain = 0.75f;
        programs_50[1].surroundGain = 0.75f;
        programs_50[2].surroundGain = 0.75f;
    
    
    //5.1 Mode
        //Name
        vst_strncpy (programs_51[0].name, "5.1 XY Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_51[1].name, "5.1 MS Microphones",kVstMaxProgNameLen);
        vst_strncpy (programs_51[2].name, "5.1 Blumlein Fig8s",kVstMaxProgNameLen);
        vst_strncpy (programs_51[3].name, "5.1 Heller et. al. 1",kVstMaxProgNameLen);
        vst_strncpy (programs_51[4].name, "5.1 Heller et. al. 2",kVstMaxProgNameLen);
        //Mode
        programs_51[0].mode = 0.f;
        programs_51[1].mode = 1.f;
        programs_51[2].mode = 0.f;
        //Width
        programs_51[0].width = (1.f/3.f);
        programs_51[1].width = (1.f/3.f);
        programs_51[2].width = 0.5f;
        //Pattern
        programs_51[0].pattern = 0.5f;
        programs_51[1].pattern = 0.5f;
        programs_51[2].pattern = 0.f;
        //Centre Pattern
        programs_51[0].centrePattern = 0.5f;
        programs_51[1].centrePattern = 0.5f;
        programs_51[2].centrePattern = 0.0f;
        //Centre Gain
        programs_51[0].centreGain = 0.75f;
        programs_51[1].centreGain = 0.75f;
        programs_51[2].centreGain = 0.75f;
        //SubGain
        programs_51[0].subGain = 0.75f;
        programs_51[1].subGain = 0.75f;
        programs_51[2].subGain = 0.75f;
        programs_51[3].subGain = 0.75f;
        programs_51[4].subGain = 0.75f;
        //FC
        programs_51[0].fc = 5.0f/11.0f;
        programs_51[1].fc = 5.0f/11.0f;
        programs_51[2].fc = 5.0f/11.0f;
        programs_51[3].fc = 5.0f/11.0f;
        programs_51[4].fc = 5.0f/11.0f;
        //Surround Mode
        programs_51[0].surroundMode = 0.f;
        programs_51[1].surroundMode = 1.f;
        programs_51[2].surroundMode = 0.f;
        //Surround Width
        programs_51[0].surroundWidth = (5.5f/9.f);
        programs_51[1].surroundWidth = (5.5f/9.f);
        programs_51[2].surroundWidth = 0.5f;
        //Surround Pattern
        programs_51[0].surroundPattern = 0.5;
        programs_51[1].surroundPattern = 0.5;
        programs_51[2].surroundPattern = 0.0;
        //Surround Gain
        programs_51[0].surroundGain = 0.75f;
        programs_51[1].surroundGain = 0.75f;
        programs_51[2].surroundGain = 0.75f;

    
    //Load GUI
    extern AEffGUIEditor* createEditor (AudioEffectX*);
	setEditor (createEditor (this));
    
	resume ();		// flush buffer
    
    //Load Program0 default
    if (programs_20||programs_21||programs_40||programs_50||programs_51) {
        setProgram(0);
    }
}


void ClassicAmbiDec::suspend()
{
    myDecoder.clearFilter();
    
    if (editor){
        ((AEffGUIEditor*)editor)->setParameter (100, 0);
    }
}

void ClassicAmbiDec::close()
{
}


void ClassicAmbiDec::open()
{
}





//------------------------------------------------------------------------
bool ClassicAmbiDec::setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
                                        VstSpeakerArrangement* pluginOutput)
{
    numberInputs = pluginInput->numChannels;
    numberOutputs = pluginOutput->numChannels;
    
    
    bool result;//What to return, true for acceptable speaker arrangement
    
    switch (pluginOutput->type) {
        case kSpeakerArr51://5.1 Output
        {
            if (pluginInput->type==kSpeakerArr31Cine) {
                result = true;
                }
            else {
                allocateArrangement (&myInputArrangement, 4);
                myInputArrangement->type = kSpeakerArr31Cine;
                result = false;
            }
            break;
        }
            
        case kSpeakerArr50://NOT WORKING AS INTENDED
        {
            if (pluginInput->numChannels==4) {
                result = true;
            }
            else {
                allocateArrangement (&myInputArrangement, 4);
                myInputArrangement->type = kSpeakerArr31Cine;
                result = false;
            }
            break;
        }
            
        case kSpeakerArr40Cine://4.0 Output (LRCS)
        {
            if (pluginInput->type==kSpeakerArr40Cine) {
                result = true;
            }
            else {
                allocateArrangement (&myInputArrangement, 4);
                myInputArrangement->type = kSpeakerArr40Cine;
                result = false;
            }
            break;
        }
            
        case kSpeakerArr40Music://4.0 Output (Music)
        {
            if (pluginInput->type==kSpeakerArr40Music) {
                result = true;
            }
            else {
                allocateArrangement (&myInputArrangement, 4);
                myInputArrangement->type = kSpeakerArr40Music;
                result = false;
            }
            break;
        }
            
        case kSpeakerArrStereo://Stereo
        {
            if (pluginInput->type==kSpeakerArr40Music) {
                result = true;
            }
            else {
                result = false;
            }
            break;
        }
            
            
        default:
        {
            if (pluginInput->type==kSpeakerArr31Cine) {
                result = true;
            }
            else {
                allocateArrangement (&myInputArrangement, 4);
                myInputArrangement->type = kSpeakerArr31Cine;
                result = false;
            }
            break;
        }
    }
    
    return result;
}


//------------------------------------------------------------------------
bool ClassicAmbiDec::getSpeakerArrangement(VstSpeakerArrangement **pluginInput, VstSpeakerArrangement **pluginOutput)
{
	*pluginInput  = myInputArrangement;    
    return true;
}



//------------------------------------------------------------------------
VstInt32 ClassicAmbiDec::getVstVersion()
{
    return kVstVersion;
}


//------------------------------------------------------------------------
ClassicAmbiDec::~ClassicAmbiDec () //clears protected variables
{
	deallocateArrangement (&myInputArrangement);
    
    if (programs_20)
		delete[] programs_20;
    if (programs_21)
		delete[] programs_21;
    if (programs_40)
		delete[] programs_40;
    if (programs_50)
		delete[] programs_50;
    if (programs_51)
		delete[] programs_51;
}


//------------------------------------------------------------------------
void ClassicAmbiDec::resume ()  //Do this on a resume from the host
{
	AudioEffectX::resume ();
    if (editor){
        ((AEffGUIEditor*)editor)->setParameter (101, 0);
    }
}


//------------------------------------------------------------------------
bool ClassicAmbiDec::getProgramNameIndexed(VstInt32 category, VstInt32 index, char *text)
{
    switch (myDecoder.decoderMode) {
        case 2:
            strcpy(text, programs_20[index].name);
            break;
        case 3:
            strcpy(text, programs_21[index].name);
            break;
        case 4:
            strcpy(text, programs_40[index].name);
            break;
        case 5:
            strcpy(text, programs_50[index].name);
            break;
        case 6:
            strcpy(text, programs_51[index].name);
            break;
            
        default:
            break;
    }

    return true;
}


//------------------------------------------------------------------------
void ClassicAmbiDec::setProgram(VstInt32 program)
{
    ClassicAmbiDecProgram* curProg;
    curProgram = program;

    switch (myDecoder.decoderMode) {
        case 2:
            curProg = &programs_20[program];
            setParameter(kMode, curProg->mode);
            setParameter(kWidth, curProg->width);
            setParameter(kPattern, curProg->pattern);
            setParameter(kRearVerb, curProg->rearVerb);
            setParameter(kHiVerb, curProg->hiVerb);
            break;
            
        case 3:
            curProg = &programs_21[program];
            setParameter(kMode, curProg->mode);
            setParameter(kWidth, curProg->width);
            setParameter(kPattern, curProg->pattern);
            setParameter(kRearVerb, curProg->rearVerb);
            setParameter(kHiVerb, curProg->hiVerb);
            setParameter(kSubGain, curProg->subGain);
            setParameter(kFc, curProg->fc);
            break;
            
        case 4:
            curProg = &programs_40[program];
            setParameter(kMode, curProg->mode);
            setParameter(kWidth, curProg->width);
            setParameter(kPattern, curProg->pattern);
            setParameter(kSurroundMode, curProg->surroundMode);
            setParameter(kSurroundWidth, curProg->surroundWidth);
            setParameter(kSurroundPattern, curProg->surroundPattern);
            setParameter(kSurroundGain, curProg->surroundGain);
            break;

        case 5:
            curProg = &programs_50[program];
            if (program<3) {
                myDecoder.mode5x=0;
                setParameter(kMode, curProg->mode);
                setParameter(kWidth, curProg->width);
                setParameter(kPattern, curProg->pattern);
                setParameter(kCentrePattern, curProg->centrePattern);
                setParameter(kCentreGain, curProg->centreGain);
                setParameter(kSurroundMode, curProg->surroundMode);
                setParameter(kSurroundWidth, curProg->surroundWidth);
                setParameter(kSurroundPattern, curProg->surroundPattern);
                setParameter(kSurroundGain, curProg->surroundGain);
                if (editor){
                    ((AEffGUIEditor*)editor)->setParameter (103, 0.f);
                }
            }
            else if (program==3) {
                myDecoder.mode5x=1;
                if (editor){
                    ((AEffGUIEditor*)editor)->setParameter (103, 0.5f);
                }
            }
            else if (program==4) {
                myDecoder.mode5x=2;
                if (editor){
                    ((AEffGUIEditor*)editor)->setParameter (103, 1.f);
                }
            }
            break;
        case 6:
            curProg = &programs_51[program];
            if (program<3) {
                myDecoder.mode5x=0;
                setParameter(kMode, curProg->mode);
                setParameter(kWidth, curProg->width);
                setParameter(kPattern, curProg->pattern);
                setParameter(kCentrePattern, curProg->centrePattern);
                setParameter(kCentreGain, curProg->centreGain);
                setParameter(kSubGain, curProg->subGain);
                setParameter(kFc, curProg->fc);
                setParameter(kSurroundMode, curProg->surroundMode);
                setParameter(kSurroundWidth, curProg->surroundWidth);
                setParameter(kSurroundPattern, curProg->surroundPattern);
                setParameter(kSurroundGain, curProg->surroundGain);
                
                if (editor){
                    ((AEffGUIEditor*)editor)->setParameter (103, 0.f);
                }
            }
            else if (program==3) {
                //Only set the sub
                setParameter(kSubGain, curProg->subGain);
                setParameter(kFc, curProg->fc);
                myDecoder.mode5x=1;
                if (editor){
                    ((AEffGUIEditor*)editor)->setParameter (103, 0.5f);
                }
            }
            else if (program==4) {
                //Only set the sub
                setParameter(kSubGain, curProg->subGain);
                setParameter(kFc, curProg->fc);
                myDecoder.mode5x=2;
                if (editor){
                    ((AEffGUIEditor*)editor)->setParameter (103, 1.f);
                }
            }
            break;
            
        default:
            curProg = &programs_20[program];
            break;
    }
}



//------------------------------------------------------------------------
void ClassicAmbiDec::setProgramName (char *name)
{
    switch (myDecoder.decoderMode) {
        case 2:
            strcpy (programs_20[curProgram].name, name);
            break;
        case 3:
            strcpy (programs_21[curProgram].name, name);
            break;
        case 4:
            strcpy (programs_40[curProgram].name, name);
            break;
        case 5:
            strcpy (programs_50[curProgram].name, name);
            break;
        case 6:
            strcpy (programs_51[curProgram].name, name);
            break;
            
        default:
            break;
    }
}

//------------------------------------------------------------------------
void ClassicAmbiDec::getProgramName (char *name)
{
    switch (myDecoder.decoderMode) {
        case 2:
            strcpy (name, programs_20[curProgram].name);
            break;
        case 3:
            strcpy (name, programs_21[curProgram].name);
            break;
        case 4:
            strcpy (name, programs_40[curProgram].name);
            break;
        case 5:
            strcpy (name, programs_50[curProgram].name);
            break;
        case 6:
            strcpy (name, programs_51[curProgram].name);
            break;
            
        default:
            break;
    }
}




//------------------------------------------------------------------------
//VstInt32 ClassicAmbiDec::getProgram()
//{
//    return curProgram;
//}





//------------------------------------------------------------------------
void ClassicAmbiDec::setParameter (VstInt32 index, float value) // SET Parameter value from host
{
    ClassicAmbiDecProgram* curProg;
    switch (myDecoder.decoderMode) {
        case 2:
            curProg = &programs_20[curProgram];
            break;
        case 3:
            curProg = &programs_21[curProgram];
            break;
        case 4:
            curProg = &programs_40[curProgram];
            break;
        case 5:
            curProg = &programs_50[curProgram];
            break;
        case 6:
            curProg = &programs_51[curProgram];
            break;
            
        default:
            curProg = &programs_20[curProgram];
            break;
    }
    
    
	switch (index)
	{
        case kMode :
			fMode = curProg->mode = value;
			if (value<=0.5f) {
				myDecoder.Mode = 0;
			}
			else {
				myDecoder.Mode = 1;
			}
            break;
		case kWidth:
			fWidth = curProg->width = value;
			myDecoder.Width = (double)value*90;
			break;
		case kPattern:
			fPattern = curProg->pattern = value;
			myDecoder.Pattern = (double)value;
			break;
		case kRotate :
			fRotate = value;
			if (value==0.5f) {
				myDecoder.Rotate=0.0;
			}
			else {
				myDecoder.Rotate = (double)value*-360+180;
			}
			break;
		case kTilt:
			fTilt = value;
			if (value==0.5f) {
				myDecoder.Tilt=0.0;
			}
			else {
				myDecoder.Tilt = (double)value*-360+180;
			}
			break;
		case kTumble:
			fTumble = value;
			if (value==0.5f) {
				myDecoder.Tumble=0.00;
			}
			else {
				myDecoder.Tumble = (double)value*-360+180;
			}
			break;
		case kZoom:
			fZoom = value;
			myDecoder.Zoom = (double)value*200-100;
			break;
		case kZoomMethod:
			fZoomMethod = value;
			if (value<=0.2f) {
				myDecoder.ZoomMethod = 0;
			}
			else if (value>0.2f && value<=0.5f) {
				myDecoder.ZoomMethod = 1;
			}
			else if (value>0.5f && value<=0.8f) {
				myDecoder.ZoomMethod = 2;
			}
			else if (value>0.8f && value<=1.f) {
				myDecoder.ZoomMethod = 3;
			}
			
			break;
		case kRearVerb :
			fRearVerb = curProg->rearVerb = value;
            if (value==0.0f) {
                myDecoder.RearVerb=-100;
            }
            else {
                myDecoder.RearVerb = -36+(double)value*36;
            }
			break;
		case kHiVerb :
			fHiVerb = curProg->hiVerb = value;
            if (value==0.0f) {
                myDecoder.HiVerb=-100;
            }
            else {
                myDecoder.HiVerb= -36+(double)value*36;
            }
			break;
        case kCentrePattern:
            fCentrePattern = curProg->centrePattern = value;
			myDecoder.centrePattern = (double)value;
            break;
        case kCentreGain:
            fCentreGain = curProg->centreGain = value;
			myDecoder.centreGain = ((double)value*24-18);
            break;
        case kSubGain:
            fSubGain = curProg->subGain = value;
			myDecoder.subGain = ((double)value*24-18);
            break;
        case kFc:
            fFc = curProg->fc = value;
			myDecoder.Fc = (int)((value*220)+20);
            myDecoder.filterCoefs();
            break;
        case kSurroundMode:
            fSurroundMode = curProg->surroundMode = value;
            if (value<=0.5f) {
				myDecoder.surMode = 0;
			}
			else {
				myDecoder.surMode = 1;
			}
            break;
        case kSurroundPattern:
            fSurroundPattern = curProg->surroundPattern = value;
			myDecoder.surPattern = (double)value;
            break;
        case kSurroundWidth:
            fSurroundWidth = curProg->surroundWidth = value;
			myDecoder.surWidth = (double)value*90;
            break;
        case kSurroundGain:
            fSurroundGain = curProg->surroundGain = value;
			myDecoder.surGain = ((double)value*24-18);
            break;
        case kDecoderMode:
            fDecoderMode = value;
            
            if (value<=0.125f) {
				myDecoder.decoderMode = 2; //Stereo
			}
			else if (value>0.125f && value<=0.375f) {
				myDecoder.decoderMode = 3; //2.1
			}
			else if (value>0.375f && value<=0.625f) {
				myDecoder.decoderMode = 4; //Quad
			}
			else if (value>0.625f && value<=0.875f) {
				myDecoder.decoderMode = 5; //5.0
			}
            else if (value>0.875f) {
				myDecoder.decoderMode = 6; //5.1
			}
            updateDisplay();
            break;
        case kChannelOrder:
            fChannelOrder = value;
			if (value<=0.5f) {
				myDecoder.channelOrder = 0; //Natural Outputs
			}
			else {
                myDecoder.channelOrder = 1; //5.1 Outputs
			}
            break;
            
        default:
            break;
	}
    if (editor){
        ((AEffGUIEditor*)editor)->setParameter (index, value);
    }
    if (index==kDecoderMode) {
        setProgram(curProgram);
    }
}


//------------------------------------------------------------------------
float ClassicAmbiDec::getParameter (VstInt32 index) // GET the value of the parameter
{
	float returnFloat; 
    
	switch (index)
	{
        case kMode :
			returnFloat = fMode;
            break;
		case kWidth:
			returnFloat = fWidth;
			break;
		case kPattern:
			returnFloat = fPattern;
			break;
		case kRotate :
			returnFloat = fRotate;
			break;
		case kTilt:
			returnFloat = fTilt;
			break;
		case kTumble:
			returnFloat = fTumble;
			break;
		case kZoom:
			returnFloat = fZoom;
			break;
		case kZoomMethod:
			returnFloat = fZoomMethod;
			break;
		case kRearVerb :
			returnFloat = fRearVerb;
			break;
		case kHiVerb :
			returnFloat = fHiVerb;
			break;
        case kCentrePattern:
            returnFloat = fCentrePattern;
            break;
        case kCentreGain:
            returnFloat = fCentreGain;
            break;
        case kSubGain:
            returnFloat = fSubGain;
            break;
        case kFc:
            returnFloat = fFc;
            break;
        case kSurroundMode:
            returnFloat = fSurroundMode;
            break;
        case kSurroundPattern:
            returnFloat = fSurroundPattern;
            break;
        case kSurroundWidth:
            returnFloat = fSurroundWidth;
            break;
        case kSurroundGain:
            returnFloat = fSurroundGain;
            break;
        case kDecoderMode:
            returnFloat = fDecoderMode;
            break;
        case kChannelOrder:
            returnFloat = fChannelOrder;
            break;
            
            
        //HIDDEN PArameters for GUI Control
        case 102: //Bit Mode for GUI display
            returnFloat = bits;
            break;
        case 103:
            returnFloat = myDecoder.mode5x;
            break;
            
        default:
            break;
	}
	return returnFloat; //Returns the chosen Parameters value
}


//------------------------------------------------------------------------
void ClassicAmbiDec::getParameterName (VstInt32 index, char *label) //SET display value shown for Parameters
{
	switch (index)
	{
        case kMode :
			switch (myDecoder.Mode) {
				case 0 :
					strcpy(label, "XY");
					break;
				case 1 :
					strcpy(label, "MS");
					break;
			}
            break;
		case kWidth:
			strcpy(label, "Width");
			break;
		case kPattern:
			strcpy(label, "Pattern");
			break;
		case kRotate :
			strcpy(label, "Rotate");
			break;
		case kTilt:
			strcpy(label, "Tilt");
			break;
		case kTumble:
			strcpy(label, "Tumble");
			break;
		case kZoom:
			strcpy(label, "Zoom");
			break;
		case kZoomMethod:
			strcpy(label, "Zoom Method");
			break;
		case kRearVerb :
			strcpy(label, "RearVerb");
			break;
		case kHiVerb :
			strcpy(label, "HiVerb");
			break;
        case kCentrePattern:
            strcpy(label, "Ctr. Pattern");
            break;
        case kCentreGain:
            strcpy(label, "Ctr. Gain");
            break;
        case kSubGain:
            strcpy(label, "Sub. Gain");
            break;
        case kFc:
            strcpy(label, "Sub. Xover");
            break;
        case kSurroundMode:
            strcpy(label, "Sur. Mode");
            break;
        case kSurroundPattern:
            strcpy(label, "Sur. Pattern");
            break;
        case kSurroundWidth:
            strcpy(label, "Sur. Width");
            break;
        case kSurroundGain:
            strcpy(label, "Sur. Gain");
            break;
        case kDecoderMode:
            strcpy(label, "Dec. Mode");
            break;
        case kChannelOrder:
            strcpy(label, "Ch. Order");
            break;
            
        default:
            break;
	}
}


//------------------------------------------------------------------------
void ClassicAmbiDec::getParameterDisplay (VstInt32 index, char *text)   //GET display value shown for Parameters
{
	switch (index)
	{
        case kMode :
			switch (myDecoder.Mode) {
				case 0 :
					strcpy(text, "XY");
					break;
				case 1 :
					strcpy(text, "MS");
					break;
			}
            break;
		case kWidth:
			sprintf (text, "%.1f\u00B0", myDecoder.Width);
			break;
		case kPattern:
			if (myDecoder.Pattern<=0.125) {
				strcpy(text, "Fig-of-8");
			}
			else if (myDecoder.Pattern>0.125 && myDecoder.Pattern<=0.375) {
				strcpy(text, "Hyper-Card.");
			}
			else if (myDecoder.Pattern>0.375 && myDecoder.Pattern<=0.625) {
				strcpy(text, "Cardioid");
			}
			else if (myDecoder.Pattern>0.625 && myDecoder.Pattern<=0.875) {
				strcpy(text, "Sub-Card.");
			}
			else {
				strcpy(text, "Omni.");
			}
			break;
		case kRotate :
			sprintf (text, "%.1f\u00B0", myDecoder.Rotate);
			break;
		case kTilt:
			sprintf (text, "%.1f\u00B0", myDecoder.Tilt);
			break;
		case kTumble:
			sprintf (text, "%.1f\u00B0", myDecoder.Tumble);
			break;
		case kZoom:
			sprintf (text, "%.1f%%", myDecoder.Zoom);
			break;
		case kZoomMethod:
			switch (myDecoder.ZoomMethod) {
				case 0:
					strcpy(text, "Dominance");
					break;
				case 1:
					strcpy(text, "Press");
					break;
				case 2:
					strcpy(text, "Push");
					break;
				case 3:
					strcpy(text, "Focus");
					break;
				default:
					break;
			}
			break;
		case kRearVerb :
            if (myDecoder.RearVerb>-40) {
                sprintf (text, "%.2fdB", myDecoder.RearVerb);
            }
			else {
                strcpy(text, "Off");
            }
			break;
		case kHiVerb :
            if (myDecoder.HiVerb>-40) {
                sprintf (text, "%.2fdB", myDecoder.HiVerb);
            }
            else {
                strcpy(text, "Off");
            }
			break;
        case kCentrePattern:
            if (myDecoder.centrePattern<=0.125) {
				strcpy(text, "Fig-of-8");
			}
			else if (myDecoder.centrePattern>0.125 && myDecoder.centrePattern<=0.375) {
				strcpy(text, "Hyper-Card.");
			}
			else if (myDecoder.centrePattern>0.375 && myDecoder.centrePattern<=0.625) {
				strcpy(text, "Cardioid");
			}
			else if (myDecoder.centrePattern>0.625 && myDecoder.centrePattern<=0.875) {
				strcpy(text, "Sub-Card.");
			}
			else {
				strcpy(text, "Omni.");
			}
            break;
        case kCentreGain:
            sprintf (text, "%.2fdB", myDecoder.centreGain);
            break;
        case kSubGain:
            sprintf (text, "%.2fdB", myDecoder.subGain);
            break;
        case kFc:
            sprintf (text, "%dHz", myDecoder.Fc);
            break;
        case kSurroundMode:
            switch (myDecoder.surMode) {
				case 0 :
					strcpy(text, "XY");
					break;
				case 1 :
					strcpy(text, "MS");
					break;
			}
            break;
        case kSurroundPattern:
            if (myDecoder.surPattern<=0.125) {
				strcpy(text, "Fig-of-8");
			}
			else if (myDecoder.surPattern>0.125 && myDecoder.surPattern<=0.375) {
				strcpy(text, "Hyper-Card.");
			}
			else if (myDecoder.surPattern>0.375 && myDecoder.surPattern<=0.625) {
				strcpy(text, "Cardioid");
			}
			else if (myDecoder.surPattern>0.625 && myDecoder.surPattern<=0.875) {
				strcpy(text, "Sub-Card.");
			}
			else {
				strcpy(text, "Omni.");
			}
            break;
        case kSurroundWidth:
            sprintf (text, "%.1f\u00B0", myDecoder.surWidth);
            break;
        case kSurroundGain:
            sprintf (text, "%.2fdB", myDecoder.surGain);
            break;
        case kDecoderMode:
            switch (myDecoder.decoderMode) {
				case 2 :
					strcpy(text, "Stereo");
					break;
				case 3 :
					strcpy(text, "2.1");
					break;
                case 4 :
					strcpy(text, "Quad");
					break;
                case 5 :
					strcpy(text, "5.0");
					break;
                case 6 :
					strcpy(text, "5.1");
					break;
			}
            break;
        case kChannelOrder:
            switch (myDecoder.channelOrder) {
				case 0 :
					strcpy(text, "Natural");
					break;
				case 1 :
					strcpy(text, "5.1");
					break;
			}
            break;
            
        default:
            break;
	}
}



//------------------------------------------------------------------------
void ClassicAmbiDec::getParameterLabel (VstInt32 index, char *label)    // Labels shown for Parameters
{
	switch (index)
	{
        case kMode :
			strcpy(label, "Microphones");
			break;
		case kWidth:
			strcpy(label, "Degrees");
			break;
		case kPattern:
			strcpy(label, "Omni");
			break;
		case kRotate :
			strcpy(label, "Degrees");
			break;
		case kTilt:
			strcpy(label, "Degrees");
			break;
		case kTumble:
			strcpy(label, "Degrees");
			break;
		case kZoom:
			strcpy(label, "Percentage");
			break;
		case kZoomMethod:
			strcpy(label, "Selection");
			break;
		case kRearVerb :
			strcpy(label, "dB");
			break;
		case kHiVerb :
			strcpy(label, "dB");
			break;
        case kCentrePattern:
            strcpy(label, "Omni");
            break;
        case kCentreGain:
            strcpy(label, "dB");
            break;
        case kSubGain:
            strcpy(label, "dB");
            break;
        case kFc:
            strcpy(label, "Hz");
            break;
        case kSurroundMode:
            strcpy(label, "Microphones");
            break;
        case kSurroundPattern:
            strcpy(label, "Omni");
            break;
        case kSurroundWidth:
            strcpy(label, "Degrees");
            break;
        case kSurroundGain:
            strcpy(label, "dB");
            break;
        case kDecoderMode:
            strcpy(label, "Speakers");
            break;
        case kChannelOrder:
            strcpy(label, "Output");
            break;
	}
}



//------------------------------------------------------------------------
bool ClassicAmbiDec::getEffectName (char* name) // Tha NAME of the effect
{
	strcpy (name, "Classic Ambisonics Decoder");
	return true;
}



//------------------------------------------------------------------------
bool ClassicAmbiDec::getProductString (char* text)  // The PRODUCT name
{
	strcpy (text, "Classic Ambisonics Decoder");
	return true;
}



//------------------------------------------------------------------------
bool ClassicAmbiDec::getVendorString (char* text)   // Vendor (Creator/Publisher)
{
	strcpy (text, "Martin J. Morrell");
	return true;
}


//------------------------------------------------------------------------
VstInt32 ClassicAmbiDec::getVendorVersion () 
{
    return VERSION;
}



//------------------------------------------------------------------------
void ClassicAmbiDec::setSampleRate(float sampleRate)
{
    myDecoder.Fs = (int)sampleRate;
    myDecoder.filterCoefs();
}



//---------------------------------------------------------------------------
void ClassicAmbiDec::processReplacing (float** inputs, float** outputs, VstInt32 sampleFrames) //The part that does some actual DSP. This section takes the input audio and gives the output audio back.
{
	while (--sampleFrames >= 0) //Do this process if the audio is running
	{
		//Set the internal B-Format values as doubles.
        double w, x, y, z;
        switch (numberInputs) {
            case 3:
            {
                w = (double) *inputs[0]++;
                x = (double) *inputs[1]++;
                y = (double) *inputs[2]++;
                z = 0;
                break;
            }
                
            case 4:
            {
                w = (double) *inputs[0]++;
                x = (double) *inputs[1]++;
                y = (double) *inputs[2]++;
                z = (double) *inputs[3]++;
                break;
            }
                
            default:
            {
                w = 0;
                x = 0;
                y = 0;
                z = 0;
                break;
            }
        }

		
        int numOut;
        numOut = myDecoder.processDecoder(w, x, y, z); //Process B-Format

        if (numOut<numberOutputs){  //Zero up extra outputs
            for (int i=0; i<numOut; i++)    
                *outputs[i]++ = float(myDecoder.output[i]);
            for (int i=numOut; i<numberOutputs; i++)
                *outputs[i]++ = 0.f;
        }
        else if (numOut==numberOutputs){    //Number of decoder outputs matches channel outputs
            for (int i=0; i<numOut; i++)
                *outputs[i]++ = float(myDecoder.output[i]);
        }
        else{   //Only use available outputs
            for (int i=0; i<numberOutputs; i++)
                *outputs[i]++ = float(myDecoder.output[i]);
        }
	}
}


//---------------------------------------------------------------------------
void ClassicAmbiDec::processDoubleReplacing(double **inputs, double **outputs, VstInt32 sampleFrames) //The part that does some actual DSP. This section takes the input audio and gives the output audio back.
{
	while (--sampleFrames >= 0) //Do this process if the audio is running
	{
		//Set the internal B-Format values as doubles.
        double w, x, y, z;
        switch (numberInputs) {
            case 3:
            {
                w = *inputs[0]++;
                x = *inputs[1]++;
                y = *inputs[2]++;
                z = 0;
                break;
            }
                
            case 4:
            {
                w = *inputs[0]++;
                x = *inputs[1]++;
                y = *inputs[2]++;
                z = *inputs[3]++;
                break;
            }
                
            default:
            {
                w = 0;
                x = 0;
                y = 0;
                z = 0;
                break;
            }
        }
        
		
        int numOut;
        numOut = myDecoder.processDecoder(w, x, y, z); //Process B-Format
        
        if (numOut<numberOutputs){  //Zero up extra outputs
            for (int i=0; i<numOut; i++)
                *outputs[i]++ = myDecoder.output[i];
            for (int i=numOut; i<numberOutputs; i++)
                *outputs[i]++ = 0.0;
        }
        else if (numOut==numberOutputs){    //Number of decoder outputs matches channel outputs
            for (int i=0; i<numOut; i++)
                *outputs[i]++ = myDecoder.output[i];
        }
        else{   //Only use available outputs
            for (int i=0; i<numberOutputs; i++)
                *outputs[i]++ = myDecoder.output[i];
        }
	}
}