Mercurial > hg > ambi-plugin
view Source/SoundField.cpp @ 0:2fa9c10568d1
Initial setup.
author | martinm_home <martin.morrell@eecs.qmul.ac.uk> |
---|---|
date | Tue, 14 Aug 2012 09:34:15 +0100 |
parents | |
children | e85bd6381a58 |
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" #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 //version = 2300; // 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.centreOrder=1; myDecoder.centrePattern=0.5; myDecoder.centreGain=0.0; myDecoder.subGain=0.0; myDecoder.decoderMode=2; myDecoder.Fs = sampleRate; myDecoder.Fc = 120; myDecoder.filterCoefs(); } 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 || !pluginInput) return false; bool result = true; // This plug-in can act on any speaker arrangement, // provided that there are the same number of inputs/outputs. // if (pluginInput->numChannels > MAX_CHANNELS) // { // // This plug-in can't have so many channels. So we answer // // false, and we set the input arrangement with the maximum // // number of channels possible // result = false; // allocateArrangement (&plugInput, MAX_CHANNELS); // plugInput->type = kSpeakerArr51; // } // else // { // matchArrangement (&plugInput, pluginInput); // } // if (pluginOutput->numChannels != plugInput->numChannels) if (pluginOutput->numChannels <= MAX_CHANNELS) { // This plug-in only deals with symetric IO configurations... // result = false; // matchArrangement (&plugOutput, plugInput); myDecoder.decoderMode=pluginOutput->numChannels; } else { // matchArrangement (&plugOutput, pluginOutput); myDecoder.decoderMode=6; } return result; } 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; deallocateArrangement (&plugInput); deallocateArrangement (&plugOutput); } //------------------------------------------------------------------------ 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 50: returnFloat = bits; 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, "Precentage"); 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, "SoundField Decoder"); return true; } //------------------------------------------------------------------------ bool SoundField::getProductString (char* text) // The PRODUCT name { strcpy (text, "SoundField 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); } } }