vst2sdk

A clean room reverse engineering project for the VST 2.x interface
Log | Files | Refs | README | LICENSE

audioeffectx.cpp (8008B)


      1 /*
      2  * Copyright 2024 Michael Fabian 'Xaymar' Dirks <info@xaymar.com>
      3  * Copyright 2024 Steinberg Media Technologies GmbH
      4  *
      5  * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
      6  *
      7  * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
      8  *
      9  * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
     10  *
     11  * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     14  */
     15 
     16 #include "audioeffectx.hpp"
     17 #include "vstkey.h"
     18 
     19 AudioEffectX::AudioEffectX(audioMasterCallback audioMaster, VstInt32 __unk00, VstInt32 __unk01) : AudioEffect(audioMaster, __unk00, __unk01)
     20 {
     21 	cEffect.processDoubleReplacing = [](AEffect* self, double** inputs, double** outputs, VstInt32 sampleFrames) { return reinterpret_cast<AudioEffectX*>(self->effect_data)->processDoubleReplacing(inputs, outputs, sampleFrames); };
     22 }
     23 
     24 AudioEffectX::~AudioEffectX() {}
     25 
     26 VstIntPtr AudioEffectX::control(VstInt32 opcode, VstInt32 param1, VstIntPtr param2, void* ptr, float value)
     27 {
     28 	switch (opcode) {
     29 	case audioEffectProcessEvents:
     30 		return processEvents((VstEvents*)ptr);
     31 	case audioEffectIsParameterAutomatable:
     32 		return canParameterBeAutomated(param1) ? 1 : 0;
     33 	case audioEffectConvertStringToParameter:
     34 		return string2parameter(param1, (char*)ptr) ? 1 : 0;
     35 	case audioEffectGetProgramNameIndexed:
     36 		return getProgramNameIndexed(static_cast<VstInt32>(value), param1, (char*)ptr) ? 1 : 0;
     37 	case audioEffectGetInputProperties:
     38 		return getInputProperties(param1, (VstPinProperties*)ptr);
     39 	case audioEffectGetOutputProperties:
     40 		return getOutputProperties(param1, (VstPinProperties*)ptr);
     41 	case audioEffectGetPlugCategory:
     42 		return (VstIntPtr)getPlugCategory();
     43 	case audioEffectSetSpeakerArrangement:
     44 		return setSpeakerArrangement((VstSpeakerArrangement*)param2, (VstSpeakerArrangement*)ptr);
     45 	case audioEffectBypass:
     46 		return setBypass(!!param2) ? 1 : 0;
     47 	case audioEffectGetEffectName:
     48 		return getEffectName((char*)ptr) ? 1 : 0;
     49 	case audioEffectGetVendorString:
     50 		return getVendorString((char*)ptr) ? 1 : 0;
     51 	case audioEffectGetProductString:
     52 		return getProductString((char*)ptr) ? 1 : 0;
     53 	case audioEffectGetVendorVersion:
     54 		return getVendorVersion();
     55 	case audioEffectVendorSpecific:
     56 		return vendorSpecific(param1, param2, ptr, value);
     57 	case audioEffectCanDo:
     58 		return canDo((char*)ptr);
     59 	case audioEffectGetTailSize:
     60 		return getGetTailSize();
     61 	case audioEffectGetParameterProperties:
     62 		return getParameterProperties(param1, (VstParameterProperties*)ptr) ? 1 : 0;
     63 	case audioEffectGetVSTVersion:
     64 		return cEffect.version;
     65 
     66 #if (!defined VST_VERSION_SUPPORT) || (VST_VERSION_SUPPORT >= kVstVersion_2100)
     67 	case audioEffectEditorKeyDown:
     68 		if (editor) {
     69 			VstKeyCode keycode{.character = param1, .virt = static_cast<unsigned char>(param2), .modifier = static_cast<unsigned char>(value)};
     70 			editor->onKeyDown(keycode);
     71 		}
     72 		return 0;
     73 	case audioEffectEditorKeyUp:
     74 		if (editor) {
     75 			VstKeyCode keycode{.character = param1, .virt = static_cast<unsigned char>(param2), .modifier = static_cast<unsigned char>(value)};
     76 			editor->onKeyUp(keycode);
     77 		}
     78 		return 0;
     79 	case audioEffectEditorKnobMode:
     80 		if (editor) {
     81 			editor->setKnobMode(param2) ? 1 : 0;
     82 		}
     83 		return 0;
     84 	case audioEffectMidiGetProgramName:
     85 		return getMidiProgramName(param1, (MidiProgramName*)ptr);
     86 	case audioEffectMidiGetCurrentProgram:
     87 		return getCurrentMidiProgram(param1, (MidiProgramName*)ptr);
     88 	case audioEffectMidiGetProgramCategory:
     89 		return getMidiProgramCategory(param1, (MidiProgramCategory*)ptr);
     90 	case audioEffectMidiHasProgramsChanged:
     91 		return hasMidiProgramsChanged(param1) ? 1 : 0;
     92 	case audioEffectMidiGetKeyName:
     93 		return getMidiKeyName(param1, (MidiKeyName*)ptr) ? 1 : 0;
     94 #endif
     95 
     96 #if (!defined VST_VERSION_SUPPORT) || (VST_VERSION_SUPPORT >= kVstVersion_2300)
     97 	case audioEffectGetSpeakerArrangement:
     98 		return getSpeakerArrangement((VstSpeakerArrangement**)param2, (VstSpeakerArrangement**)ptr);
     99 	case audioEffectStartProcessing:
    100 		return startProcess();
    101 	case audioEffectStopProcessing:
    102 		return stopProcess();
    103 #endif
    104 
    105 #if (!defined VST_VERSION_SUPPORT) || (VST_VERSION_SUPPORT >= kVstVersion_2400)
    106 	case audioEffectSetProcessingPrecision:
    107 		return setProcessPrecision(param1) ? 1 : 0;
    108 	case audioEffectMidiGetNumInputChannels:
    109 		return getNumMidiInputChannels();
    110 	case audioEffectMidiGetNumOutputChannels:
    111 		return getNumMidiOutputChannels();
    112 #endif
    113 	default:
    114 		return AudioEffect::control(opcode, param1, param2, ptr, value);
    115 	}
    116 }
    117 
    118 VstInt32 AudioEffectX::canHostDo(char* text)
    119 {
    120 	if (audioMaster)
    121 		return !!audioMaster(getAeffect(), audioMasterCanDo, 0, 0, text, 0);
    122 	return false;
    123 }
    124 
    125 bool AudioEffectX::beginEdit(VstInt32 paramIndex)
    126 {
    127 	if (audioMaster)
    128 		return !!audioMaster(getAeffect(), audioMasterBeginEdit, paramIndex, 0, 0, 0);
    129 	return false;
    130 }
    131 
    132 bool AudioEffectX::endEdit(VstInt32 paramIndex)
    133 {
    134 	if (audioMaster)
    135 		return !!audioMaster(getAeffect(), audioMasterEndEdit, paramIndex, 0, 0, 0);
    136 	return false;
    137 }
    138 
    139 bool AudioEffectX::ioChanged()
    140 {
    141 	if (audioMaster)
    142 		return !!audioMaster(getAeffect(), audioMasterIOChanged, 0, 0, 0, 0);
    143 	return false;
    144 }
    145 
    146 bool AudioEffectX::updateDisplay()
    147 {
    148 	if (audioMaster)
    149 		return !!audioMaster(getAeffect(), audioMasterUpdateDisplay, 0, 0, 0, 0);
    150 	return false;
    151 }
    152 
    153 bool AudioEffectX::sizeWindow(VstInt32 width, VstInt32 height)
    154 {
    155 	if (audioMaster)
    156 		return !!audioMaster(getAeffect(), audioMasterSizeWindow, width, height, 0, 0);
    157 	return false;
    158 }
    159 
    160 VstInt32 AudioEffectX::getCurrentProcessLevel()
    161 {
    162 	if (audioMaster)
    163 		return !!audioMaster(getAeffect(), audioMasterGetCurrentProcessLevel, 0, 0, 0, 0);
    164 	return 0;
    165 }
    166 
    167 bool AudioEffectX::getHostVendorString(char* text)
    168 {
    169 	if (audioMaster)
    170 		return !!audioMaster(getAeffect(), audioMasterGetVendorString, 0, 0, text, 0);
    171 	return false;
    172 }
    173 
    174 bool AudioEffectX::getHostProductString(char* text)
    175 {
    176 	if (audioMaster)
    177 		return !!audioMaster(getAeffect(), audioMasterGetProductString, 0, 0, text, 0);
    178 	return false;
    179 }
    180 
    181 VstInt32 AudioEffectX::getHostVendorVersion()
    182 {
    183 	if (audioMaster)
    184 		return !!audioMaster(getAeffect(), audioMasterGetVendorVersion, 0, 0, 0, 0);
    185 	return 0;
    186 }
    187 
    188 void AudioEffectX::canDoubleReplacing(bool value)
    189 {
    190 	if (value)
    191 		cEffect.flags |= AEffectFlagCanDoubleReplacing;
    192 	else
    193 		cEffect.flags &= ~AEffectFlagCanDoubleReplacing;
    194 }
    195 
    196 void AudioEffectX::noTail(bool value)
    197 {
    198 	if (value)
    199 		cEffect.flags |= AEffectFlagIsSilentOnSilence;
    200 	else
    201 		cEffect.flags &= ~AEffectFlagIsSilentOnSilence;
    202 }
    203 
    204 VstTimeInfo* AudioEffectX::getTimeInfo(VstInt32 filter)
    205 {
    206 	if (audioMaster) {
    207 		auto ptr = audioMaster(getAeffect(), audioMasterGetTimeInfo, 0, filter, 0, 0);
    208 		// Returned value should be a pointer to a VstTimeInfo.
    209 		return reinterpret_cast<VstTimeInfo*>(ptr);
    210 	}
    211 	return 0;
    212 }
    213 
    214 bool AudioEffectX::sendVstEventsToHost(VstEvents* events)
    215 {
    216 	if (audioMaster) {
    217 		audioMaster(getAeffect(), audioMasterProcessEvents, 0, 0, events, 0);
    218 	}
    219 	return 0;
    220 }