From a8dbed162c7d1fded8581d900b78110dc29a7f23 Mon Sep 17 00:00:00 2001 From: Wrong People Date: Fri, 25 Dec 2020 20:12:06 +0300 Subject: [PATCH] init --- .gitignore | 6 ++ CMakeLists.txt | 82 +++++++++++++++ LICENSE | 21 ++++ README.md | 0 resources/Info.plist.in | 34 +++++++ resources/vstplug.def | 3 + src/JustRepeat.cpp | 214 ++++++++++++++++++++++++++++++++++++++++ src/JustRepeat.h | 78 +++++++++++++++ src/main.cpp | 6 ++ 9 files changed, 444 insertions(+) create mode 100644 .gitignore create mode 100644 CMakeLists.txt create mode 100644 LICENSE create mode 100644 README.md create mode 100644 resources/Info.plist.in create mode 100644 resources/vstplug.def create mode 100644 src/JustRepeat.cpp create mode 100644 src/JustRepeat.h create mode 100644 src/main.cpp diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9528498 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.swp +*.bak +.idea +/cmake-build-debug +/cmake-build-release +/tmp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..cbd9bfb --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,82 @@ +project(JustRepeat) +cmake_minimum_required(VERSION 3.0.0) +set(CMAKE_COLOR_MAKEFILE ON) + +if(MSVC) + add_definitions(/D _CRT_SECURE_NO_WARNINGS) +endif() + +############################ +# API fix for Linux builds # +############################ + +if(UNIX AND NOT APPLE) + add_definitions( -D__cdecl= ) +endif() + +################# +# Build plug-in # +################# + +set(VSTSDK_PATH "${PROJECT_SOURCE_DIR}/../VST_SDK/VST2_SDK") +set(REASDK_PATH "${PROJECT_SOURCE_DIR}/../REA_SDK/jmde") + +set(VSTSDK_INCLUDE_DIR ${VSTSDK_PATH}) +set(REASDK_INCLUDE_DIR ${REASDK_PATH}) + +set(VSTSDK_PLUGIN_SOURCE + ${VSTSDK_PATH}/public.sdk/source/vst2.x/audioeffectx.cpp + ${VSTSDK_PATH}/public.sdk/source/vst2.x/audioeffect.cpp + ${VSTSDK_PATH}/public.sdk/source/vst2.x/vstplugmain.cpp + ${VSTSDK_PATH}/pluginterfaces/vst2.x/aeffectx.h +) + +file(GLOB_RECURSE JUSTREPEAT_SOURCE "src/*.cpp") +set(JUSTREPEAT_SOURCE + ${JUSTREPEAT_SOURCE} + resources/vstplug.def + ${VSTSDK_PLUGIN_SOURCE} +) + +add_library(JustRepeat MODULE ${JUSTREPEAT_SOURCE}) + +include_directories(src) + +include_directories(${VSTSDK_INCLUDE_DIR}) +include_directories(${REASDK_INCLUDE_DIR}) + +target_link_libraries(JustRepeat ${VSTSDK_LIBRARIES}) + +###################################### +# Set OSX-specific bundle properties # +###################################### + +set_target_properties(JustRepeat PROPERTIES + BUNDLE true + BUNDLE_EXTENSION "vst" + XCODE_ATTRIBUTE_WRAPPER_EXTENSION "vst" + MACOSX_BUNDLE_INFO_PLIST "resources/Info.plist.in" + MACOSX_BUNDLE_BUNDLE_NAME "JustRepeat" + MACOSX_BUNDLE_GUI_IDENTIFIER "com.WrongPeople.JustRepeat" + MACOSX_BUNDLE_ICON_FILE "" + MACOSX_BUNDLE_SHORT_VERSION_STRING "1.0.0" + MACOSX_BUNDLE_COPYRIGHT "WrongPeople © 2020" +) + +#################### +# Set Install Path # +#################### + +if(APPLE) + install(TARGETS JustRepeat + DESTINATION "$ENV{HOME}/Library/Audio/Plug-Ins/VST" + ) +elseif(WIN32) + install(TARGETS JustRepeat + DESTINATION "/Program Files/VstPlugins/" + ) +elseif(UNIX AND NOT APPLE) #Linux + install(TARGETS JustRepeat + DESTINATION "/usr/lib/lxvst" + ) +endif() diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..8d65800 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2020 WrongPeople + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..e69de29 diff --git a/resources/Info.plist.in b/resources/Info.plist.in new file mode 100644 index 0000000..f61f8fa --- /dev/null +++ b/resources/Info.plist.in @@ -0,0 +1,34 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + ${MACOSX_BUNDLE_EXECUTABLE_NAME} + CFBundleGetInfoString + ${MACOSX_BUNDLE_INFO_STRING} + CFBundleIconFile + ${MACOSX_BUNDLE_ICON_FILE} + CFBundleIdentifier + ${MACOSX_BUNDLE_GUI_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleLongVersionString + ${MACOSX_BUNDLE_LONG_VERSION_STRING} + CFBundleName + ${MACOSX_BUNDLE_BUNDLE_NAME} + CFBundlePackageType + BNDL + CFBundleShortVersionString + ${MACOSX_BUNDLE_SHORT_VERSION_STRING} + CFBundleSignature + ???? + CFBundleVersion + ${MACOSX_BUNDLE_BUNDLE_VERSION} + CSResourcesFileMapped + + NSHumanReadableCopyright + ${MACOSX_BUNDLE_COPYRIGHT} + + diff --git a/resources/vstplug.def b/resources/vstplug.def new file mode 100644 index 0000000..a3c4af7 --- /dev/null +++ b/resources/vstplug.def @@ -0,0 +1,3 @@ +EXPORTS + VSTPluginMain + main=VSTPluginMain \ No newline at end of file diff --git a/src/JustRepeat.cpp b/src/JustRepeat.cpp new file mode 100644 index 0000000..da0a6bd --- /dev/null +++ b/src/JustRepeat.cpp @@ -0,0 +1,214 @@ +#include "JustRepeat.h" + + +const double JustRepeat::DIVS[NUM_DIVS] = { + 1, 1.5, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, +}; + + +JustRepeat::JustRepeat(audioMasterCallback audioMaster) : AudioEffectX(audioMaster, 1, NUM_PARAMS) { + barTime = sampleRate * 4; + + setNumInputs(2); + setNumOutputs(2); + + setUniqueID('JRpt'); + + resume(); +} + + +void JustRepeat::resume() { + AudioEffectX::resume(); +} + + +void JustRepeat::setParameter(VstInt32 index, float value) { + switch(index) { + case PARAM_REPEAT: + value = value < 0.5f ? 0.f : 1.f; + if(pRepeat != value) { + if(value == 1) { + barTime = 240.0 / getTempo(); + recSamples = (int) floor(barTime * sampleRate); + if(recSamples > BUF_LEN) + recSamples = BUF_LEN; + setPlaySamples(); + recPos = 0; + state = REC; + } + else { + state = STOP; + } + } + pRepeat = value; + break; + case PARAM_LENGTH: + if(pLength != value) { + div = (int) roundf(value * (float) (NUM_DIVS - 1)); + setPlaySamples(); + } + pLength = value; + break; + default: + break; + } +} + + +float JustRepeat::getParameter(VstInt32 index) { + float v = 0; + + switch(index) { + case PARAM_REPEAT: + v = pRepeat; + break; + case PARAM_LENGTH: + v = pLength; + break; + default: + break; + } + + return v; +} + + +void JustRepeat::getParameterName(VstInt32 index, char *label) { + switch(index) { + case PARAM_REPEAT: + strcpy(label, "Repeat"); + break; + case PARAM_LENGTH: + strcpy(label, "Length"); + break; + default: + strcpy(label, ""); + break; + } +} + + +void JustRepeat::getParameterDisplay(VstInt32 index, char *text) { + switch(index) { + case PARAM_REPEAT: + strcpy(text, pRepeat < 0.5f ? "Off" : "On"); + break; + case PARAM_LENGTH: + strcpy(text, "1/"); + float2string( + (float) DIVS[div], + text + 2, + (double) (int) DIVS[div] == DIVS[div] ? (DIVS[div] < 10 ? 1 : 2) : 3 + ); + break; + default: + break; + } +} + + +void JustRepeat::getParameterLabel(VstInt32 index, char *label) { + strcpy(label, ""); +} + + +bool JustRepeat::getEffectName(char *name) { + strcpy(name, "JustRepeat"); + return true; +} + + +bool JustRepeat::getProductString(char *text) { + strcpy(text, "JustRepeat"); + return true; +} + + +bool JustRepeat::getVendorString(char *text) { + strcpy(text, "WrongPeople"); + return true; +} + + +void JustRepeat::processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames) { + for(int s = 0; s < sampleFrames; s++) { + + if(state == STOP) { + processBypass(s, inputs, outputs); + continue; + } + + if(state == REC) { + + if(recPos < playSamples) { + processRec(s, inputs, outputs); + processBypass(s, inputs, outputs); + recPos++; + } + else { + playPos = 0; + totalPlayPos = 0; + state = PLAY; + } + + } + + if(state == PLAY) { + + if(recPos < recSamples) { + processRec(s, inputs, outputs); + recPos++; + } + + processPlay(s, inputs, outputs); + + playPos++; + totalPlayPos++; + + if(playPos >= playSamples) + playPos = 0; + + if(totalPlayPos >= recSamples) + totalPlayPos = 0; + + } + + } +} + + +inline void JustRepeat::setPlaySamples() { + int samples = (int) floor((barTime / DIVS[div]) * sampleRate); + + if(state == PLAY && playPos >= samples) { + playPos = playPos % samples; + } + + playSamples = samples; +} + + +inline void JustRepeat::processBypass(int s, float **inputs, float **outputs) { + outputs[0][s] = inputs[0][s]; + outputs[1][s] = inputs[1][s]; +} + + +inline void JustRepeat::processRec(int s, float **inputs, float **outputs) { + buf[0][recPos] = inputs[0][s]; + buf[1][recPos] = inputs[1][s]; +} + + +inline void JustRepeat::processPlay(int s, float **inputs, float **outputs) { + outputs[0][s] = buf[0][playPos]; + outputs[1][s] = buf[1][playPos]; +} + + +inline double JustRepeat::getTempo() { + static VstTimeInfo *timeInfo; + timeInfo = getTimeInfo(kVstTempoValid); + return timeInfo != nullptr ? timeInfo->tempo : 60.0; +} \ No newline at end of file diff --git a/src/JustRepeat.h b/src/JustRepeat.h new file mode 100644 index 0000000..a34089d --- /dev/null +++ b/src/JustRepeat.h @@ -0,0 +1,78 @@ +#pragma once + +#include +#include +#include + +#include "public.sdk/source/vst2.x/audioeffectx.h" + + +#define BUF_LEN (44100 * 32) +#define NUM_DIVS 13 + + +class JustRepeat : public AudioEffectX { + + enum Param { + PARAM_REPEAT, + PARAM_LENGTH, + NUM_PARAMS + }; + + enum State { STOP, REC, PLAY }; + +public: + + explicit JustRepeat(audioMasterCallback audioMaster); + + virtual void setParameter(VstInt32 index, float value); + + virtual float getParameter(VstInt32 index); + + virtual void getParameterLabel(VstInt32 index, char *label); + + virtual void getParameterDisplay(VstInt32 index, char *text); + + virtual void getParameterName(VstInt32 index, char *text); + + virtual void resume(); + + virtual bool getEffectName(char *name); + + virtual bool getVendorString(char *text); + + virtual bool getProductString(char *text); + + virtual VstInt32 getVendorVersion() { return 1000; } + + virtual VstPlugCategory getPlugCategory() { return kPlugCategEffect; } + + virtual void processReplacing(float **inputs, float **outputs, VstInt32 sampleFrames); + + +protected: + + static const double DIVS[NUM_DIVS]; + + float pRepeat = 0; + float pLength = 0; + + int div = 0; + + int state = STOP; + int recPos = 0; + int playPos = 0; + int recSamples = 0; + int playSamples = 0; + int totalPlayPos = 0; + double barTime; + + float buf[2][BUF_LEN]{}; + + inline void setPlaySamples(); + inline void processBypass(int s, float **inputs, float **outputs); + inline void processRec(int s, float **inputs, float **outputs); + inline void processPlay(int s, float **inputs, float **outputs); + inline double getTempo(); + +}; diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..a48f2f8 --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,6 @@ +#include "JustRepeat.h" + +AudioEffect *createEffectInstance(audioMasterCallback audioMaster) { + return new JustRepeat(audioMaster); +} +