Initial commit

master
cranix 2017-11-03 11:36:20 +01:00
commit 7bea14cf75
8 changed files with 578 additions and 0 deletions

23
Makefile Normal file
View File

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

139
b~super_saw.adb Normal file
View File

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

209
b~super_saw.ads Normal file
View File

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

5
manifest.ttl Normal file
View File

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

75
super_saw.adb Normal file
View File

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

19
super_saw.ads Normal file
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;

69
super_saw.cpp Normal file
View File

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

39
super_saw.peg Normal file
View File

@ -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 */