view Source/SoundField.cpp @ 6:503cbcdd0b2a

Working now.
author martinm_home <martin.morrell@eecs.qmul.ac.uk>
date Mon, 10 Sep 2012 14:03:14 +0100
parents e85bd6381a58
children d967dd1eafe8
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 ()
{
    //Define name if all programs are to be the same
    
}

//-----------------------------------------------------------------------------
SoundField::SoundField (audioMasterCallback audioMaster)
: AudioEffectX (audioMaster, 1, kNumParameters)
{	
	// init
	programs = new SoundFieldProgram[numPrograms];
    
    
    //	if (programs)
    //		setProgram (0);
	
    //Set the number of input and output channels
	setNumInputs (4);	// 4 Channel Classic B-Format Input
	setNumOutputs (2);	// MAX_CHANNELS 5.1 Output 
    
    
    // We initialize the arrangements to default values.
	// Nevertheless, the host should modify them via
	// appropriate calls to setSpeakerArrangement.
	//allocateArrangement (&plugInput, MAX_CHANNELS);
	//plugInput->type = kSpeakerArr51;
    
	//allocateArrangement (&plugOutput, 2); // MAX_CHANNELS, now 2 for stereo
	//plugOutput->type = kSpeakerArrStereo; // kSpeakerArr51, now set output to stereo
    
    
	
	setUniqueID ('MMa2');	// this should be unique, use the Steinberg web page for plugin Id registration
    
    
    if(setProcessPrecision(kVstProcessPrecision64)){
        setProcessPrecision(kVstProcessPrecision64);
        bits=64;
    }
    else {
        bits=32;
    }
    
    
    
	//Load GUI
    extern AEffGUIEditor* createEditor (AudioEffectX*);
	setEditor (createEditor (this));
    
    
	resume ();		// flush buffer
    
    canProcessReplacing(); //Plugin can use process replacing 
    noTail ();
	
    //Default Program Names
    vst_strncpy (programs[0].name, "Default",kVstMaxProgNameLen);
    
    vst_strncpy (programName, "Default", kVstMaxProgNameLen);	// default program name
    

    //  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;
	
	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.outputL=0.0;
    myDecoder.outputR=0.0;
    myDecoder.outputC=0.0;
    myDecoder.outputS=0.0;
    myDecoder.outputSL=0.0;
    myDecoder.outputSR=0.0;
    myDecoder.surMode=0;
    myDecoder.surPattern=0.5;
    myDecoder.surWidth=60.0;
    myDecoder.subGain=0.0;
    myDecoder.centrePattern=0.5;
    myDecoder.centreGain=0.0;
    myDecoder.subGain=0.0;
    myDecoder.Fs = sampleRate;
    myDecoder.Fc = 120;
    myDecoder.filterCoefs();
    myDecoder.decoderMode=0; //Default mode to user set output, let host call over it.
}


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

void SoundField::close()
{
}


void SoundField::open()
{
}



//------------------------------------------------------------------------
//bool SoundField::getSpeakerArrangement (VstSpeakerArrangement** pluginInput, VstSpeakerArrangement** pluginOutput)
//{
//	*pluginInput  = plugInput;
//	*pluginOutput = plugOutput;
//	return true;
//}

//------------------------------------------------------------------------
bool SoundField::setSpeakerArrangement (VstSpeakerArrangement* pluginInput,
                                        VstSpeakerArrangement* pluginOutput)
{   
    if (pluginOutput->type == kSpeakerArrStereo)
        {
        myDecoder.decoderMode=2;
	}
	else if (pluginOutput->type == kSpeakerArr40Cine)
	{
        myDecoder.decoderMode=4;
	}
    else if (pluginOutput->type == kSpeakerArr50 )
	{
        myDecoder.decoderMode=5;
	}
    else if (pluginOutput->type == kSpeakerArr51 )
	{
        myDecoder.decoderMode=6;
	}
    else
    {
        myDecoder.decoderMode=0; //Unknown speaker layout type, user will get drop down menu.
    }
    
    
	return true;
}


//------------------------------------------------------------------------
void SoundField::setProgram (VstInt32 program) //Host to SET the Program
{
    curProgram = program; //Change the curProgram value
}


//------------------------------------------------------------------------
void	SoundField::setProgramName(char *name) //SET the Program name
{ 
	strcpy(programs[curProgram].name, name); //Host SETS the Program[].name
}


//------------------------------------------------------------------------
void	SoundField::getProgramName(char *name) //GET the Program name
{ 
	strcpy(name, programs[curProgram].name); //Host GETS the Program[].name
}


//------------------------------------------------------------------------
bool	SoundField::getProgramNameIndexed (VstInt32 category, VstInt32 which, char* name)
{
	if ((unsigned int)which < kNumPrograms) //Check the ProgramNameIndexed is within range
	{
	    strcpy(name, programs[which].name);	//Host GETS the programs[].name
	    return true; //TRUE- ProgramNameIndexed does exits
	}
	return false; //FALSE- ProgramNameIndexed does not exits
}


//------------------------------------------------------------------------
SoundField::~SoundField () //clears protected variables
{
	if (programs)
		delete[] programs; 
    
}


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


//------------------------------------------------------------------------
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;
	}
    if (editor){
        ((AEffGUIEditor*)editor)->setParameter (index, value);
    }
}


//------------------------------------------------------------------------
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 102:
            returnFloat = bits;
            break;
        case 103:
            returnFloat = myDecoder.decoderMode;
            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;
	}
}


//------------------------------------------------------------------------
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:
			//sprintf (text, "%.1f", myDecoder.Pattern);
			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;
	}
	//kVstMaxParamStrLen
}


//------------------------------------------------------------------------
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;
	}
}


//------------------------------------------------------------------------
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::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=(double) *inputs[0]++;
		double x=(double) *inputs[1]++;
		double y=(double) *inputs[2]++;
		double z=(double) *inputs[3]++;
		
        if (myDecoder.decoderMode == 2) {//Stereo
            myDecoder.stereoDecoder(w, x, y, z);
            *outputs[0]++ = float(myDecoder.outputL);
            *outputs[1]++ = float(myDecoder.outputR);
        }
//        else if (myDecoder.decoderMode == 3) {//2.1
//            myDecoder.twoOneDecoder(w, x, y, z);
//            *outputs[0]++ = float(myDecoder.outputL);
//            *outputs[1]++ = float(myDecoder.outputR);
//            *outputs[2]++ = float(myDecoder.outputS);
//        }
        else if (myDecoder.decoderMode == 4) {//LRCS
            myDecoder.fiveOneDecoder(w, x, y, z);
            *outputs[0]++ = float(myDecoder.outputL);
            *outputs[1]++ = float(myDecoder.outputR);
            *outputs[2]++ = float(myDecoder.outputSL);
            *outputs[3]++ = float(myDecoder.outputSR);
        }
        else if (myDecoder.decoderMode == 5) {//5.0
            myDecoder.fiveOneDecoder(w, x, y, z);
            *outputs[0]++ = float(myDecoder.outputL);
            *outputs[1]++ = float(myDecoder.outputR);
            *outputs[2]++ = float(myDecoder.outputC);
            *outputs[3]++ = float(myDecoder.outputSL);
            *outputs[4]++ = float(myDecoder.outputSR);
        }
        else if (myDecoder.decoderMode == 6) {//5.1
            myDecoder.fiveOneDecoder(w, x, y, z);
            *outputs[0]++ = float(myDecoder.outputL);
            *outputs[1]++ = float(myDecoder.outputR);
            *outputs[2]++ = float(myDecoder.outputC);
            *outputs[3]++ = float(myDecoder.outputS);
            *outputs[4]++ = float(myDecoder.outputSL);
            *outputs[5]++ = float(myDecoder.outputSR);
        }
	}
}