Browse Source

Merge 2d40755674 into 98ab7d627a

pull/2/merge
Cranix GitHub 6 years ago
parent
commit
3ed4576332
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 440 additions and 0 deletions
  1. +1
    -0
      Makefile
  2. +11
    -0
      plugins/Super_Saw/DistrhoPluginInfo.h
  3. +61
    -0
      plugins/Super_Saw/Makefile
  4. +168
    -0
      plugins/Super_Saw/SuperSaw.cpp
  5. +36
    -0
      plugins/Super_Saw/blep.adb
  6. +14
    -0
      plugins/Super_Saw/blep.ads
  7. +52
    -0
      plugins/Super_Saw/polyphony.adb
  8. +20
    -0
      plugins/Super_Saw/polyphony.ads
  9. +58
    -0
      plugins/Super_Saw/super_saw.adb
  10. +19
    -0
      plugins/Super_Saw/super_saw.ads

+ 1
- 0
Makefile View File

@@ -22,6 +22,7 @@ plugins: dgl
$(MAKE) all -C plugins/MidiThrough
$(MAKE) all -C plugins/Parameters
$(MAKE) all -C plugins/States
$(MAKE) all -C plugins/Super_Saw

ifneq ($(CROSS_COMPILING),true)
gen: plugins dpf/utils/lv2_ttl_generator


+ 11
- 0
plugins/Super_Saw/DistrhoPluginInfo.h View File

@@ -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"
#define DISTRHO_PLUGIN_NUM_INPUTS 1
#define DISTRHO_PLUGIN_NUM_OUTPUTS 1
#define DISTRHO_PLUGIN_IS_SYNTH 1

#endif // DISTRHO_PLUGIN_INFO_H_INCLUDED


+ 61
- 0
plugins/Super_Saw/Makefile View File

@@ -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 = \
# InfoExampleUI.cpp.o

# --------------------------------------------------------------
# Do some magic

include ../Makefile.mk

# --------------------------------------------------------------
# Enable all possible plugin types

ifeq ($(HAVE_DGL),true)
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
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
BASE_FLAGS += -L/usr/lib/gcc/x86_64-redhat-linux/7/adalib

all: ADA $(TARGETS)

# --------------------------------------------------------------

+ 168
- 0
plugins/Super_Saw/SuperSaw.cpp View File

@@ -0,0 +1,168 @@
#include "DistrhoPlugin.hpp"
#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


+ 36
- 0
plugins/Super_Saw/blep.adb View File

@@ -0,0 +1,36 @@
package body Blep is
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;


+ 14
- 0
plugins/Super_Saw/blep.ads View File

@@ -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;


+ 52
- 0
plugins/Super_Saw/polyphony.adb View File

@@ -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;


+ 20
- 0
plugins/Super_Saw/polyphony.ads View File

@@ -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;


+ 58
- 0
plugins/Super_Saw/super_saw.adb View File

@@ -0,0 +1,58 @@
with Interfaces.C;
use Interfaces.C;

with Ada.Numerics;
use Ada.Numerics;

with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions;

with Blep;
package body Super_Saw is
function Super_Saw(Time : Interfaces.C.C_Float; Pitch : Interfaces.C.C_Float;
Detune : Interfaces.C.C_Float; Mix : Interfaces.C.C_Float;
Sample_Rate : Interfaces.C.C_Float)
return Interfaces.C.C_Float is
Offsets : Offset_Array_Type := (0.01952356,0.06288439,0.11002313);
Sample : Float := 0.0;
Mix_Level : Mix_Level_Type := Compute_Mix(Float(Mix));
begin
-- Main oscillator
Sample := Sample + Saw(Float(Time),Float(Pitch), Float(Sample_Rate))*Mix_Level.Master;

-- 3 oscillators of higher pitch than main
Higher_Oscillators:for D in 1 .. 3 loop
Sample := Sample + Saw(Float(Time),Float(Pitch)*(1.0+Offsets(D)*Compute_Detune(Float(Detune))),
Float(Sample_Rate))*Mix_Level.Slave;
end loop Higher_Oscillators;

-- 3 oscillators of lower pitch than main
Lower_Oscillators:for D in 1 .. 3 loop
Sample := Sample + Saw(Float(Time),Float(Pitch)*(1.0+Offsets(D)*Compute_Detune(Float(Detune))),
Float(Sample_Rate))*Mix_Level.Slave;
end loop Lower_Oscillators;
return Interfaces.C.C_FLoat(Sample)*Interfaces.C.C_Float(0.1);
end Super_Saw;

function Saw(Time : Float; Pitch : Float; Sample_Rate : Float) return Float is
begin
return Blep.BLEP_Saw(Time,Pitch/Sample_Rate);
end Saw;
function Compute_Detune(Amount : Float) return Float is
begin
return (10028.7312891634*Amount**11)-(50818.8652045924*Amount**10)
+(111363.4808729368*Amount**9)-(138150.6761080548*Amount**8)+
(106649.6679158292*Amount**7)-(53046.9642751875*Amount**6)+
(17019.9518580080*Amount**5)-(3425.0836591318*Amount**4)+
(404.2703938388*Amount**3)-(24.1878824391*Amount**2)+
(0.6717417634*Amount)+0.0030115596;
end Compute_Detune;
function Compute_Mix(Level : Float) return Mix_Level_Type is
Mix_Level : Mix_Level_Type;
begin
Mix_Level.Master := -0.55366*Level + 0.99785;
Mix_Level.Slave := -0.73764*Level**2 + 1.2841*Level + 0.044372;
return Mix_Level;
end Compute_Mix;
end Super_Saw;


+ 19
- 0
plugins/Super_Saw/super_saw.ads View File

@@ -0,0 +1,19 @@
with Interfaces.C;
use Interfaces.C;
package Super_Saw is
type Mix_Level_Type is record
Master : Float;
Slave : Float;
end record;
type Offset_Array_Type is array (1..3) of Float;
function Saw(Time : Float; Pitch : Float; Sample_Rate : Float) return Float;
function Compute_Detune(Amount : Float) return Float;
function Compute_Mix(Level : Float) return Mix_Level_Type;
function Super_Saw(Time : Interfaces.C.C_Float;
Pitch : Interfaces.C.C_Float;Detune : Interfaces.C.C_Float;
Mix : Interfaces.C.C_Float
;Sample_Rate : Interfaces.C.C_Float)
return Interfaces.C.C_Float;
pragma Export(CPP,Super_Saw,"Super_Saw");
end Super_Saw;


Loading…
Cancel
Save