-
Notifications
You must be signed in to change notification settings - Fork 9
Added Super Saw plugin #2
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| #ifndef DISTRHO_PLUGIN_INFO_H_INCLUDED | ||
| #define DISTRHO_PLUGIN_INFO_H_INCLUDED | ||
|
|
||
| #define DISTRHO_PLUGIN_NAME "Super Saw" | ||
| #define DISTRHO_PLUGIN_URI "https://github.com/cranixx/Super_Saw_DPF" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This URI should be like the other plugins, if it is going to be part of DISTRHO examples. |
||
| #define DISTRHO_PLUGIN_NUM_INPUTS 1 | ||
| #define DISTRHO_PLUGIN_NUM_OUTPUTS 1 | ||
| #define DISTRHO_PLUGIN_IS_SYNTH 1 | ||
|
|
||
| #endif // DISTRHO_PLUGIN_INFO_H_INCLUDED | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| #!/usr/bin/make -f | ||
| # Makefile for DISTRHO Plugins # | ||
| # ---------------------------- # | ||
| # Created by falkTX | ||
| # | ||
|
|
||
| # -------------------------------------------------------------- | ||
| # Project name, used for binaries | ||
|
|
||
| NAME = Super_Saw | ||
|
|
||
| # -------------------------------------------------------------- | ||
| # Files to build | ||
|
|
||
| OBJS_DSP = \ | ||
| SuperSaw.cpp.o | ||
|
|
||
| #OBJS_UI = \ | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are you planning to add an UI? or not needed? |
||
| # InfoExampleUI.cpp.o | ||
|
|
||
| # -------------------------------------------------------------- | ||
| # Do some magic | ||
|
|
||
| include ../Makefile.mk | ||
|
|
||
| # -------------------------------------------------------------- | ||
| # Enable all possible plugin types | ||
|
|
||
| ifeq ($(HAVE_DGL),true) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. likewise, remove the HAVE_DGL check. |
||
| ifeq ($(HAVE_JACK),true) | ||
| TARGETS += jack | ||
| endif | ||
| endif | ||
|
|
||
| ifeq ($(HAVE_DGL),true) | ||
| TARGETS += lv2_sep | ||
| else | ||
| TARGETS += lv2_dsp | ||
| endif | ||
|
|
||
| TARGETS += vst | ||
|
|
||
| ADA: | ||
| gnat make -fPIC blep | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this requires external tools, we need to make sure to make this plugin optional then... |
||
| gnat bind -n blep | ||
| gnat make -fPIC super_saw | ||
| gnat bind -n super_saw | ||
| gnat make -fPIC b~super_saw | ||
| gnat bind -n b~super_saw | ||
| gnat make -fPIC polyphony | ||
| gnat bind -n polyphony | ||
| gnat make -fPIC b~polyphony | ||
| gnat bind -n b~polyphony | ||
|
|
||
| #BASE_FLAGS += super_saw.o b~super_saw.o -lgnat -lgnarl -lgmem | ||
| BASE_FLAGS += super_saw.o polyphony.o b~polyphony.o blep.o -lgnat -lgnarl -lgmem -ggdb | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please use pkg-config to find the libs and paths to use for linking (this and the line below). |
||
| BASE_FLAGS += -L/usr/lib/gcc/x86_64-redhat-linux/7/adalib | ||
|
|
||
| all: ADA $(TARGETS) | ||
|
|
||
| # -------------------------------------------------------------- | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,168 @@ | ||
| #include "DistrhoPlugin.hpp" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. header comments missing on this file. |
||
| #include <math.h> | ||
| extern "C" void adainit(void); | ||
| extern "C" void adafinal(void); | ||
| extern "C" void Add_Note(float); | ||
| extern "C" void Remove_Note(float); | ||
| extern "C" float Super_Saw(float,float,float,float,float); | ||
| extern "C" float Compute_Polyphony(float,float,float,float); | ||
|
|
||
| START_NAMESPACE_DISTRHO | ||
| class SuperSaw : public Plugin | ||
| { | ||
| public: | ||
| SuperSaw() : Plugin(2,0,0){ | ||
| adainit(); | ||
| } | ||
|
|
||
| ~SuperSaw() { | ||
| adafinal(); | ||
| } | ||
|
|
||
| protected: | ||
| const char* getLabel() const override | ||
| { | ||
| return "Super Saw"; | ||
| } | ||
|
|
||
| const char* getDescription() const override | ||
| { | ||
| return "Roland JP-8000 Super Saw emulator"; | ||
| } | ||
| const char* getMaker() const override | ||
| { | ||
| return "Cranix"; | ||
| } | ||
|
|
||
| /** | ||
| Get the plugin homepage. | ||
| */ | ||
| const char* getHomePage() const override | ||
| { | ||
| return "http://example.org/Super_Saw"; | ||
| } | ||
|
|
||
| /** | ||
| Get the plugin license name (a single line of text). | ||
| For commercial plugins this should return some short copyright information. | ||
| */ | ||
| const char* getLicense() const override | ||
| { | ||
| return "GPL"; | ||
| } | ||
|
|
||
| /** | ||
| Get the plugin version, in hexadecimal. | ||
| */ | ||
| uint32_t getVersion() const override | ||
| { | ||
| return d_version(1, 0, 0); | ||
| } | ||
|
|
||
| /** | ||
| Get the plugin unique Id. | ||
| This value is used by LADSPA, DSSI and VST plugin formats. | ||
| */ | ||
| int64_t getUniqueId() const override | ||
| { | ||
| return d_cconst('d', 'N', 'f', 'o'); | ||
| } | ||
| void setParameterValue(uint32_t index, float value) override | ||
| { | ||
| if (index == 0) { | ||
| detune = value; | ||
| } else if (index == 1) { | ||
| mix = value; | ||
| } | ||
| } | ||
|
|
||
| float getParameterValue(uint32_t index) const override | ||
| { | ||
| if (index == 0) { | ||
| return detune; | ||
| } else if (index == 1) { | ||
| return mix; | ||
| } | ||
| } | ||
|
|
||
| void initParameter(uint32_t index, Parameter& parameter) override { | ||
| if (index == 0) { /*Detune*/ | ||
| parameter.hints = kParameterIsAutomable; | ||
| parameter.name = "Detune"; | ||
| parameter.symbol = "detune"; | ||
| parameter.ranges.min = 0.0f; | ||
| parameter.ranges.max = 0.9f; | ||
| parameter.ranges.def = 0.5f; | ||
| } else if (index == 1) { /*Mix*/ | ||
| parameter.hints = kParameterIsAutomable; | ||
| parameter.name = "Mix"; | ||
| parameter.symbol = "mix"; | ||
| parameter.ranges.min = 0.0f; | ||
| parameter.ranges.max = 0.9f; | ||
| parameter.ranges.def = 0.5f; | ||
| } | ||
| } | ||
|
|
||
|
|
||
| void run(const float** inputs, float** outputs, uint32_t frames, const MidiEvent* midiEvents, | ||
| uint32_t midiEventCount) override { | ||
| const uint8_t* data; | ||
| uint8_t status; | ||
| uint8_t note; | ||
| float frequency; | ||
| uint32_t framesDone=0; | ||
| uint32_t curEventIndex=0; | ||
|
|
||
| while (framesDone < frames) { | ||
| while (curEventIndex < midiEventCount && framesDone == midiEvents[curEventIndex].frame) { | ||
| if ( midiEvents[curEventIndex].size > MidiEvent::kDataSize ) | ||
| continue; | ||
| data=midiEvents[curEventIndex].data; | ||
| status=data[0]&0xFF; | ||
| if ( ! ( ( status == 0x80 || status == 0x90))) { | ||
| curEventIndex++; | ||
| continue; | ||
| } | ||
| note=data[1]; | ||
| if (status == 0x90) { | ||
| frequency=pow(2.0,(note-57.0)/12.0)*440.0; | ||
| Add_Note(frequency); | ||
| } else if (status == 0x80) { | ||
| // frequency = 0.0; | ||
| frequency=pow(2.0,(note-57.0)/12.0)*440.0; | ||
| Remove_Note(frequency); | ||
| } | ||
| curEventIndex++; | ||
| } | ||
| //outputs[0][framesDone]=sin(phase*frequency/44100.0*2.0*3.14); | ||
| //outputs[0][framesDone]=sin(phase*frequency/44100.0*2.0*3.14); | ||
| outputs[0][framesDone]=Compute_Polyphony(phase,detune,mix,getSampleRate()); | ||
| phase++; | ||
| framesDone++; | ||
| } | ||
| /*data=midiEvents[0].data; | ||
| status=data[0]&0xFF; | ||
| if (status == 0x90){ | ||
| note=data[1]; | ||
| frequency=pow(2.0,(note-57.0)/12.0)*440.0; | ||
| for (i=0;i<frames;i++){ | ||
| outputs[0][i] = sin(phase*2.0*3.14*frequency); | ||
| phase++; | ||
| } | ||
| }*/ | ||
| } //run | ||
|
|
||
| private: | ||
| float phase=0; | ||
| float detune; | ||
| float mix; | ||
| }; | ||
|
|
||
| Plugin* createPlugin() | ||
| { | ||
| return new SuperSaw(); | ||
| } | ||
|
|
||
|
|
||
| END_NAMESPACE_DISTRHO | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package body Blep is | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please add header comments to ADB files. |
||
| function BLEP_Saw(Phase : Float; Pitch : Float) return Float is | ||
| T : Float := modulo(Phase,1.0); | ||
| begin | ||
| return Naive_Saw(Phase, Pitch)+T-(T*T/2.0)-0.5; | ||
| end BLEP_Saw; | ||
|
|
||
| function Naive_Saw(Phase : Float; Frequency: Float) return Float is | ||
| begin | ||
| return Modulo((Phase*Frequency),1.0); | ||
| end Naive_Saw; | ||
|
|
||
| function modulo (Dividend : Float; Divisor : Float) return Float is | ||
| Fraction : Float; | ||
| Int_Part : Integer; | ||
| begin | ||
| Int_Part := Integer(Dividend); | ||
| Fraction := Dividend - Float(Int_Part); | ||
| return Float((Int_Part mod Integer(Divisor))) + Fraction; | ||
| end modulo; | ||
|
|
||
| function Sinc (Phase : Float) return Float is | ||
| begin | ||
| if Phase = 0.0 then | ||
| return 1.0; | ||
| else | ||
| return Sin(Phase)/Phase; | ||
| end if; | ||
| end Sinc; | ||
|
|
||
| function Hamming (N : Float; Size : Float) return Float is | ||
| begin | ||
| return 0.54 - 0.46*Cos(2.0*Pi*N/(Size - 1.0)); | ||
| end Hamming; | ||
| end Blep; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| with Ada.Numerics; | ||
| use Ada.Numerics; | ||
| with Ada.Numerics.Elementary_Functions; | ||
| use Ada.Numerics.Elementary_Functions; | ||
|
|
||
| package Blep is | ||
| function BLEP_Saw(Phase : Float; Pitch : Float) return Float; | ||
| private | ||
| function Naive_Saw(Phase : Float; Frequency : Float) return Float; | ||
| function modulo (Dividend : Float; Divisor : Float) return Float; | ||
| function Sinc (Phase : Float) return Float; | ||
| function Hamming (N : Float; Size : Float) return Float; | ||
| end Blep; | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| with Interfaces.C; | ||
| use Interfaces.C; | ||
|
|
||
| with Ada.Numerics.Generic_Elementary_Functions; | ||
|
|
||
| with Super_Saw; | ||
|
|
||
| package body Polyphony is | ||
| procedure Add_Note (Pitch : C_Float) is | ||
| begin | ||
| if Note_Count <= Voices then | ||
| for I in Notes'Range loop | ||
| if Notes(I) = 0.0 then | ||
| Notes(I) := Float(Pitch); | ||
| Note_Count := Note_Count + 1; | ||
| exit; | ||
| end if; | ||
| end loop; | ||
| end if; | ||
| end Add_Note; | ||
|
|
||
| procedure Remove_Note (Pitch : C_Float) is | ||
| begin | ||
| if Note_Count > 0 then | ||
| for I in Notes'Range loop | ||
| if Notes(I) = Float(Pitch) then | ||
| Notes(I) := 0.0; | ||
| Note_Count := Note_Count - 1; | ||
| exit; | ||
| end if; | ||
| end loop; | ||
| end if; | ||
| end Remove_Note; | ||
|
|
||
| function Compute_Polyphony (Time : C_Float; | ||
| Detune : C_Float; Mix : C_Float; | ||
| Sample_Rate : C_Float) return C_Float is | ||
| package Float_Functions is new Ada.Numerics.Generic_Elementary_Functions (Float); | ||
| Sample : C_Float := 0.0; | ||
| begin | ||
| for I in Notes'Range loop | ||
| if Notes(I) /= 0.0 then | ||
| -- Compensate for changes in volume by dividing output by logarithm of frequency | ||
| Sample := Sample + Super_Saw.Super_Saw(Time => Time, Pitch => C_Float(Notes(I)), | ||
| Detune => Detune, Mix => Mix, | ||
| Sample_Rate => Sample_Rate)/C_Float(Float_Functions.Log(Notes(I)*30.0,10.0)); | ||
| end if; | ||
| end loop; | ||
| return Sample; | ||
| end Compute_Polyphony; | ||
| end Polyphony; | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| with Interfaces.C; | ||
| use Interfaces.C; | ||
|
|
||
| package Polyphony is | ||
| type Note_Array_Type is array (1..4) of Float; | ||
| Notes : Note_Array_Type := (others => 0.0); | ||
| Note_Count : Natural := 0; | ||
| Voices : constant := 4; | ||
| procedure Add_Note (Pitch : C_Float) | ||
| with Post => Note_Count <= Voices and Note_Count >= 0; | ||
| procedure Remove_Note (Pitch : C_Float) | ||
| with Post => Note_Count <= Voices and Note_Count >= 0; | ||
| function Compute_Polyphony (Time : C_Float; Detune : C_Float; Mix : C_Float; | ||
| Sample_Rate : C_Float) return C_Float; | ||
|
|
||
| pragma Export(CPP,Add_Note,"Add_Note"); | ||
| pragma Export(CPP,Remove_Note,"Remove_Note"); | ||
| pragma Export(CPP,Compute_Polyphony,"Compute_Polyphony"); | ||
| end Polyphony; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are using uppercase and lowercase names here, so please use CamelCase for the folder name.
(ie, rename it SuperSaw)