view Source/SoundField.cpp @ 11:76e2e62635b4

Fixed the automation problem when a control isn't a child.
author martinm_home <martin.morrell@eecs.qmul.ac.uk>
date Thu, 27 Sep 2012 12:33:46 +0100
parents b5d48e9b9aea
children
line wrap: on
line source
//-------------------------------------------------------------------------------------------------------
// VST Plug-Ins SDK
// Version 2.4		$Date: 2006/11/13 09:08:27 $
//
// Category     : VST 2.x SDK Samples
// Filename     : adelay.cpp
// Created by   : Steinberg Media Technologies
// Description  : Simple Delay plugin (Mono->Stereo)
//
// © 2006, Steinberg Media Technologies, All Rights Reserved
//-------------------------------------------------------------------------------------------------------


#ifndef __SoundField__
#include "SoundField.h"
#include "Version.h"
#endif
//C++ Headers
#include <stdio.h>
#include <string.h>
#include <cmath>

//GUI Headers
#include "aeffguieditor.h"


//-----------------------------------------------------------------------------
SoundFieldProgram::SoundFieldProgram()
{
    
}



//-----------------------------------------------------------------------------
SoundField::SoundField (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
    numberInputs=4;
    numberOutputs=MAX_CHANNELS;
    
	setUniqueID ('MMca');	// this should be unique, use the Steinberg web page for plugin Id registration
    //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;
    }
    
    allocateArrangement (&myInputArrangement, 4);
    myInputArrangement->type = kSpeakerArr31Cine;
    

    //  Declare any variables to their default values
    //  Default Program Values if NOT using a bank of programs
    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 parameters
	myDecoder.Rotate=0.0;
	myDecoder.Tilt=0.0;
	myDecoder.Tumble=0.0;
	myDecoder.Zoom=0.0;
	myDecoder.ZoomMethod=0.0;
	myDecoder.Width=45.0;
	myDecoder.Pattern=0.5;
	myDecoder.Mode=0;
	myDecoder.RearVerb=-100;
	myDecoder.HiVerb=-100;
    myDecoder.surMode=0;
    myDecoder.surPattern=0.5;
    myDecoder.surWidth=60.0;
    myDecoder.surGain = 0.0;
    myDecoder.Fc = 120;
    myDecoder.centrePattern=0.5;
    myDecoder.centreGain=0.0;
    myDecoder.subGain=0.0;
    myDecoder.Fs = sampleRate;
    myDecoder.filterCoefs();
    myDecoder.decoderMode=2; //Default mode is Stereo
    myDecoder.channelOrder=1;
    myDecoder.mode5x=0;
    
    // Zero up decoder outputs as a safety
    myDecoder.outputL=0.0;
    myDecoder.outputR=0.0;
    myDecoder.outputC=0.0;
    myDecoder.outputS=0.0;
    myDecoder.outputSL=0.0;
    myDecoder.outputSR=0.0;
    

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

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

    
    //Load GUI
    extern AEffGUIEditor* createEditor (AudioEffectX*);
	setEditor (createEditor (this));
    
	resume ();		// flush buffer
    
    //Load Program0 default
    setProgram(0);
}


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

void SoundField::close()
{
}


void SoundField::open()
{
}





//------------------------------------------------------------------------
bool SoundField::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->numChannels = 4;
//                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:
        {
            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 SoundField::getSpeakerArrangement(VstSpeakerArrangement **pluginInput, VstSpeakerArrangement **pluginOutput)
{
	*pluginInput  = myInputArrangement;
	//*pluginOutput = myOutputArrangement;
    
    return true;
}



////------------------------------------------------------------------------
//bool SoundField::getInputProperties(VstInt32 index, VstPinProperties *properties)
//{
//    bool returnCode = false;
//    if (index < numberInputs)
//    {
//        sprintf (properties->label, "My %1d In", index + 1);
//        sprintf (properties->shortLabel, "%1d In", index + 1);
//        properties->flags = kVstPinIsActive;
//        returnCode = true;
//    }
//    return returnCode;
//}
//
//
////------------------------------------------------------------------------
//bool SoundField::getOutputProperties(VstInt32 index, VstPinProperties *properties)
//{
//    bool returnCode = false;
//    if (index < numberOutputs)
//    {
//        sprintf (properties->label, "My %1d Out", index + 1);
//        sprintf (properties->shortLabel, "%1d Out", index + 1);
//        properties->flags = kVstPinIsActive;
//        returnCode = true;
//    }
//    return (returnCode);
//}



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


//------------------------------------------------------------------------
SoundField::~SoundField () //clears protected variables
{
	deallocateArrangement (&myInputArrangement);
    //deallocateArrangement (&myOutputArrangement);
}


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


//------------------------------------------------------------------------
bool SoundField::getProgramNameIndexed(VstInt32 category, VstInt32 index, char *text)
{
    switch (myDecoder.decoderMode) {
        case 2:
            strcpy(text, programs[0][index].name);
            break;
        case 3:
            strcpy(text, programs[1][index].name);
            break;
        case 4:
            strcpy(text, programs[2][index].name);
            break;
        case 5:
            strcpy(text, programs[3][index].name);
            break;
        case 6:
            strcpy(text, programs[4][index].name);
            break;
            
        default:
            break;
    }

    

    return true;
}


//------------------------------------------------------------------------
void SoundField::setProgram(VstInt32 program)
{
    curProgram = program;
    
        switch (myDecoder.decoderMode) {
            case 2:
                setParameter(kMode, programs[0][program].mode);
                setParameter(kWidth, programs[0][program].width);
                setParameter(kPattern, programs[0][program].pattern);
                setParameter(kRearVerb, programs[0][program].rearVerb);
                setParameter(kHiVerb, programs[0][program].hiVerb);
                break;
            case 3:
                setParameter(kMode, programs[1][program].mode);
                setParameter(kWidth, programs[1][program].width);
                setParameter(kPattern, programs[1][program].pattern);
                setParameter(kRearVerb, programs[1][program].rearVerb);
                setParameter(kHiVerb, programs[1][program].hiVerb);
                setParameter(kSubGain, programs[1][program].subGain);
                setParameter(kFc, programs[1][program].fc);
                break;
            case 4:
                setParameter(kMode, programs[2][program].mode);
                setParameter(kWidth, programs[2][program].width);
                setParameter(kPattern, programs[2][program].pattern);
                setParameter(kSurroundMode, programs[2][program].surroundMode);
                setParameter(kSurroundWidth, programs[2][program].surroundWidth);
                setParameter(kSurroundPattern, programs[2][program].surroundPattern);
                setParameter(kSurroundGain, programs[2][program].surroundGain);
                break;
            case 5:
                if (program<3) {
                    myDecoder.mode5x=0;
                    
                    setParameter(kMode, programs[3][program].mode);
                    setParameter(kWidth, programs[3][program].width);
                    setParameter(kPattern, programs[3][program].pattern);
                    setParameter(kCentrePattern, programs[3][program].centrePattern);
                    setParameter(kCentreGain, programs[3][program].centreGain);
                    setParameter(kSurroundMode, programs[3][program].surroundMode);
                    setParameter(kSurroundWidth, programs[3][program].surroundWidth);
                    setParameter(kSurroundPattern, programs[3][program].surroundPattern);
                    setParameter(kSurroundGain, programs[3][program].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:
                if (program<3) {
                    myDecoder.mode5x=0;
                    
                    setParameter(kMode, programs[4][program].mode);
                    setParameter(kWidth, programs[4][program].width);
                    setParameter(kPattern, programs[4][program].pattern);
                    setParameter(kCentrePattern, programs[4][program].centrePattern);
                    setParameter(kCentreGain, programs[4][program].centreGain);
                    setParameter(kSubGain, programs[4][program].subGain);
                    setParameter(kFc, programs[4][program].fc);
                    setParameter(kSurroundMode, programs[4][program].surroundMode);
                    setParameter(kSurroundWidth, programs[4][program].surroundWidth);
                    setParameter(kSurroundPattern, programs[4][program].surroundPattern);
                    setParameter(kSurroundGain, programs[4][program].surroundGain);
                    if (editor){
                        ((AEffGUIEditor*)editor)->setParameter (103, 0.f);
                    }
                }
                else if (program==3) {
                    //Only set the sub
                    setParameter(kSubGain, programs[4][program].subGain);
                    setParameter(kFc, programs[4][program].fc);
                    myDecoder.mode5x=1;
                    if (editor){
                        ((AEffGUIEditor*)editor)->setParameter (103, 0.5f);
                    }
                }
                else if (program==4) {
                    //Only set the sub
                    setParameter(kSubGain, programs[4][program].subGain);
                    setParameter(kFc, programs[4][program].fc);
                    myDecoder.mode5x=2;
                    if (editor){
                        ((AEffGUIEditor*)editor)->setParameter (103, 1.f);
                    }
                }
                break;
                
            default:
                break;
        }
}



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







//------------------------------------------------------------------------
void SoundField::setParameter (VstInt32 index, float value) // SET Parameter value from host
{
	switch (index)
	{
        case kMode :
			fMode = value;
			if (value<=0.5f) {
				myDecoder.Mode = 0;
			}
			else {
				myDecoder.Mode = 1;
			}
            break;
		case kWidth:
			fWidth = value;
			myDecoder.Width = (double)value*90;
			break;
		case kPattern:
			fPattern = 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 = value;
            if (value==0.0f) {
                myDecoder.RearVerb=-100;
            }
            else {
                myDecoder.RearVerb = -36+(double)value*36;
            }
			break;
		case kHiVerb :
			fHiVerb = value;
            if (value==0.0f) {
                myDecoder.HiVerb=-100;
            }
            else {
                myDecoder.HiVerb= -36+(double)value*36;
            }
			break;
        case kCentrePattern:
            fCentrePattern = value;
			myDecoder.centrePattern = (double)value;
            break;
        case kCentreGain:
            fCentreGain = value;
			myDecoder.centreGain = ((double)value*24-18);
            break;
        case kSubGain:
            fSubGain = value;
			myDecoder.subGain = ((double)value*24-18);
            break;
        case kFc:
            fFc = value;
			myDecoder.Fc = (int)((value*220)+20);
            myDecoder.filterCoefs();
            break;
        case kSurroundMode:
            fSurroundMode = value;
            if (value<=0.5f) {
				myDecoder.surMode = 0;
			}
			else {
				myDecoder.surMode = 1;
			}
            break;
        case kSurroundPattern:
            fSurroundPattern = value;
			myDecoder.surPattern = (double)value;
            break;
        case kSurroundWidth:
            fSurroundWidth = value;
			myDecoder.surWidth = (double)value*90;
            break;
        case kSurroundGain:
            fSurroundGain = value;
			myDecoder.surGain = ((double)value*24-18);
            break;
        case kDecoderMode:
            fDecoderMode = value;
            if (value<=0.125f) {
//                if (myDecoder.channelOrder==0) {
//                    setNumOutputs(2);
//                    allocateArrangement (&myOutputArrangement, 2);
//                    myOutputArrangement->type = kSpeakerArrStereo;
//                    setNumInputs(4);
//                    allocateArrangement (&myInputArrangement, 4);
//                    myInputArrangement->type = kSpeakerArr31Cine;
//                    ioChanged();
//                }
				myDecoder.decoderMode = 2; //Stereo
			}
			else if (value>0.125f && value<=0.375f) {
//                if (myDecoder.channelOrder==0) {
//                    setNumOutputs(3);
//                    allocateArrangement (&myOutputArrangement, 3);
//                    myOutputArrangement->type = kSpeakerArr30Music;
//                    setNumInputs(4);
//                    allocateArrangement (&myInputArrangement, 4);
//                    myInputArrangement->type = kSpeakerArr31Cine;
//                    ioChanged();
//                }
				myDecoder.decoderMode = 3; //2.1
			}
			else if (value>0.375f && value<=0.625f) {
//                if (myDecoder.channelOrder==0) {
//                    setNumOutputs(6);
//                    allocateArrangement (&myOutputArrangement, 4);
//                    myOutputArrangement->type = kSpeakerArr40Music;
//                    setNumInputs(4);
//                    allocateArrangement (&myInputArrangement, 4);
//                    myInputArrangement->type = kSpeakerArr31Cine;
//                    ioChanged();
//                }
				myDecoder.decoderMode = 4; //Quad
			}
			else if (value>0.625f && value<=0.875f) {
//                if (myDecoder.channelOrder==0) {
//                    setNumOutputs(5);
//                    allocateArrangement (&myOutputArrangement, 5);
//                    myOutputArrangement->type = kSpeakerArr50;
//                    setNumInputs(4);
//                    allocateArrangement (&myInputArrangement, 4);
//                    myInputArrangement->type = kSpeakerArr31Cine;
//                    ioChanged();
//                }
				myDecoder.decoderMode = 5; //5.0
			}
            else if (value>0.875f) {
//                if (myDecoder.channelOrder==0) {
//                    setNumOutputs(6);
//                    allocateArrangement (&myOutputArrangement, 6);
//                    myOutputArrangement->type = kSpeakerArr51;
//                    setNumInputs(4);
//                    allocateArrangement (&myInputArrangement, 4);
//                    myInputArrangement->type = kSpeakerArr31Cine;
//                    ioChanged();
//                }
				myDecoder.decoderMode = 6; //5.1
			}
            updateDisplay();
            break;
        case kChannelOrder:
            fChannelOrder = value;
			if (value<=0.5f) {
				myDecoder.channelOrder = 0; //Natural Outputs
//                setParameter(kDecoderMode, fDecoderMode);
			}
			else {
//                setNumOutputs(6);
//                allocateArrangement (&myOutputArrangement, 6);
//                myOutputArrangement->type = kSpeakerArr51;
//                setNumInputs(4);
//                allocateArrangement (&myInputArrangement, 4);
//                myInputArrangement->type = kSpeakerArr31Cine;
//                ioChanged();
                myDecoder.channelOrder = 1; //5.1 Outputs
			}
            break;
            
            
        default:
            break;
	}
    if (editor){
        ((AEffGUIEditor*)editor)->setParameter (index, value);
    }
    if (index==kDecoderMode) {
        setProgram(curProgram);
    }
}


//------------------------------------------------------------------------
float SoundField::getParameter (VstInt32 index) // GET the value of the parameter
{
	float returnFloat;    //Define a float to output
    
    // Use a switch when more than 1 parameter
	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 SoundField::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 SoundField::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 SoundField::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 SoundField::getEffectName (char* name) // Tha NAME of the effect
{
	strcpy (name, "Classic Ambisonics Decoder");
	return true;
}


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


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


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



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



//---------------------------------------------------------------------------
void SoundField::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){
            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){
            for (int i=0; i<numOut; i++)
                *outputs[i]++ = float(myDecoder.output[i]);
        }
        else{
            for (int i=0; i<numberOutputs; i++)
                *outputs[i]++ = float(myDecoder.output[i]);
        }
	}
}


//---------------------------------------------------------------------------
void SoundField::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){
            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){
            for (int i=0; i<numOut; i++)
                *outputs[i]++ = myDecoder.output[i];
        }
        else{
            for (int i=0; i<numberOutputs; i++)
                *outputs[i]++ = myDecoder.output[i];
        }
	}
}