From f00479c725b05bfed7d450fd47f13e3dc7b8b6e2 Mon Sep 17 00:00:00 2001 From: Christian Colglazier Date: Sun, 23 Jan 2022 19:11:31 -0500 Subject: [PATCH] Documentation for creating new droplets --- README.md | 52 +++++++++++++++++++++++++++++++ create-new-droplet.sh | 33 ++++++++++++++++++++ src/droplets/template_droplet.cpp | 20 ++++++++++++ src/droplets/template_droplet.h | 50 +++++++++++++++++++++++++++++ src/menu.cpp | 4 ++- 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100755 create-new-droplet.sh create mode 100644 src/droplets/template_droplet.cpp create mode 100644 src/droplets/template_droplet.h diff --git a/README.md b/README.md index 8cd2d34..e16f281 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,55 @@ make lib && make ```sh make deploy ``` + +## Creating Droplets + +The Droplets firmware is based around writing modular code blocks called droplets. A droplet needs to support three states (full, left, right). Droplets should have an animated title bar that ideally interacts with the current state of the droplet. + +### Hardware Allocation + +#### Full Mode + +CTRL [1-4] +GATE IN [1-2] +GATE OUT 1 +AUDIO IN [1-4] +AUDIO OUT [1-4] +MIDI IN +MIDI OUT +CV OUT [1-2] + +#### Left Mode + +CTRL [1-2] +GATE IN 1 +GATE OUT 1 +AUDIO IN [1-2] +AUDIO OUT [1-2] +MIDI IN +MIDI OUT +CV OUT 1 + +#### Right Mode + +CTRL [3-4] +GATE IN 2 +AUDIO IN [3-4] +AUDIO OUT [3-4] +CV OUT 2 + +### Setting Up Code + +1. Create new c++ program and header file from the Droplet template. + +```sh +create-new-droplet.sh [Droplet Name] +``` + +2. Add a MenuState enum for the new droplet in the `menu_item.h` with the format of k[Droplet Name]. + +3. Add menu to the `menu.cpp` by creating a new AddItemEnd to the list with the MenuState and droplet name. + +4. Include the droplet header in the `main.h` file. + +5. In the GetDroplet function in `main.cpp` add a case for the new droplet to return a constructor. diff --git a/create-new-droplet.sh b/create-new-droplet.sh new file mode 100755 index 0000000..cac6ba7 --- /dev/null +++ b/create-new-droplet.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash + +function printHelp { + echo 'This bash script will create a new droplet. Please input the name for the droplet in PascalCase as a command line argument.' +} + +# Check for arguments +if [ $# -eq 0 ] + then + printHelp +fi + +# Setup Droplet names +dropletName=$1 +dropletNameWords=$(echo $dropletName | sed 's/\([A-Z][^A-Z]\)/ \1/g') +upper=$(echo ${dropletNameWords} | tr '[:lower:]' '[:upper:]') +upper="${upper// /_}" +lower=$(echo ${upper} | tr '[:upper:]' '[:lower:]') + +# Create copy from template +folder=$(dirname "$0") +headerFile="${folder}/src/droplets/${lower}_droplet.h" +cppFile="${folder}/src/droplets/${lower}_droplet.cpp" +cp ${folder}/src/droplets/template_droplet.cpp ${cppFile} +cp ${folder}/src/droplets/template_droplet.h ${headerFile} + +# Replace +sed -i "s/Template/${dropletName}/g" ${headerFile} +sed -i "s/Template/${dropletName}/g" ${cppFile} +sed -i "s/template/${lower}/g" ${headerFile} +sed -i "s/template/${lower}/g" ${cppFile} +sed -i "s/TEMPLATE/${upper}/g" ${headerFile} +sed -i "s/TEMPLATE/${upper}/g" ${cppFile} diff --git a/src/droplets/template_droplet.cpp b/src/droplets/template_droplet.cpp new file mode 100644 index 0000000..489de46 --- /dev/null +++ b/src/droplets/template_droplet.cpp @@ -0,0 +1,20 @@ +#include "template_droplet.h" + +TemplateDroplet::TemplateDroplet(DaisyPatch* m_patch, + DropletState m_state) : + Droplet(m_patch, + m_state) { +} + +void TemplateDroplet::Control() {} + +void TemplateDroplet::Process(AudioHandle::InputBuffer in, + AudioHandle::OutputBuffer out, + size_t size) { +} + +void TemplateDroplet::Draw() { + DrawName("Template"); +} + +void TemplateDroplet::UpdateStateCallback() {} diff --git a/src/droplets/template_droplet.h b/src/droplets/template_droplet.h new file mode 100644 index 0000000..8c608d0 --- /dev/null +++ b/src/droplets/template_droplet.h @@ -0,0 +1,50 @@ +#pragma once + +#ifndef DROPLETS_TEMPLATE_DROPLET_H_ +#define DROPLETS_TEMPLATE_DROPLET_H_ + +#include "daisysp.h" +#include "daisy_patch.h" + +#include "droplet.h" +#include "../util.h" + +class TemplateDroplet: public Droplet { +private: +public: + /* + * Constructor for a droplet. + * + * @param m_patch pointer to patch + * @param m_state droplet position + */ + TemplateDroplet(DaisyPatch*, DropletState); + + /* + * Processes user controls and inputs. + */ + void Control(); + + /* + * Processes audio input and outputs. + * + * @param in the audio inputs for the patch + * @param out the audio outputs for the patch + * @param size the number of inputs and outputs + */ + void Process(AudioHandle::InputBuffer in, + AudioHandle::OutputBuffer out, + size_t size); + + /* + * Processes information to be shown on the display. + */ + void Draw(); + + /* + * Runs when droplet state is updated. + */ + void UpdateStateCallback(); +}; + +#endif // DROPLETS_TEMPLATE_DROPLET_H_ diff --git a/src/menu.cpp b/src/menu.cpp index bf0457d..a205a16 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -139,8 +139,10 @@ void Menu::Select() { } void Menu::Select(MenuItem* item) { - if (selected->GetState() != MenuState::kSplit) { + if (selected->GetState() != MenuState::kSplit || + selected->GetState() != MenuState::kChange) { buffer = selected; } + selected = item; }