Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
path = vstgui
url = https://github.com/steinbergmedia/vstgui.git
ignore = dirty
[submodule "JUCE"]
path = JUCE
url = https://github.com/juce-framework/JUCE.git
1 change: 1 addition & 0 deletions JUCE
Submodule JUCE added at 51a8a6
81 changes: 81 additions & 0 deletions OnePingOnly-JUCE/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
cmake_minimum_required(VERSION 3.15)

project(OnePingOnly VERSION 1.0.0)

# Include JUCE from the shared location in the parent directory
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../JUCE JUCE_build)

# Set C++ standard
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

# Create binary data for assets
juce_add_binary_data(OnePingOnlyBinaryData
SOURCES
assets/logo.png
)

# Create plugin
juce_add_plugin(OnePingOnly
VERSION 1.0.0
COMPANY_NAME "Smartelectronix"
PLUGIN_MANUFACTURER_CODE Smtx
PLUGIN_CODE Ping
FORMATS VST3 AU
PRODUCT_NAME "One Ping Only"
COMPANY_WEBSITE "https://github.com/bdejong/smartelectronix"
COMPANY_EMAIL "[email protected]"
IS_SYNTH TRUE
NEEDS_MIDI_INPUT TRUE
NEEDS_MIDI_OUTPUT FALSE
IS_MIDI_EFFECT FALSE
VST_NUM_MIDI_INPUTS 1
VST_NUM_MIDI_OUTPUTS 0
)

# Source files
target_sources(OnePingOnly
PRIVATE
src/PluginProcessor.cpp
src/PluginEditor.cpp
src/Delay.cpp
)

# Include directories
target_include_directories(OnePingOnly
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src
)

# JUCE module dependencies
target_compile_definitions(OnePingOnly
PUBLIC
JUCE_WEB_BROWSER=0
JUCE_USE_CURL=0
JUCE_VST3_CAN_REPLACE_VST2=0
)

# Required JUCE modules
juce_generate_juce_header(OnePingOnly)

target_link_libraries(OnePingOnly
PRIVATE
juce::juce_audio_basics
juce::juce_audio_devices
juce::juce_audio_formats
juce::juce_audio_plugin_client
juce::juce_audio_processors
juce::juce_audio_utils
juce::juce_core
juce::juce_data_structures
juce::juce_dsp
juce::juce_events
juce::juce_graphics
juce::juce_gui_basics
juce::juce_gui_extra
OnePingOnlyBinaryData
PUBLIC
juce::juce_recommended_config_flags
juce::juce_recommended_lto_flags
juce::juce_recommended_warning_flags
)
71 changes: 71 additions & 0 deletions OnePingOnly-JUCE/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# One Ping Only (JUCE Version)

This is a JUCE-based port of the original OnePingOnly VST plugin from Smartelectronix.

## Features

- 128 unique oscillators with configurable parameters
- Delay effect with adjustable feedback
- 12 factory presets
- MIDI note input triggering individual pings
- VST3 and AU plugin formats supported

## Building the Plugin

### Prerequisites

- CMake 3.15 or later
- A C++17 compatible compiler
- JUCE framework (added as a submodule in the parent directory)

### Setup

First, ensure JUCE is properly set up by running the setup script in the parent directory:

```bash
# From the root smartelectronix directory
./setup-juce.sh
```

### Building

```bash
# Create a build directory
mkdir -p build
cd build

# Configure and build
cmake ..
cmake --build .
```

The built plugins will be in the `build` directory under platform-specific folders.

## Usage

- Each MIDI note (0-127) triggers a unique oscillator
- Use the global controls (delay time, feedback, and master volume) to shape the overall sound
- The program selector allows you to choose between 12 different presets

## Parameters

### Global Parameters

- **Delay Time**: Controls the delay time (0.0 to 1.0 seconds)
- **Feedback**: Controls the delay feedback (0.0 to 0.95)
- **Master Volume**: Controls the overall output volume

### Voice Parameters (Per MIDI Note)

Each MIDI note (0-127) has its own set of parameters:

- **Frequency**: Adjusts the oscillator frequency
- **Duration**: Controls the ping duration
- **Amplitude**: Sets the volume of the individual ping
- **Balance**: Controls stereo positioning
- **Noise**: Adds noise to the ping
- **Distortion**: Adds harmonic distortion to the ping

## License

This software is licensed under the same terms as the original Smartelectronix plugins.
1 change: 1 addition & 0 deletions OnePingOnly-JUCE/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
80 changes: 80 additions & 0 deletions OnePingOnly-JUCE/src/Delay.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
#include "Delay.h"

Delay::Delay(int maxDelay)
: feedback(0.0f)
, feedbackTemp(1.0f)
, bufferIndex(0)
, readPosition(0)
, delaySamples(0)
, maxDelaySamples(maxDelay)
{
buffer = std::make_unique<float[]>(static_cast<size_t>(maxDelaySamples));
clearBuffer();
}

Delay::~Delay()
{
}

void Delay::setDelay(int delayInSamples)
{
delaySamples = delayInSamples;

readPosition = bufferIndex - delayInSamples;

// Wrap readPosition to valid buffer range
while (readPosition >= maxDelaySamples)
readPosition -= maxDelaySamples;

while (readPosition < 0)
readPosition += maxDelaySamples;
}

float Delay::getVal(float input)
{
// Read from buffer
float delayedSample = buffer[static_cast<size_t>(readPosition)];

// Calculate output with feedback - matching original implementation exactly
float output = input + feedback * delayedSample;

// Write to buffer
buffer[static_cast<size_t>(bufferIndex)] = output;

// Increment and wrap indices
bufferIndex++;
if (bufferIndex >= maxDelaySamples)
bufferIndex = 0;

readPosition++;
if (readPosition >= maxDelaySamples)
readPosition = 0;

return output;
}

void Delay::setMaxDelay(int maxDelay)
{
maxDelaySamples = maxDelay;

buffer = std::make_unique<float[]>(static_cast<size_t>(maxDelaySamples));
clearBuffer();

// Reset indices
bufferIndex = 0;

// Recalculate read position based on new buffer size
setDelay(delaySamples);
}

void Delay::clearBuffer()
{
for (size_t i = 0; i < static_cast<size_t>(maxDelaySamples); i++)
buffer[i] = 0.0f;
}

void Delay::setFeedback(float feedbackAmount)
{
feedback = feedbackAmount;
feedbackTemp = 1.0f - feedback; // Match the original implementation
}
27 changes: 27 additions & 0 deletions OnePingOnly-JUCE/src/Delay.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#pragma once

#include "../JuceLibraryCode/JuceHeader.h"

class Delay
{
public:
Delay(int maxDelay = 44100 * 5);
~Delay();

void setFeedback(float feedback);
void clearBuffer();
void setMaxDelay(int maxDelay);
float getVal(float input); // Renamed to match original implementation
void setDelay(int delayInSamples);

private:
std::unique_ptr<float[]> buffer;
float feedback;
float feedbackTemp; // Added to match original implementation
int bufferIndex;
int readPosition;
int delaySamples;
int maxDelaySamples;

JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(Delay)
};
Loading