summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorcranix <cranix@hackerspace.pl>2017-11-03 11:36:20 +0100
committercranix <cranix@hackerspace.pl>2017-11-03 11:36:20 +0100
commit7bea14cf751d4a3297ff1954c3b3cdca7e1e2ecb (patch)
treee7a951dd7a3ceb2737dd1618653cf2455a98ee3b
downloadLv2_Super_Saw-master.tar.gz
Lv2_Super_Saw-master.tar.bz2
Lv2_Super_Saw-master.zip
Initial commitHEADmaster
-rw-r--r--Makefile23
-rw-r--r--b~super_saw.adb139
-rw-r--r--b~super_saw.ads209
-rw-r--r--manifest.ttl5
-rw-r--r--super_saw.adb75
-rw-r--r--super_saw.ads19
-rw-r--r--super_saw.cpp69
-rw-r--r--super_saw.peg39
8 files changed, 578 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..09d18cd
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,23 @@
+BUNDLE = super_saw.lv2
+INSTALL_DIR = ./build
+
+
+$(BUNDLE): manifest.ttl super_saw.ttl super_saw.so
+ rm -rf $(BUNDLE)
+ mkdir $(BUNDLE)
+ cp $^ $(BUNDLE)
+
+super_saw.so: super_saw.cpp super_saw.peg
+ g++ -shared -fPIC -DPIC super_saw.cpp `pkg-config --cflags --libs lv2-plugin` -o super_saw.so
+
+super_saw.peg: super_saw.ttl
+ lv2peg super_saw.ttl super_saw.peg
+
+install: $(BUNDLE)
+ mkdir -p $(INSTALL_DIR)
+ rm -rf $(INSTALL_DIR)/$(BUNDLE)
+ cp -R $(BUNDLE) $(INSTALL_DIR)
+
+clean:
+ rm -rf $(BUNDLE) super_saw.so super_saw.peg
+
diff --git a/b~super_saw.adb b/b~super_saw.adb
new file mode 100644
index 0000000..423a157
--- /dev/null
+++ b/b~super_saw.adb
@@ -0,0 +1,139 @@
+pragma Ada_95;
+pragma Warnings (Off);
+pragma Source_File_Name (ada_main, Spec_File_Name => "b~super_saw.ads");
+pragma Source_File_Name (ada_main, Body_File_Name => "b~super_saw.adb");
+pragma Suppress (Overflow_Check);
+
+package body ada_main is
+
+ E11 : Short_Integer; pragma Import (Ada, E11, "system__soft_links_E");
+ E09 : Short_Integer; pragma Import (Ada, E09, "system__exception_table_E");
+ E06 : Short_Integer; pragma Import (Ada, E06, "ada__numerics_E");
+ E61 : Short_Integer; pragma Import (Ada, E61, "interfaces__c_E");
+ E23 : Short_Integer; pragma Import (Ada, E23, "system__exceptions_E");
+ E15 : Short_Integer; pragma Import (Ada, E15, "system__secondary_stack_E");
+ E02 : Short_Integer; pragma Import (Ada, E02, "super_saw_E");
+
+ Local_Priority_Specific_Dispatching : constant String := "";
+ Local_Interrupt_States : constant String := "";
+
+ Is_Elaborated : Boolean := False;
+
+ procedure adafinal is
+
+ procedure Runtime_Finalize;
+ pragma Import (C, Runtime_Finalize, "__gnat_runtime_finalize");
+
+ begin
+ if not Is_Elaborated then
+ return;
+ end if;
+ Is_Elaborated := False;
+ Runtime_Finalize;
+ null;
+ end adafinal;
+
+ type No_Param_Proc is access procedure;
+
+ procedure adainit is
+ Main_Priority : Integer;
+ pragma Import (C, Main_Priority, "__gl_main_priority");
+ Time_Slice_Value : Integer;
+ pragma Import (C, Time_Slice_Value, "__gl_time_slice_val");
+ WC_Encoding : Character;
+ pragma Import (C, WC_Encoding, "__gl_wc_encoding");
+ Locking_Policy : Character;
+ pragma Import (C, Locking_Policy, "__gl_locking_policy");
+ Queuing_Policy : Character;
+ pragma Import (C, Queuing_Policy, "__gl_queuing_policy");
+ Task_Dispatching_Policy : Character;
+ pragma Import (C, Task_Dispatching_Policy, "__gl_task_dispatching_policy");
+ Priority_Specific_Dispatching : System.Address;
+ pragma Import (C, Priority_Specific_Dispatching, "__gl_priority_specific_dispatching");
+ Num_Specific_Dispatching : Integer;
+ pragma Import (C, Num_Specific_Dispatching, "__gl_num_specific_dispatching");
+ Main_CPU : Integer;
+ pragma Import (C, Main_CPU, "__gl_main_cpu");
+ Interrupt_States : System.Address;
+ pragma Import (C, Interrupt_States, "__gl_interrupt_states");
+ Num_Interrupt_States : Integer;
+ pragma Import (C, Num_Interrupt_States, "__gl_num_interrupt_states");
+ Unreserve_All_Interrupts : Integer;
+ pragma Import (C, Unreserve_All_Interrupts, "__gl_unreserve_all_interrupts");
+ Detect_Blocking : Integer;
+ pragma Import (C, Detect_Blocking, "__gl_detect_blocking");
+ Default_Stack_Size : Integer;
+ pragma Import (C, Default_Stack_Size, "__gl_default_stack_size");
+ Leap_Seconds_Support : Integer;
+ pragma Import (C, Leap_Seconds_Support, "__gl_leap_seconds_support");
+ Bind_Env_Addr : System.Address;
+ pragma Import (C, Bind_Env_Addr, "__gl_bind_env_addr");
+
+ procedure Runtime_Initialize (Install_Handler : Integer);
+ pragma Import (C, Runtime_Initialize, "__gnat_runtime_initialize");
+
+ Finalize_Library_Objects : No_Param_Proc;
+ pragma Import (C, Finalize_Library_Objects, "__gnat_finalize_library_objects");
+ begin
+ if Is_Elaborated then
+ return;
+ end if;
+ Is_Elaborated := True;
+ Main_Priority := -1;
+ Time_Slice_Value := -1;
+ WC_Encoding := 'b';
+ Locking_Policy := ' ';
+ Queuing_Policy := ' ';
+ Task_Dispatching_Policy := ' ';
+ Priority_Specific_Dispatching :=
+ Local_Priority_Specific_Dispatching'Address;
+ Num_Specific_Dispatching := 0;
+ Main_CPU := -1;
+ Interrupt_States := Local_Interrupt_States'Address;
+ Num_Interrupt_States := 0;
+ Unreserve_All_Interrupts := 0;
+ Detect_Blocking := 0;
+ Default_Stack_Size := -1;
+ Leap_Seconds_Support := 0;
+
+ Runtime_Initialize (1);
+
+ if E11 = 0 then
+ System.Soft_Links'Elab_Spec;
+ end if;
+ if E09 = 0 then
+ System.Exception_Table'Elab_Body;
+ end if;
+ E09 := E09 + 1;
+ if E06 = 0 then
+ Ada.Numerics'Elab_Spec;
+ end if;
+ E06 := E06 + 1;
+ if E61 = 0 then
+ Interfaces.C'Elab_Spec;
+ end if;
+ if E23 = 0 then
+ System.Exceptions'Elab_Spec;
+ end if;
+ E23 := E23 + 1;
+ E61 := E61 + 1;
+ if E11 = 0 then
+ System.Soft_Links'Elab_Body;
+ end if;
+ E11 := E11 + 1;
+ if E15 = 0 then
+ System.Secondary_Stack'Elab_Body;
+ end if;
+ E15 := E15 + 1;
+ E02 := E02 + 1;
+ end adainit;
+
+-- BEGIN Object file/option list
+ -- ./super_saw.o
+ -- -L./
+ -- -L/usr/lib/gcc/x86_64-redhat-linux/6.3.1/adalib/
+ -- -static
+ -- -lgnat
+-- END Object file/option list
+
+end ada_main;
diff --git a/b~super_saw.ads b/b~super_saw.ads
new file mode 100644
index 0000000..1b04db6
--- /dev/null
+++ b/b~super_saw.ads
@@ -0,0 +1,209 @@
+pragma Ada_95;
+pragma Warnings (Off);
+with System;
+package ada_main is
+
+ procedure adainit;
+ pragma Export (C, adainit, "adainit");
+
+ procedure adafinal;
+ pragma Export (C, adafinal, "adafinal");
+
+ type Version_32 is mod 2 ** 32;
+ u00001 : constant Version_32 := 16#ed0b57b1#;
+ pragma Export (C, u00001, "super_sawB");
+ u00002 : constant Version_32 := 16#2c05898c#;
+ pragma Export (C, u00002, "super_sawS");
+ u00003 : constant Version_32 := 16#b6df930e#;
+ pragma Export (C, u00003, "system__standard_libraryB");
+ u00004 : constant Version_32 := 16#937076cc#;
+ pragma Export (C, u00004, "system__standard_libraryS");
+ u00005 : constant Version_32 := 16#3ffc8e18#;
+ pragma Export (C, u00005, "adaS");
+ u00006 : constant Version_32 := 16#84ad4a42#;
+ pragma Export (C, u00006, "ada__numericsS");
+ u00007 : constant Version_32 := 16#6326c08a#;
+ pragma Export (C, u00007, "systemS");
+ u00008 : constant Version_32 := 16#87a448ff#;
+ pragma Export (C, u00008, "system__exception_tableB");
+ u00009 : constant Version_32 := 16#3e88a9c8#;
+ pragma Export (C, u00009, "system__exception_tableS");
+ u00010 : constant Version_32 := 16#465d427a#;
+ pragma Export (C, u00010, "system__soft_linksB");
+ u00011 : constant Version_32 := 16#fda218df#;
+ pragma Export (C, u00011, "system__soft_linksS");
+ u00012 : constant Version_32 := 16#b01dad17#;
+ pragma Export (C, u00012, "system__parametersB");
+ u00013 : constant Version_32 := 16#1d0ccdf5#;
+ pragma Export (C, u00013, "system__parametersS");
+ u00014 : constant Version_32 := 16#0f0cb66d#;
+ pragma Export (C, u00014, "system__secondary_stackB");
+ u00015 : constant Version_32 := 16#c8470fe3#;
+ pragma Export (C, u00015, "system__secondary_stackS");
+ u00016 : constant Version_32 := 16#39a03df9#;
+ pragma Export (C, u00016, "system__storage_elementsB");
+ u00017 : constant Version_32 := 16#4ee58a8e#;
+ pragma Export (C, u00017, "system__storage_elementsS");
+ u00018 : constant Version_32 := 16#e7214354#;
+ pragma Export (C, u00018, "ada__exceptionsB");
+ u00019 : constant Version_32 := 16#020f9e08#;
+ pragma Export (C, u00019, "ada__exceptionsS");
+ u00020 : constant Version_32 := 16#e947e6a9#;
+ pragma Export (C, u00020, "ada__exceptions__last_chance_handlerB");
+ u00021 : constant Version_32 := 16#41e5552e#;
+ pragma Export (C, u00021, "ada__exceptions__last_chance_handlerS");
+ u00022 : constant Version_32 := 16#ce4af020#;
+ pragma Export (C, u00022, "system__exceptionsB");
+ u00023 : constant Version_32 := 16#0b45ad7c#;
+ pragma Export (C, u00023, "system__exceptionsS");
+ u00024 : constant Version_32 := 16#4c9e814d#;
+ pragma Export (C, u00024, "system__exceptions__machineS");
+ u00025 : constant Version_32 := 16#aa0563fc#;
+ pragma Export (C, u00025, "system__exceptions_debugB");
+ u00026 : constant Version_32 := 16#1dac394e#;
+ pragma Export (C, u00026, "system__exceptions_debugS");
+ u00027 : constant Version_32 := 16#570325c8#;
+ pragma Export (C, u00027, "system__img_intB");
+ u00028 : constant Version_32 := 16#61fd2048#;
+ pragma Export (C, u00028, "system__img_intS");
+ u00029 : constant Version_32 := 16#39df8c17#;
+ pragma Export (C, u00029, "system__tracebackB");
+ u00030 : constant Version_32 := 16#3d041e4e#;
+ pragma Export (C, u00030, "system__tracebackS");
+ u00031 : constant Version_32 := 16#9ed49525#;
+ pragma Export (C, u00031, "system__traceback_entriesB");
+ u00032 : constant Version_32 := 16#637d36fa#;
+ pragma Export (C, u00032, "system__traceback_entriesS");
+ u00033 : constant Version_32 := 16#6fd210f2#;
+ pragma Export (C, u00033, "system__traceback__symbolicB");
+ u00034 : constant Version_32 := 16#dd19f67a#;
+ pragma Export (C, u00034, "system__traceback__symbolicS");
+ u00035 : constant Version_32 := 16#701f9d88#;
+ pragma Export (C, u00035, "ada__exceptions__tracebackB");
+ u00036 : constant Version_32 := 16#20245e75#;
+ pragma Export (C, u00036, "ada__exceptions__tracebackS");
+ u00037 : constant Version_32 := 16#57a37a42#;
+ pragma Export (C, u00037, "system__address_imageB");
+ u00038 : constant Version_32 := 16#c2ca5db0#;
+ pragma Export (C, u00038, "system__address_imageS");
+ u00039 : constant Version_32 := 16#8c33a517#;
+ pragma Export (C, u00039, "system__wch_conB");
+ u00040 : constant Version_32 := 16#785be258#;
+ pragma Export (C, u00040, "system__wch_conS");
+ u00041 : constant Version_32 := 16#9721e840#;
+ pragma Export (C, u00041, "system__wch_stwB");
+ u00042 : constant Version_32 := 16#554ace59#;
+ pragma Export (C, u00042, "system__wch_stwS");
+ u00043 : constant Version_32 := 16#b96cfbef#;
+ pragma Export (C, u00043, "system__wch_cnvB");
+ u00044 : constant Version_32 := 16#77ec58ab#;
+ pragma Export (C, u00044, "system__wch_cnvS");
+ u00045 : constant Version_32 := 16#4be8ce1b#;
+ pragma Export (C, u00045, "interfacesS");
+ u00046 : constant Version_32 := 16#ece6fdb6#;
+ pragma Export (C, u00046, "system__wch_jisB");
+ u00047 : constant Version_32 := 16#f79c418a#;
+ pragma Export (C, u00047, "system__wch_jisS");
+ u00048 : constant Version_32 := 16#41837d1e#;
+ pragma Export (C, u00048, "system__stack_checkingB");
+ u00049 : constant Version_32 := 16#ed99ab62#;
+ pragma Export (C, u00049, "system__stack_checkingS");
+ u00050 : constant Version_32 := 16#03e83d1c#;
+ pragma Export (C, u00050, "ada__numerics__elementary_functionsB");
+ u00051 : constant Version_32 := 16#00443200#;
+ pragma Export (C, u00051, "ada__numerics__elementary_functionsS");
+ u00052 : constant Version_32 := 16#3e0cf54d#;
+ pragma Export (C, u00052, "ada__numerics__auxB");
+ u00053 : constant Version_32 := 16#9f6e24ed#;
+ pragma Export (C, u00053, "ada__numerics__auxS");
+ u00054 : constant Version_32 := 16#67b17b79#;
+ pragma Export (C, u00054, "system__fat_llfS");
+ u00055 : constant Version_32 := 16#fe7e644a#;
+ pragma Export (C, u00055, "system__unsigned_typesS");
+ u00056 : constant Version_32 := 16#6c9dbb44#;
+ pragma Export (C, u00056, "system__machine_codeS");
+ u00057 : constant Version_32 := 16#6c05c057#;
+ pragma Export (C, u00057, "system__exn_llfB");
+ u00058 : constant Version_32 := 16#df587b56#;
+ pragma Export (C, u00058, "system__exn_llfS");
+ u00059 : constant Version_32 := 16#3b53dc9e#;
+ pragma Export (C, u00059, "system__fat_fltS");
+ u00060 : constant Version_32 := 16#769e25e6#;
+ pragma Export (C, u00060, "interfaces__cB");
+ u00061 : constant Version_32 := 16#61e3d2ff#;
+ pragma Export (C, u00061, "interfaces__cS");
+ u00062 : constant Version_32 := 16#58e7cff7#;
+ pragma Export (C, u00062, "system__memoryB");
+ u00063 : constant Version_32 := 16#3a5ba6be#;
+ pragma Export (C, u00063, "system__memoryS");
+ u00064 : constant Version_32 := 16#13b71684#;
+ pragma Export (C, u00064, "system__crtlS");
+ -- BEGIN ELABORATION ORDER
+ -- ada%s
+ -- interfaces%s
+ -- system%s
+ -- system.exn_llf%s
+ -- system.exn_llf%b
+ -- system.img_int%s
+ -- system.img_int%b
+ -- system.machine_code%s
+ -- system.parameters%s
+ -- system.parameters%b
+ -- system.crtl%s
+ -- system.standard_library%s
+ -- system.exceptions_debug%s
+ -- system.exceptions_debug%b
+ -- system.storage_elements%s
+ -- system.storage_elements%b
+ -- system.stack_checking%s
+ -- system.stack_checking%b
+ -- system.traceback_entries%s
+ -- system.traceback_entries%b
+ -- ada.exceptions%s
+ -- system.soft_links%s
+ -- system.unsigned_types%s
+ -- system.fat_flt%s
+ -- system.fat_llf%s
+ -- system.wch_con%s
+ -- system.wch_con%b
+ -- system.wch_cnv%s
+ -- system.wch_jis%s
+ -- system.wch_jis%b
+ -- system.wch_cnv%b
+ -- system.wch_stw%s
+ -- system.wch_stw%b
+ -- ada.exceptions.last_chance_handler%s
+ -- ada.exceptions.last_chance_handler%b
+ -- ada.exceptions.traceback%s
+ -- system.address_image%s
+ -- system.exception_table%s
+ -- system.exception_table%b
+ -- ada.numerics%s
+ -- ada.numerics.aux%s
+ -- ada.numerics.aux%b
+ -- ada.numerics.elementary_functions%s
+ -- ada.numerics.elementary_functions%b
+ -- interfaces.c%s
+ -- system.exceptions%s
+ -- system.exceptions%b
+ -- system.exceptions.machine%s
+ -- system.memory%s
+ -- system.memory%b
+ -- system.standard_library%b
+ -- system.secondary_stack%s
+ -- interfaces.c%b
+ -- system.soft_links%b
+ -- system.secondary_stack%b
+ -- system.address_image%b
+ -- ada.exceptions.traceback%b
+ -- system.traceback%s
+ -- system.traceback%b
+ -- system.traceback.symbolic%s
+ -- system.traceback.symbolic%b
+ -- ada.exceptions%b
+ -- super_saw%s
+ -- super_saw%b
+ -- END ELABORATION ORDER
+
+
+end ada_main;
diff --git a/manifest.ttl b/manifest.ttl
new file mode 100644
index 0000000..1320168
--- /dev/null
+++ b/manifest.ttl
@@ -0,0 +1,5 @@
+@prefix lv2: <http://lv2plug.in/ns/lv2core#>.
+@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>.
+ <http://example.org/super_saw>
+ a lv2:Plugin;
+ rdfs:seeAlso <super_saw.ttl>.
diff --git a/super_saw.adb b/super_saw.adb
new file mode 100644
index 0000000..7498e03
--- /dev/null
+++ b/super_saw.adb
@@ -0,0 +1,75 @@
+with Interfaces.C;
+use Interfaces.C;
+
+with Ada.Numerics;
+use Ada.Numerics;
+
+with Ada.Numerics.Elementary_Functions;
+use Ada.Numerics.Elementary_Functions;
+
+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);
+ end Super_Saw;
+
+ function Saw(Time : Float; Pitch : Float; Sample_Rate : Float) return Float is
+ Number_Of_Harmonics : Integer := 0;
+ Sample : Float := 0.0;
+ begin
+ while 2.0*Pi*Pitch*Float(Number_Of_Harmonics) < Sample_Rate/2.0 loop
+ Number_Of_Harmonics := Number_Of_Harmonics + 1;
+ end loop;
+
+ for I in 1 .. Number_Of_Harmonics loop
+ Sample := Sample + ((((1.0)**Float(I))*Sin(Float(I)*((2.0*Pi*Pitch)/Sample_Rate)*Time)));
+ end loop;
+ Sample := 0.5 - Sample/Pi;
+
+ -- Add a few extra sines to simulate aliasing above fundamental frequency of main oscillator
+ Simulate_Aliasing:for I in 1 .. Number_Of_Harmonics loop
+ if (0.5-2.0*Pi*Float(I)*Pitch/Sample_Rate) >= (2.0*Pi*Pitch)/Sample_Rate then
+ Sample := Sample + Sin((0.5-2.0*Pi*Float(I)*Pitch/Sample_Rate)*Time)*0.6;
+ end if;
+ end loop Simulate_Aliasing;
+
+ return Sample;
+ 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;
+
diff --git a/super_saw.ads b/super_saw.ads
new file mode 100644
index 0000000..676c0bf
--- /dev/null
+++ b/super_saw.ads
@@ -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;
+
diff --git a/super_saw.cpp b/super_saw.cpp
new file mode 100644
index 0000000..2ce1156
--- /dev/null
+++ b/super_saw.cpp
@@ -0,0 +1,69 @@
+#include <lv2synth.hpp>
+#include "super_saw.peg"
+#include <stdio.h>
+#include <math.h>
+extern "C" void adainit(void);
+extern "C" void adafinal(void);
+extern "C" float Super_Saw(float,float,float,float,float);
+
+class SuperSawVoice : public LV2::Voice {
+public:
+
+ SuperSawVoice(double rate)
+ : m_key(LV2::INVALID_KEY), m_rate(rate), m_period(10), m_counter(0) {
+ }
+
+ void on(unsigned char key, unsigned char velocity) {
+ m_key = key;
+ m_period = m_rate / LV2::key2hz(m_key);
+ }
+
+ void off(unsigned char velocity) {
+ m_key = LV2::INVALID_KEY;
+ }
+
+ unsigned char get_key() const {
+ return m_key;
+ }
+
+ void render(uint32_t from, uint32_t to) {
+ if (m_key == LV2::INVALID_KEY)
+ return;
+ for (uint32_t i = from; i < to; ++i) {
+ //Time, Pitch, Detune, Mix, Sample Rate
+ float detune = *p(p_Detune);
+ float mix = *p(p_Mix);
+ float s = Super_Saw(m_counter,LV2::key2hz(m_key),detune,mix,m_rate)/100.0;
+ p(p_left)[i] += s;
+ p(p_right)[i] += s;
+ m_counter = (m_counter + 1);// % m_period;
+ }
+ }
+
+protected:
+
+ unsigned char m_key;
+ double m_rate;
+ uint32_t m_period;
+ uint32_t m_counter;
+
+};
+
+
+class SuperSaw : public LV2::Synth<SuperSawVoice, SuperSaw> {
+public:
+ SuperSaw(double rate)
+ : LV2::Synth<SuperSawVoice, SuperSaw>(p_n_ports, p_midi) {
+ adainit();
+ add_voices(new SuperSawVoice(rate), new SuperSawVoice(rate), new SuperSawVoice(rate));
+ add_audio_outputs(p_left, p_right);
+ printf("Created object");
+ }
+ ~SuperSaw(){
+ adafinal();
+ }
+};
+
+
+static int _ = SuperSaw::register_class(p_uri);
+
diff --git a/super_saw.peg b/super_saw.peg
new file mode 100644
index 0000000..8cd49d8
--- /dev/null
+++ b/super_saw.peg
@@ -0,0 +1,39 @@
+#ifndef super_saw_peg
+#define super_saw_peg
+
+
+#ifndef PEG_STRUCT
+#define PEG_STRUCT
+typedef struct {
+ float min;
+ float max;
+ float default_value;
+ char toggled;
+ char integer;
+ char logarithmic;
+} peg_data_t;
+#endif
+
+/* <http://example.org/super_saw> */
+
+static const char p_uri[] = "http://example.org/super_saw";
+
+enum p_port_enum {
+ p_midi,
+ p_Detune,
+ p_Mix,
+ p_left,
+ p_right,
+ p_n_ports
+};
+
+static const peg_data_t p_ports[] = {
+ { -3.40282e+38, 3.40282e+38, -3.40282e+38, 0, 0, 0 },
+ { 0, 0.9, 0.5, 0, 0, 0 },
+ { 0, 1, 0.5, 0, 0, 0 },
+ { -3.40282e+38, 3.40282e+38, -3.40282e+38, 0, 0, 0 },
+ { -3.40282e+38, 3.40282e+38, -3.40282e+38, 0, 0, 0 },
+};
+
+
+#endif /* super_saw_peg */