Hello everyone. In my quest to develop a nice little suite of UGens, I wrote this little bash script and thought I might share it here in case anyone else finds it useful.
I found that I really wanted a simple script that would automate adding a script to my repo, create the necessary structure and all cpp and sc-files and then in the end update CMakeLists.txt with the new files / plugins at the end and so I wrote this add_plugin
script.
This script expects that you are running it from the root of the repo and takes one argument which is the name of the plugin.
Example:
./add_plugin FunkyWahWah
This will create the directory FunkWahWah in plugins
containing all the necessary files for a plugin (FunkyWahWah.cpp
, FunkyWahWah.hpp
, FunkyWahWah.schelp
, FunkyWahWah.sc
). After generating the files, it adds them to the CMakeLists.txt file so that they are correctly compiled by CMake.
The script
#!/bin/bash
#########################
# add_plugin
# Generate plugin template including help file, hpp/cpp pair and the necessary supercollider class
#########################
PLUGIN_AUTHOR="Mads Kjeldgaard"
AUTHOR_EMAIL="mads@notam.no"
PLUGIN_NAME=$1
TARGET_FOLDER=plugins/$PLUGIN_NAME
if [[ -z $PLUGIN_NAME ]]; then
echo "You need to specify Plugin name as first argument"
exit 1
fi
function init(){
if [[ -d $TARGET_FOLDER ]]; then
echo "$TARGET_FOLDER already exists..." && \
exit 1
else
echo "Creating $TARGET_FOLDER..."
mkdir "$TARGET_FOLDER" && \
welcome && \
echo "--------------------" && \
generate_files && \
echo "--------------------" && \
exit 0
fi
}
function generate_files(){
generate_sc_class && \
generate_help && \
generate_hpp && \
generate_cpp && \
add_to_cmakelists && \
echo "Done generating files..." && \
exit 0
}
function generate_help(){
# Help file
echo "Gerating help file for $PLUGIN_NAME ..."
echo "class:: $PLUGIN_NAME
summary:: A plugin developed by Notam
related:: TODO
categories:: UGens>TODO
description::
This plugin is a part of notamplugins, a collection of SuperCollider plugins developed by Notam, the Norwegian center for technology and art.
classmethods::
method::ar, kr
argument::TODO
argument::TODO
examples::
code::
{ $PLUGIN_NAME.ar(/* TODO */) }.play
::
" >> $TARGET_FOLDER/$PLUGIN_NAME.schelp
}
# SuperCollider class file
function generate_sc_class(){
echo "Generating SuperCollider class file"
echo "$PLUGIN_NAME : UGen {
*ar { |input, gain|
/* TODO */
^this.multiNew('audio', input, gain);
}
checkInputs {
/* TODO */
^this.checkValidInputs;
}
}
" >> $TARGET_FOLDER/$PLUGIN_NAME.sc
}
function generate_hpp(){
echo "Generating hpp file"
echo "// $PLUGIN_NAME.hpp
// $PLUGIN_AUTHOR ($AUTHOR_EMAIL)
#pragma once
#include \"SC_PlugIn.hpp\"
#include \"../Common/modulators.hpp\"
#include \"../Common/filters.hpp\"
#include \"../Common/allpass.hpp\"
namespace $PLUGIN_NAME {
class $PLUGIN_NAME : public SCUnit {
public:
$PLUGIN_NAME();
// Destructor
~$PLUGIN_NAME();
private:
// Calc function
void next(int nSamples);
};
} // namespace $PLUGIN_NAME
">> $TARGET_FOLDER/$PLUGIN_NAME.hpp
}
function generate_cpp(){
echo "Generating cpp file"
echo "// $PLUGIN_NAME.cpp
// $PLUGIN_AUTHOR ($AUTHOR_EMAIL)
#include \"SC_PlugIn.hpp\"
#include \"${PLUGIN_NAME}.hpp\"
InterfaceTable* ft;
namespace $PLUGIN_NAME {
$PLUGIN_NAME::$PLUGIN_NAME() {
mCalcFunc = make_calc_function<$PLUGIN_NAME, &$PLUGIN_NAME::next>();
next(1);
}
void $PLUGIN_NAME::next(int nSamples) {
const float* input = in(0);
const float* gain = in(1);
float* outbuf = out(0);
// simple gain function
for (int i = 0; i < nSamples; ++i) {
outbuf[i] = input[i] * gain[i];
}
}
} // namespace $PLUGIN_NAME
PluginLoad(${PLUGIN_NAME}UGens) {
// Plugin magic
ft = inTable;
registerUnit<$PLUGIN_NAME::$PLUGIN_NAME>(ft, \"$PLUGIN_NAME\", false);
}
" >> $TARGET_FOLDER/$PLUGIN_NAME.cpp
}
function add_to_cmakelists(){
if [[ -f "CMakeLists.txt" ]]; then
echo "Modifying CMakeLists.txt to add $PLUGIN_NAME as a target"
echo "# $PLUGIN_NAME
set(${PLUGIN_NAME}_cpp_files
$TARGET_FOLDER/$PLUGIN_NAME.hpp
$TARGET_FOLDER/$PLUGIN_NAME.cpp
)
set(${PLUGIN_NAME}_sc_files
$TARGET_FOLDER/$PLUGIN_NAME.sc
)
set(${PLUGIN_NAME}_schelp_files
$TARGET_FOLDER/$PLUGIN_NAME.schelp
)
sc_add_server_plugin(
\"Notam Plugins/$PLUGIN_NAME\" # desination directory
\"$PLUGIN_NAME\" # target name
\"\${${PLUGIN_NAME}_cpp_files}\"
\"\${${PLUGIN_NAME}_sc_files}\"
\"\${${PLUGIN_NAME}_schelp_files}\"
)
" >> CMakeLists.txt
else
echo "Could not find CMakeLists.txt"
fi
}
function welcome(){
echo "
add_plugin:
Generate plugin files
"
}
init