view Source/ClassicAmbiDec.cpp @ 13:989865d55c73 tip

Commit.
author martinm_home <martin.morrell@eecs.qmul.ac.uk>
date Thu, 27 Sep 2012 23:30:29 +0100
parents 87dc3d84c120
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];
        }
	}
}