diff --git a/java/libraries/sound/.gitignore b/java/libraries/sound/.gitignore
new file mode 100644
index 000000000..06a0ef56d
--- /dev/null
+++ b/java/libraries/sound/.gitignore
@@ -0,0 +1,5 @@
+*.o
+*.class
+.DS_Store
+/distribution
+/bin
diff --git a/java/libraries/sound/build.xml b/java/libraries/sound/build.xml
new file mode 100755
index 000000000..7f403f259
--- /dev/null
+++ b/java/libraries/sound/build.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/java/libraries/sound/examples/Analysis/AmplitudeRMS/AmplitudeRMS.pde b/java/libraries/sound/examples/Analysis/AmplitudeRMS/AmplitudeRMS.pde
new file mode 100644
index 000000000..f13746792
--- /dev/null
+++ b/java/libraries/sound/examples/Analysis/AmplitudeRMS/AmplitudeRMS.pde
@@ -0,0 +1,41 @@
+/*
+This example shows how to use the RMS amplitude tracker. The tracker
+calculates the Root Mean Square over a block of audio and returns
+the mean as a float between 0 and 1.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SoundFile sample;
+Amplitude rms;
+
+int scale=1;
+
+public void setup() {
+ size(350,350);
+
+ // Create and start the sound renderer
+ stream = new Sound(this, 44100, 512);
+
+ //Load and play a soundfile and loop it
+ sample = new SoundFile(this, "beat.aiff");
+ sample.loop();
+
+ // Create and patch the rms tracker
+ rms = new Amplitude(this);
+ rms.input(sample);
+}
+
+public void draw() {
+ background(125,255,125);
+
+ // rms.process() return a value between 0 and 1. To adjust
+ // the scaling and mapping of an ellipse we scale from 0 to 0.5
+ scale=int(map(rms.process(), 0, 0.5, 1, 350));
+ noStroke();
+
+ fill(255,0,150);
+ // We draw an ellispe coupled to the audio analysis
+ ellipse(width/2, height/2, 1*scale, 1*scale);
+}
diff --git a/java/libraries/sound/examples/Analysis/AmplitudeRMS/data/beat.aiff b/java/libraries/sound/examples/Analysis/AmplitudeRMS/data/beat.aiff
new file mode 100644
index 000000000..017b7ce23
Binary files /dev/null and b/java/libraries/sound/examples/Analysis/AmplitudeRMS/data/beat.aiff differ
diff --git a/java/libraries/sound/examples/Analysis/FFTSpectrum/FFTSpectrum.pde b/java/libraries/sound/examples/Analysis/FFTSpectrum/FFTSpectrum.pde
new file mode 100644
index 000000000..7bc9af57e
--- /dev/null
+++ b/java/libraries/sound/examples/Analysis/FFTSpectrum/FFTSpectrum.pde
@@ -0,0 +1,47 @@
+/*
+This example shows how to use the Fast Fourier Transform function to get the spectrum
+of a sound. This function calculates the FFT of a signal and returns the positive normalized
+magnitude spectrum. This means we pass it the number of bands we want (the actual FFT size is
+two times that size) and a float array with the same size.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SoundFile sample;
+FFT fft;
+
+int scale=1;
+int bands=512;
+float[] spec = new float[bands];
+
+public void setup() {
+ size(bands,350);
+ background(255);
+
+ // Create and start the sound renderer
+ stream = new Sound(this, 44100, 256);
+
+ //Load and play a soundfile and loop it. This has to be called
+ // before the FFT is created.
+ sample = new SoundFile(this, "beat.aiff");
+ sample.loop();
+
+ // Create and patch the rms tracker
+ fft = new FFT(this);
+ fft.input(sample, bands);
+}
+
+public void draw() {
+ background(255);
+
+ fft.process(spec);
+
+ for(int i = 0; i < bands; i++)
+ {
+ // The result of the FFT is normalized
+ // draw the line for frequency band i scaling it up by 5 to get more amplitude.
+ line( i, height, i, height - spec[i]*height*5 );
+ }
+}
+
diff --git a/java/libraries/sound/examples/Analysis/FFTSpectrum/data/beat.aiff b/java/libraries/sound/examples/Analysis/FFTSpectrum/data/beat.aiff
new file mode 100644
index 000000000..017b7ce23
Binary files /dev/null and b/java/libraries/sound/examples/Analysis/FFTSpectrum/data/beat.aiff differ
diff --git a/java/libraries/sound/examples/Effects/Filter/BandPass/BandPass.pde b/java/libraries/sound/examples/Effects/Filter/BandPass/BandPass.pde
new file mode 100644
index 000000000..e7f9e422a
--- /dev/null
+++ b/java/libraries/sound/examples/Effects/Filter/BandPass/BandPass.pde
@@ -0,0 +1,31 @@
+/*
+This is a simple WhiteNoise generator. It can be started with .play(float amp).
+In this example it is started and stopped by clicking into the renderer window.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+WhiteNoise noise;
+BPF bandPass;
+
+float amp=0.0;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the noise generator
+ stream = new Sound(this);
+ noise = new WhiteNoise(this);
+ bandPass = new BPF(this);
+ noise.play(0.5);
+ bandPass.play(noise, 100);
+}
+
+void draw() {
+
+ bandPass.freq(map(mouseX, 0, 350, 20, 10000));
+
+ bandPass.res(map(mouseY, 0, 350, 0.05, 1.0));
+}
diff --git a/java/libraries/sound/examples/Effects/Filter/HighPass/HighPass.pde b/java/libraries/sound/examples/Effects/Filter/HighPass/HighPass.pde
new file mode 100644
index 000000000..546a86dd5
--- /dev/null
+++ b/java/libraries/sound/examples/Effects/Filter/HighPass/HighPass.pde
@@ -0,0 +1,29 @@
+/*
+This is a simple WhiteNoise generator. It can be started with .play(float amp).
+In this example it is started and stopped by clicking into the renderer window.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+WhiteNoise noise;
+HPF highPass;
+
+float amp=0.0;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the noise generator
+ stream = new Sound(this);
+ noise = new WhiteNoise(this);
+ highPass = new HPF(this);
+ noise.play(0.5);
+ highPass.play(noise, 100);
+}
+
+void draw() {
+
+ highPass.freq(map(mouseX, 0, 350, 20, 10000));
+}
diff --git a/java/libraries/sound/examples/Effects/Filter/LowPass/LowPass.pde b/java/libraries/sound/examples/Effects/Filter/LowPass/LowPass.pde
new file mode 100644
index 000000000..663b16b9e
--- /dev/null
+++ b/java/libraries/sound/examples/Effects/Filter/LowPass/LowPass.pde
@@ -0,0 +1,30 @@
+/*
+This is a simple WhiteNoise generator. It can be started with .play(float amp).
+In this example it is started and stopped by clicking into the renderer window.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+WhiteNoise noise;
+LPF lowPass;
+
+
+float amp=0.0;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the noise generator
+ stream = new Sound(this);
+ noise = new WhiteNoise(this);
+ lowPass = new LPF(this);
+ noise.play(0.5);
+ lowPass.play(noise, 100);
+}
+
+void draw() {
+
+ lowPass.freq(map(mouseX, 0, 350, 20, 10000));
+}
diff --git a/java/libraries/sound/examples/Effects/Variable_Delay/Variable_Delay.pde b/java/libraries/sound/examples/Effects/Variable_Delay/Variable_Delay.pde
new file mode 100644
index 000000000..52ae04f8f
--- /dev/null
+++ b/java/libraries/sound/examples/Effects/Variable_Delay/Variable_Delay.pde
@@ -0,0 +1,53 @@
+/*
+This is a sound file player.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SoundFile soundfile;
+Delay delay;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer
+ stream = new Sound(this);
+
+ //Load a soundfile
+ soundfile = new SoundFile(this, "vibraphon.aiff");
+
+ // create a Delay Effect
+ delay = new Delay(this);
+
+ // These methods return useful infos about the file
+ println("SFSampleRate= " + soundfile.sampleRate() + " Hz");
+ println("SFSamples= " + soundfile.frames() + " samples");
+ println("SFDuration= " + soundfile.duration() + " seconds");
+
+ // Play the file in a loop
+ soundfile.loop();
+
+ // Patch the delay
+ delay.play(soundfile, 5);
+}
+
+
+void draw() {
+ // Map mouseX from 0.25 to 4.0 for playback rate. 1 equals original playback
+ // speed 2 is an octave up 0.5 is an octave down.
+ soundfile.rate(map(mouseX, 0, 350, 0.25, 4.0));
+
+ // Map mouseY from 0.2 to 1.0 for amplitude
+ soundfile.amp(map(mouseY, 0, 350, 0.2, 1.0));
+
+ // Map mouseY from -1.0 to 1.0 for left to right
+ soundfile.pan(map(mouseY, 0, 350, -1.0, 1.0));
+
+ // Map mouseY from 0.001 to 2.0 seconds for the delaytime
+ delay.time(map(mouseY, 0, 350, 0.001, 2.0));
+
+ // Map mouseX from 0 to 0.8 for the delay feedback
+ delay.feedback(map(mouseX, 0, 350, 0.0, 0.8));
+}
diff --git a/java/libraries/sound/examples/Effects/Variable_Delay/data/vibraphon.aiff b/java/libraries/sound/examples/Effects/Variable_Delay/data/vibraphon.aiff
new file mode 100644
index 000000000..b4e95a3a9
Binary files /dev/null and b/java/libraries/sound/examples/Effects/Variable_Delay/data/vibraphon.aiff differ
diff --git a/java/libraries/sound/examples/Keyboard/data/1.aif b/java/libraries/sound/examples/Keyboard/data/1.aif
new file mode 100644
index 000000000..fd65b3123
Binary files /dev/null and b/java/libraries/sound/examples/Keyboard/data/1.aif differ
diff --git a/java/libraries/sound/examples/Keyboard/data/2.aif b/java/libraries/sound/examples/Keyboard/data/2.aif
new file mode 100644
index 000000000..742301e7a
Binary files /dev/null and b/java/libraries/sound/examples/Keyboard/data/2.aif differ
diff --git a/java/libraries/sound/examples/Keyboard/data/3.aif b/java/libraries/sound/examples/Keyboard/data/3.aif
new file mode 100644
index 000000000..7b8da50f3
Binary files /dev/null and b/java/libraries/sound/examples/Keyboard/data/3.aif differ
diff --git a/java/libraries/sound/examples/Keyboard/data/4.aif b/java/libraries/sound/examples/Keyboard/data/4.aif
new file mode 100644
index 000000000..7884a3418
Binary files /dev/null and b/java/libraries/sound/examples/Keyboard/data/4.aif differ
diff --git a/java/libraries/sound/examples/Keyboard/data/5.aif b/java/libraries/sound/examples/Keyboard/data/5.aif
new file mode 100644
index 000000000..5664dad51
Binary files /dev/null and b/java/libraries/sound/examples/Keyboard/data/5.aif differ
diff --git a/java/libraries/sound/examples/Keyboard/keyboard.pde b/java/libraries/sound/examples/Keyboard/keyboard.pde
new file mode 100644
index 000000000..73b32f5eb
--- /dev/null
+++ b/java/libraries/sound/examples/Keyboard/keyboard.pde
@@ -0,0 +1,138 @@
+/*
+This example shows how to make a simple sampler and sequencer with the Sound library. In this
+sketch 5 different short samples are loaded and played back at different pitches, in this
+case 5 different octaves. The sequencer triggers and event every 200-1000 mSecs randomly.
+Each time a sound is played a colored rect with a random color is displayed.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SoundFile[] file;
+
+// Define the number of samples
+int numsounds = 5;
+
+int value[] = {0,0,0};
+
+
+void setup(){
+ size(500, 500);
+ background(255);
+
+ // Create a Sound renderer and an array of empty soundfiles
+ stream = new Sound(this, 44100, 32);
+ file = new SoundFile[numsounds];
+
+ // Load 5 soundfiles from a folder in a for loop. By naming the files 1., 2., 3., n.aif it is easy to iterate
+ // through the folder and load all files in one line of code.
+ for (int i = 0; i < numsounds; i++){
+ file[i] = new SoundFile(this, (i+1) + ".aif");
+ }
+
+}
+
+void draw(){
+
+ background(value[0],value[1],value[2]);
+
+}
+
+
+
+void keyPressed() {
+ for (int i=0; i < 3; i++) {
+ value[i]=int(random(255));
+ };
+
+
+ switch(key){
+ case 'a':
+ file[0].play(0.5, 1.0);
+ break;
+
+ case 's':
+ file[1].play(0.5, 1.0);
+ break;
+
+ case 'd':
+ file[2].play(0.5, 1.0);
+ break;
+
+ case 'f':
+ file[3].play(0.5, 1.0);
+ break;
+
+ case 'g':
+ file[4].play(0.5, 1.0);
+ break;
+
+ case 'h':
+ file[0].play(1.0, 1.0);
+ break;
+
+ case 'j':
+ file[1].play(1.0, 1.0);
+ break;
+
+ case 'k':
+ file[2].play(1.0, 1.0);
+ break;
+
+ case 'l':
+ file[3].play(1.0, 1.0);
+ break;
+
+ case 'ö':
+ file[4].play(1.0, 1.0);
+ break;
+
+ case 'ä':
+ file[0].play(2.0, 1.0);
+ break;
+
+ case 'q':
+ file[1].play(2.0, 1.0);
+ break;
+
+ case 'w':
+ file[2].play(2.0, 1.0);
+ break;
+
+ case 'e':
+ file[3].play(2.0, 1.0);
+ break;
+
+ case 'r':
+ file[4].play(2.0, 1.0);
+ break;
+
+ case 't':
+ file[0].play(3.0, 1.0);
+ break;
+
+ case 'z':
+ file[1].play(3.0, 1.0);
+ break;
+
+ case 'u':
+ file[2].play(3.0, 1.0);
+ break;
+
+ case 'i':
+ file[3].play(3.0, 1.0);
+ break;
+
+ case 'o':
+ file[4].play(3.0, 1.0);
+ break;
+
+ case 'p':
+ file[0].play(4.0, 1.0);
+ break;
+
+ case 'ü':
+ file[1].play(4.0, 1.0);
+ break;
+ }
+}
diff --git a/java/libraries/sound/examples/Oscillators/Noise/Noise.pde b/java/libraries/sound/examples/Oscillators/Noise/Noise.pde
new file mode 100644
index 000000000..85fa9dfd2
--- /dev/null
+++ b/java/libraries/sound/examples/Oscillators/Noise/Noise.pde
@@ -0,0 +1,29 @@
+/*
+This is a simple WhiteNoise generator. It can be started with .play(float amp).
+In this example it is started and stopped by clicking into the renderer window.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+WhiteNoise noise;
+
+float amp=0.0;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the noise generator
+ stream = new Sound(this);
+ noise = new WhiteNoise(this);
+ noise.play();
+}
+
+void draw() {
+ // Map mouseX from 0.0 to 1.0 for amplitude
+ noise.amp(map(mouseX, 0, 350, 0.0, 1.0));
+
+ // Map mouseY from -1.0 to 1.0 for left to right
+ noise.pan(map(mouseY, 0, 350, -1.0, 1.0));
+}
diff --git a/java/libraries/sound/examples/Oscillators/PulseWidth/PulseWidth.pde b/java/libraries/sound/examples/Oscillators/PulseWidth/PulseWidth.pde
new file mode 100644
index 000000000..b009dbb96
--- /dev/null
+++ b/java/libraries/sound/examples/Oscillators/PulseWidth/PulseWidth.pde
@@ -0,0 +1,33 @@
+/*
+This is a pulse-wave oscillator. The method .play() starts the oscillator.
+There are several setters like .amp(), .freq(), .width(), .pan() and .add().
+If you want to set all of them at the same time use
+.set(float freq, float width, float amp, float add, float pan)
+*/
+
+import processing.sound.*;
+
+Sound stream;
+Pulse pulse;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the pulse wave oscillator
+ stream = new Sound(this);
+ pulse = new Pulse(this);
+ pulse.play();
+}
+
+void draw() {
+ // Map mouseX from 20Hz to 500Hz for frequency
+ pulse.freq(map(mouseX, 0, width, 20.0, 500.0));
+ // Map mouseX from 0.0 to 0.5 for amplitude
+ pulse.pan(map(mouseX, 0, width, -1.0, 1.0));
+ // Map mouseY from 0.0 to 0.5 for amplitude
+ pulse.amp(map(mouseY, 0, height, 0.0, 0.5));
+ // Map mouseY from 0.0 to 0.5 for amplitude
+ pulse.width(map(mouseY, 0, height, 0.0, 1.0));
+}
+
diff --git a/java/libraries/sound/examples/Oscillators/SawWave/SawWave.pde b/java/libraries/sound/examples/Oscillators/SawWave/SawWave.pde
new file mode 100644
index 000000000..a39377e76
--- /dev/null
+++ b/java/libraries/sound/examples/Oscillators/SawWave/SawWave.pde
@@ -0,0 +1,36 @@
+/*
+This is a saw-wave oscillator. The method .play() starts the oscillator. There
+are several setters like .amp(), .freq(), .pan() and .add(). If you want to set all of them at
+the same time use .set(float freq, float amp, float add, float pan)
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SawOsc saw;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the sine oscillator.
+ // Second and Third arguments are optional, default is 44100 / 512
+ // for Sample Rate and Buffer Size
+ stream = new Sound(this, 44100, 256);
+ saw = new SawOsc(this);
+
+ //Start the Sine Oscillator. There will be no sound in the beginning
+ //unless the mouse enters the
+ saw.play();
+}
+
+void draw() {
+ // Map mouseY from 0.0 to 1.0 for amplitude
+ saw.amp(map(mouseY, 0, height, 1.0, 0.0));
+
+ // Map mouseX from 20Hz to 1000Hz for frequency
+ saw.freq(map(mouseX, 0, width, 80.0, 200.0));
+
+ // Map mouseX from -1.0 to 1.0 for left to right
+ saw.pan(map(mouseX, 0, width, -1.0, 1.0));
+}
diff --git a/java/libraries/sound/examples/Oscillators/SineWave/SineWave.pde b/java/libraries/sound/examples/Oscillators/SineWave/SineWave.pde
new file mode 100644
index 000000000..3f1310491
--- /dev/null
+++ b/java/libraries/sound/examples/Oscillators/SineWave/SineWave.pde
@@ -0,0 +1,43 @@
+/*
+This is a sine-wave oscillator. The method .play() starts the oscillator. There
+are several setters like .amp(), .freq(), .pan() and .add(). If you want to set all of them at
+the same time use .set(float freq, float amp, float add, float pan)
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SinOsc sine;
+
+float freq=400;
+float amp=0.5;
+float pos;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the sine oscillator.
+ // Second and Third arguments are optional, default is 44100 / 512
+ // for Sample Rate and Buffer Size
+ stream = new Sound(this, 44100, 256);
+ sine = new SinOsc(this);
+
+ //Start the Sine Oscillator.
+ sine.play();
+}
+
+void draw() {
+
+ // Map mouseY from 0.0 to 1.0 for amplitude
+ amp=map(mouseY, 0, height, 1.0, 0.0);
+ sine.amp(amp);
+
+ // Map mouseX from 20Hz to 1000Hz for frequency
+ freq=map(mouseX, 0, width, 80.0, 1000.0);
+ sine.freq(freq);
+
+ // Map mouseX from -1.0 to 1.0 for left to right
+ pos=map(mouseX, 0, width, -1.0, 1.0);
+ sine.pan(pos);
+}
diff --git a/java/libraries/sound/examples/Oscillators/SqrWave/SqrWave.pde b/java/libraries/sound/examples/Oscillators/SqrWave/SqrWave.pde
new file mode 100644
index 000000000..0c4597a6b
--- /dev/null
+++ b/java/libraries/sound/examples/Oscillators/SqrWave/SqrWave.pde
@@ -0,0 +1,36 @@
+/*
+This is a saw-wave oscillator. The method .play() starts the oscillator. There
+are several setters like .amp(), .freq(), .pan() and .add(). If you want to set all of them at
+the same time use .set(float freq, float amp, float add, float pan)
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SqrOsc sqr;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the sine oscillator.
+ // Second and Third arguments are optional, default is 44100 / 512
+ // for Sample Rate and Buffer Size
+ stream = new Sound(this, 44100, 256);
+ sqr = new SqrOsc(this);
+
+ //Start the Sine Oscillator. There will be no sound in the beginning
+ //unless the mouse enters the
+ sqr.play();
+}
+
+void draw() {
+ // Map mouseY from 0.0 to 1.0 for amplitude
+ sqr.amp(map(mouseY, 0, height, 1.0, 0.0));
+
+ // Map mouseX from 20Hz to 1000Hz for frequency
+ sqr.freq(map(mouseX, 0, width, 80.0, 200.0));
+
+ // Map mouseX from -1.0 to 1.0 for left to right
+ sqr.pan(map(mouseX, 0, width, -1.0, 1.0));
+}
diff --git a/java/libraries/sound/examples/Oscillators/TriWave/TriWave.pde b/java/libraries/sound/examples/Oscillators/TriWave/TriWave.pde
new file mode 100644
index 000000000..ec2ebefac
--- /dev/null
+++ b/java/libraries/sound/examples/Oscillators/TriWave/TriWave.pde
@@ -0,0 +1,36 @@
+/*
+This is a saw-wave oscillator. The method .play() starts the oscillator. There
+are several setters like .amp(), .freq(), .pan() and .add(). If you want to set all of them at
+the same time use .set(float freq, float amp, float add, float pan)
+*/
+
+import processing.sound.*;
+
+Sound stream;
+TriOsc tri;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer and the sine oscillator.
+ // Second and Third arguments are optional, default is 44100 / 512
+ // for Sample Rate and Buffer Size
+ stream = new Sound(this, 44100, 256);
+ tri = new TriOsc(this);
+
+ //Start the Sine Oscillator. There will be no sound in the beginning
+ //unless the mouse enters the
+ tri.play();
+}
+
+void draw() {
+ // Map mouseY from 0.0 to 1.0 for amplitude
+ tri.amp(map(mouseY, 0, height, 1.0, 0.0));
+
+ // Map mouseX from 20Hz to 1000Hz for frequency
+ tri.freq(map(mouseX, 0, width, 80.0, 1000.0));
+
+ // Map mouseX from -1.0 to 1.0 for left to right
+ tri.pan(map(mouseX, 0, width, -1.0, 1.0));
+}
diff --git a/java/libraries/sound/examples/Soundfiles/Sample/Sample.pde b/java/libraries/sound/examples/Soundfiles/Sample/Sample.pde
new file mode 100644
index 000000000..3f5aa8278
--- /dev/null
+++ b/java/libraries/sound/examples/Soundfiles/Sample/Sample.pde
@@ -0,0 +1,42 @@
+/*
+This is a sound file player.
+*/
+
+
+import processing.sound.*;
+
+Sound stream;
+SoundFile soundfile;
+
+void setup() {
+ size(350,350);
+ background(255);
+
+ // Create and start the sound renderer
+ stream = new Sound(this);
+
+ //Load a soundfile
+ soundfile = new SoundFile(this, "vibraphon.aiff");
+
+ // These methods return useful infos about the file
+ println("SFSampleRate= " + soundfile.sampleRate() + " Hz");
+ println("SFSamples= " + soundfile.frames() + " samples");
+ println("SFDuration= " + soundfile.duration() + " seconds");
+
+ // Play the file in a loop
+ soundfile.loop();
+}
+
+
+void draw() {
+ // Map mouseX from 0.25 to 4.0 for playback rate. 1 equals original playback
+ // speed 2 is an octave up 0.5 is an octave down.
+ soundfile.rate(map(mouseX, 0, 350, 0.25, 4.0));
+
+ // Map mouseY from 0.2 to 1.0 for amplitude
+ soundfile.amp(map(mouseY, 0, 350, 0.2, 1.0));
+
+ // Map mouseY from -1.0 to 1.0 for left to right
+ soundfile.pan(map(mouseY, 0, 350, -1.0, 1.0));
+}
+
diff --git a/java/libraries/sound/examples/Soundfiles/Sample/data/vibraphon.aiff b/java/libraries/sound/examples/Soundfiles/Sample/data/vibraphon.aiff
new file mode 100644
index 000000000..b4e95a3a9
Binary files /dev/null and b/java/libraries/sound/examples/Soundfiles/Sample/data/vibraphon.aiff differ
diff --git a/java/libraries/sound/examples/processing_handbook/ex1/ex1.pde b/java/libraries/sound/examples/processing_handbook/ex1/ex1.pde
new file mode 100644
index 000000000..7d5f701e3
--- /dev/null
+++ b/java/libraries/sound/examples/processing_handbook/ex1/ex1.pde
@@ -0,0 +1,60 @@
+/*
+This example shows how to create a cluster of sine oscillators, change the frequency and detune them
+depending on the position of the mouse in the renderer window. The Y position determines the basic
+frequency of the oscillator and X the detuning of the oscillator. The basic frequncy ranges between
+150 and 1150 Hz.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SinOsc[] sineWaves;
+
+// The number of oscillators
+int numSines = 5;
+
+// A float for calculating the amplitudes
+float[] sineVolume;
+
+void setup() {
+ size(500, 500);
+ background(255);
+
+ //Create and start the Sound renderer
+ stream = new Sound(this);
+
+ // Create the oscillators and amplitudes
+ sineWaves = new SinOsc[numSines];
+ sineVolume = new float[numSines];
+
+ for (int i = 0; i < numSines; i++) {
+
+ // The overall amplitude shouldn't exceed 1.0 which is prevented by 1.0/numSines.
+ // The ascending waves will get lower in volume the higher the frequency
+ sineVolume[i] = (1.0 / numSines) / (i + 1);
+
+ // Create the Sine Oscillators and start them
+ sineWaves[i] = new SinOsc(this);
+ sineWaves[i].play();
+ }
+}
+
+void draw() {
+ noStroke();
+
+ // Map mouseY to get values from 0.0 to 1.0
+ float yoffset = (height - mouseY) / float(height);
+
+ // Map that value logarithmically to 150 - 1150 Hz
+ float frequency = pow(1000, yoffset) + 150;
+
+ // Map mouseX from -0.5 to 0.5 to get a multiplier for detuning the oscillators
+ float detune = float(mouseX) / width - 0.5;
+
+ // Set the frequencies, detuning and volume
+ for (int i = 0; i < numSines; i++) {
+ sineWaves[i].freq(frequency * (i + 1 + i * detune));
+ sineWaves[i].amp(sineVolume[i]);
+
+ }
+}
diff --git a/java/libraries/sound/examples/processing_handbook/ex2/ex2.pde b/java/libraries/sound/examples/processing_handbook/ex2/ex2.pde
new file mode 100644
index 000000000..72f212f2d
--- /dev/null
+++ b/java/libraries/sound/examples/processing_handbook/ex2/ex2.pde
@@ -0,0 +1,79 @@
+/*
+This sketch shows how to use envelopes and oscillators. Envelopes are pre-defined amplitude
+distribution over time. The sound library provides an ASR envelope which stands for attach,
+sustain, release. The amplitude rises then sustains at the maximum level and decays slowly
+depending on pre defined time segments.
+
+ .________
+ . ---
+ . ---
+ . ---
+ A S R
+
+*/
+
+import processing.sound.*;
+
+Sound stream;
+TriOsc triOsc;
+Env env;
+
+// Times and levels for the ASR envelope
+float attackTime = 0.001;
+float sustainTime = 0.004;
+float sustainLevel = 0.3;
+float releaseTime = 0.4;
+
+// This is an octave in MIDI notes.
+int[] midiSequence = { 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72};
+int duration = 200;
+// Set the note trigger
+int trigger = millis();
+
+// An index to count up the notes
+int note=0;
+
+void setup() {
+ size(200, 200);
+ background(255);
+
+ //Create and start the Sound renderer
+ stream = new Sound(this);
+
+ // Create triangle wave and start it
+ triOsc = new TriOsc(this);
+ //triOsc.play();
+
+ // Create the envelope
+ env = new Env(this);
+
+}
+
+void draw() {
+
+ // If the determined trigger moment in time matches up with the computer clock and we if the
+ // sequence of notes hasn't been finished yet the next note gets played.
+ if ((millis() > trigger) && (note trigger){
+ // Redraw the background every time to erase old rects
+ background(255);
+
+ // By iterating through the playSound array we check for 1 or 0, 1 plays a sound and draws a rect,
+ // for 0 nothing happens.
+
+ for (int i = 0; i < numsounds; i++){
+ // Check which indexes are 1 and 0.
+ if (playSound[i] == 1){
+ float rate;
+ // Choose a random color and get set to noStroke()
+ fill(int(random(255)),int(random(255)),int(random(255)));
+ noStroke();
+ // Draw the rect in the positions we defined earlier in posx
+ rect(posx[i], 50, 100, 200);
+ // Choose a random index of the octave array
+ rate = octave[int(random(0,5))];
+ // Play the soundfile from the array with the respective rate and loop set to false
+ file[i].play(rate, 1.0);
+ }
+
+ // Renew the indexes of playSound so that at the next event the order is different and randomized.
+ playSound[i] = int(random(0,2));
+ };
+
+ // Create a new triggertime in the future, with a random offset between 200 and 1000 milliseconds
+ trigger = millis() + int(random(200,1000));
+ }
+}
diff --git a/java/libraries/sound/examples/processing_handbook/ex5/data/beat.aiff b/java/libraries/sound/examples/processing_handbook/ex5/data/beat.aiff
new file mode 100644
index 000000000..017b7ce23
Binary files /dev/null and b/java/libraries/sound/examples/processing_handbook/ex5/data/beat.aiff differ
diff --git a/java/libraries/sound/examples/processing_handbook/ex5/ex5.pde b/java/libraries/sound/examples/processing_handbook/ex5/ex5.pde
new file mode 100644
index 000000000..40a478b47
--- /dev/null
+++ b/java/libraries/sound/examples/processing_handbook/ex5/ex5.pde
@@ -0,0 +1,47 @@
+/*
+This example shows how to use the Fast Fourier Transform function to get the spectrum
+of a sound. This function calculates the FFT of a signal and returns the positive normalized
+magnitude spectrum. This means we pass it the number of bands we want (the actual FFT size is
+two times that size) and a float array with the same size.
+*/
+
+import processing.sound.*;
+
+Sound stream;
+SoundFile sample;
+FFT fft;
+
+int scale=1;
+int bands=512;
+float[] spec = new float[bands];
+
+public void setup() {
+ size(bands,350);
+ background(255);
+
+ // Create and start the sound renderer
+ stream = new Sound(this, 44100, 256);
+
+ //Load and play a soundfile and loop it. This has to be called
+ // before the FFT is created.
+ sample = new SoundFile(this, "beat.aiff");
+ sample.play(true);
+
+ // Create and patch the rms tracker
+ fft = new FFT(this);
+ fft.input(sample, bands);
+}
+
+public void draw() {
+ background(255);
+
+ fft.process(spec);
+
+ for(int i = 0; i < bands; i++)
+ {
+ // The result of the FFT is normalized
+ // draw the line for frequency band i scaling it up by 5 to get more amplitude.
+ line( i, height, i, height - spec[i]*height*5 );
+ }
+}
+
diff --git a/java/libraries/sound/library/README.txt b/java/libraries/sound/library/README.txt
new file mode 100644
index 000000000..525b4b317
--- /dev/null
+++ b/java/libraries/sound/library/README.txt
@@ -0,0 +1,22 @@
+
+
+
+# Processing MethCla Interface
+
+This is a processing interface and a collection of plugins for MethCla, a leight-weight, efficient sound engine for mobile devices [methcla](http://methc.la).
+
+## Executable
+
+Download the current version of the library here:
+
+[Sound](https://github.com/wirsing/ProcessingSound/releases)
+
+
+## Building the libMethClaInterface
+
+The library requires a compiled shared library of MethCla for each platform. There are specific Makefile in the src folder which compile the JNI library. For the moment this library is OsX only.
+
+The Java Library is to be compiled with ant. Please install the latest version on ant on your computer. The build.xml file is in resources. To compile do
+
+$ cd resources
+$ ant
diff --git a/java/libraries/sound/src/cpp/MakeFile_Linux b/java/libraries/sound/src/cpp/MakeFile_Linux
new file mode 100644
index 000000000..52004b60c
--- /dev/null
+++ b/java/libraries/sound/src/cpp/MakeFile_Linux
@@ -0,0 +1,12 @@
+all:
+
+ gcc -fPIC -I/usr/local/java/jdk1.7.0_60/include/linux -I./include -I/usr/local/java/jdk1.7.0_60/include -std=c++11 -g -c processing_sound_MethClaInterface.cpp;
+ gcc -shared -o libMethClaInterface.so *.o -lmethcla;
+
+clean:
+ rm *.o
+ rm *.jnilib
+
+install:
+ cp libMethClaInterface.so ../../library/linux
+
diff --git a/java/libraries/sound/src/cpp/MakeFile_Win b/java/libraries/sound/src/cpp/MakeFile_Win
new file mode 100644
index 000000000..f4816d288
--- /dev/null
+++ b/java/libraries/sound/src/cpp/MakeFile_Win
@@ -0,0 +1,11 @@
+all:
+
+ g++ -Ic:/Java/jdk1.7.0_60/include -Ic:/Java/jdk1.7.0_60/include/win32 -I./include -std=c++11 -g -c processing_sound_MethClaInterface.cpp;
+ g++ -dynamiclib -lmethcla -L../../library/macosx/ -o libMethClaInterface.jnilib *.o;
+
+clean:
+ rm *.o
+ rm *.jnilib
+
+install:
+ cp libMethClaInterface.jnilib ../../lib/macosx
diff --git a/java/libraries/sound/src/cpp/Makefile_Darwin b/java/libraries/sound/src/cpp/Makefile_Darwin
new file mode 100644
index 000000000..7ac3036da
--- /dev/null
+++ b/java/libraries/sound/src/cpp/Makefile_Darwin
@@ -0,0 +1,10 @@
+all:
+ g++ -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers -I./include -std=c++11 -g -c processing_sound_MethClaInterface.cpp;
+ g++ -dynamiclib -lmethcla -L../../library/macosx/ -o libMethClaInterface.jnilib *.o;
+
+clean:
+ rm *.o
+ rm *.jnilib
+
+install:
+ cp libMethClaInterface.jnilib ../../library/macosx
diff --git a/java/libraries/sound/src/cpp/include/methcla/common.h b/java/libraries/sound/src/cpp/include/methcla/common.h
new file mode 100644
index 000000000..2cdb58a5b
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/common.h
@@ -0,0 +1,153 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_COMMON_H_INCLUDED
+#define METHCLA_COMMON_H_INCLUDED
+
+#include
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#if defined(__cplusplus)
+# define METHCLA_C_LINKAGE extern "C"
+#else
+# define METHCLA_C_LINKAGE
+#endif
+
+#if defined _WIN32 || defined __CYGWIN__
+ #if defined(BUILDING_DLL)
+ #if defined(__GNUC__) || defined(__clang__)
+ #define METHCLA_VISIBLE __attribute__ ((dllexport))
+ #else
+ #define METHCLA_VISIBLE __declspec(dllexport) // Note: actually gcc seems to also supports this syntax.
+ #endif
+ #else
+ #if defined(__GNUC__) || defined(__clang__)
+ #define METHCLA_VISIBLE __attribute__ ((dllimport))
+ #else
+ #define METHCLA_VISIBLE __declspec(dllimport) // Note: actually gcc seems to also supports this syntax.
+ #endif
+ #endif
+#else
+ #if (__GNUC__ >= 4) || (defined(__clang__) && (__clang_major__ >= 4))
+ #define METHCLA_VISIBLE __attribute__ ((visibility ("default")))
+ #else
+ #define METHCLA_VISIBLE
+ #endif
+#endif
+
+#define METHCLA_EXPORT METHCLA_C_LINKAGE METHCLA_VISIBLE
+
+//* Time in seconds.
+typedef double Methcla_Time;
+
+typedef struct
+{
+ const void* data;
+ size_t size;
+} Methcla_OSCPacket;
+
+typedef enum
+{
+ kMethcla_NoError = 0,
+
+ /* Generic error codes */
+ kMethcla_UnspecifiedError,
+ kMethcla_LogicError,
+ kMethcla_ArgumentError,
+ kMethcla_MemoryError,
+ kMethcla_UnimplementedError,
+ kMethcla_SystemError,
+
+ /* Engine errors */
+ kMethcla_SynthDefNotFoundError = 1000,
+ kMethcla_NodeIdError,
+ kMethcla_NodeTypeError,
+
+ /* File errors */
+ kMethcla_FileNotFoundError = 2000,
+ kMethcla_FileExistsError,
+ kMethcla_PermissionsError,
+ kMethcla_UnsupportedFileTypeError,
+ kMethcla_UnsupportedDataFormatError,
+ kMethcla_InvalidFileError,
+
+ /* Audio driver errors */
+ kMethcla_DeviceUnavailableError = 3000,
+} Methcla_ErrorCode;
+
+METHCLA_EXPORT const char* methcla_error_code_description(Methcla_ErrorCode code);
+
+typedef struct Methcla_Error
+{
+ Methcla_ErrorCode error_code;
+ char* error_message;
+} Methcla_Error;
+
+static inline bool methcla_is_ok(const Methcla_Error error)
+{
+ return error.error_code == kMethcla_NoError;
+}
+
+static inline bool methcla_is_error(const Methcla_Error error)
+{
+ return error.error_code != kMethcla_NoError;
+}
+
+static inline bool methcla_error_has_code(const Methcla_Error error, Methcla_ErrorCode code)
+{
+ return error.error_code == code;
+}
+
+static inline Methcla_ErrorCode methcla_error_code(const Methcla_Error error)
+{
+ return error.error_code;
+}
+
+static inline const char* methcla_error_message(const Methcla_Error error)
+{
+ return error.error_message;
+}
+
+//* Create a new Methcla_Error with a specific error code.
+// The error message is set to NULL.
+METHCLA_EXPORT Methcla_Error methcla_error_new(Methcla_ErrorCode code);
+
+//* Create a new Methcla_Error with a specific error code and message.
+METHCLA_EXPORT Methcla_Error methcla_error_new_with_message(Methcla_ErrorCode code, const char* message);
+
+//* Free the resources associated with a Methcla_Error.
+METHCLA_EXPORT void methcla_error_free(Methcla_Error error);
+
+//* Return a Methcla_Error indicating that no error has occurred.
+static inline Methcla_Error methcla_no_error()
+{
+ return methcla_error_new(kMethcla_NoError);
+}
+
+//* Audio sample type
+typedef float Methcla_AudioSample;
+
+METHCLA_EXPORT void methcla_init();
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* METHCLA_COMMON_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/detail.hpp b/java/libraries/sound/src/cpp/include/methcla/detail.hpp
new file mode 100644
index 000000000..a09a7d960
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/detail.hpp
@@ -0,0 +1,98 @@
+// Copyright 2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_DETAIL_HPP_INCLUDED
+#define METHCLA_DETAIL_HPP_INCLUDED
+
+#include
+#include
+#include
+
+#include
+
+namespace Methcla
+{
+ namespace detail
+ {
+ template class Id
+ {
+ public:
+ explicit Id(T id)
+ : m_id(id)
+ { }
+ Id(const D& other)
+ : m_id(other.m_id)
+ { }
+
+ T id() const
+ {
+ return m_id;
+ }
+
+ bool operator==(const D& other) const
+ {
+ return m_id == other.m_id;
+ }
+
+ bool operator!=(const D& other) const
+ {
+ return m_id != other.m_id;
+ }
+
+ private:
+ T m_id;
+ };
+
+ inline static void throwError(Methcla_Error err)
+ {
+ if (methcla_is_error(err))
+ {
+ if (methcla_error_has_code(err, kMethcla_ArgumentError)) {
+ std::string msg(methcla_error_message(err));
+ methcla_error_free(err);
+ throw std::invalid_argument(msg);
+ } else if (methcla_error_has_code(err, kMethcla_LogicError)) {
+ std::string msg(methcla_error_message(err));
+ methcla_error_free(err);
+ throw std::logic_error(msg);
+ } else if (methcla_error_has_code(err, kMethcla_MemoryError)) {
+ methcla_error_free(err);
+ throw std::bad_alloc();
+ } else {
+ std::string msg( methcla_error_message(err)
+ ? methcla_error_message(err)
+ : methcla_error_code_description(methcla_error_code(err)));
+ methcla_error_free(err);
+ throw std::runtime_error(msg);
+ }
+ }
+ }
+
+ inline static void checkReturnCode(Methcla_Error err)
+ {
+ throwError(err);
+ }
+
+ template T combineFlags(T a, T b)
+ {
+ // FIXME: Not available in GCC 4.6, Clang 3.3
+ // typedef typename std::underlying_type::type enum_type;
+ typedef int enum_type;
+ static_assert(sizeof(T) <= sizeof(enum_type), "combineFlags: Cannot determine underlying enum type");
+ return static_cast(static_cast(a) | static_cast(b));
+ }
+ }
+}
+
+#endif // METHCLA_DETAIL_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/detail/result.hpp b/java/libraries/sound/src/cpp/include/methcla/detail/result.hpp
new file mode 100644
index 000000000..bf1bf4e33
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/detail/result.hpp
@@ -0,0 +1,171 @@
+// Copyright 2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_DETAIL_RESULT_HPP_INCLUDED
+#define METHCLA_DETAIL_RESULT_HPP_INCLUDED
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+
+namespace Methcla
+{
+ namespace detail
+ {
+ class ResultBase
+ {
+ std::condition_variable m_cond_var;
+
+ protected:
+ std::mutex m_mutex;
+ bool m_cond;
+ Methcla_ErrorCode m_error;
+ std::string m_errorMessage;
+
+ public:
+ ResultBase()
+ : m_cond(false)
+ , m_error(kMethcla_NoError)
+ { }
+
+ ResultBase(const ResultBase&) = delete;
+ ResultBase& operator=(const ResultBase&) = delete;
+
+ void checkResponse(const char* requestAddress, const OSCPP::Server::Message& msg)
+ {
+ if (msg == "/error")
+ {
+ auto args(msg.args());
+ Methcla_ErrorCode errorCode = static_cast(args.int32());
+ const char* errorMessage = args.string();
+ setError(errorCode, errorMessage);
+ }
+ else if (msg != requestAddress)
+ {
+ std::stringstream s;
+ s << "Unexpected response message address " << msg.address() << " (expected " << requestAddress << ")";
+ setError(kMethcla_LogicError, s.str().c_str());
+ }
+ }
+
+ protected:
+ inline void notify()
+ {
+ m_cond = true;
+ m_cond_var.notify_one();
+ }
+
+ inline void wait()
+ {
+ std::unique_lock lock(m_mutex);
+ while (!m_cond) {
+ m_cond_var.wait(lock);
+ }
+ if (m_error != kMethcla_NoError) {
+ throwError(methcla_error_new_with_message(m_error, m_errorMessage.c_str()));
+ }
+ }
+
+ void setError(Methcla_ErrorCode error, const char* message)
+ {
+ std::lock_guard lock(m_mutex);
+ if (m_cond)
+ {
+ m_error = kMethcla_LogicError;
+ m_errorMessage = "Result error already set";
+ }
+ else
+ {
+ m_error = error;
+ m_errorMessage = message;
+ }
+ notify();
+ }
+ };
+
+ template class Result : public ResultBase
+ {
+ public:
+ void set(Methcla_ErrorCode error, const char* message)
+ {
+ setError(error, message);
+ }
+
+ void set(const T& value)
+ {
+ std::lock_guard lock(m_mutex);
+ if (m_error == kMethcla_NoError)
+ {
+ if (m_cond)
+ {
+ m_error = kMethcla_LogicError;
+ m_errorMessage = "Result already set";
+ }
+ else
+ {
+ m_value = value;
+ notify();
+ }
+ }
+ }
+
+ const T& get()
+ {
+ wait();
+ return m_value;
+ }
+
+ private:
+ T m_value;
+ };
+
+ template <> class Result : public ResultBase
+ {
+ public:
+ void set(Methcla_ErrorCode error, const char* message)
+ {
+ setError(error, message);
+ }
+
+ void set()
+ {
+ std::lock_guard lock(m_mutex);
+ if (m_error == kMethcla_NoError)
+ {
+ if (m_cond)
+ {
+ m_error = kMethcla_LogicError;
+ m_errorMessage = "Result already set";
+ }
+ else
+ {
+ notify();
+ }
+ }
+ }
+
+ void get()
+ {
+ wait();
+ }
+ };
+ }
+}
+
+#endif // METHCLA_DETAIL_RESULT_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/engine.h b/java/libraries/sound/src/cpp/include/methcla/engine.h
new file mode 100644
index 000000000..a820885a2
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/engine.h
@@ -0,0 +1,155 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_ENGINE_H_INCLUDED
+#define METHCLA_ENGINE_H_INCLUDED
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+//* Return library version string.
+const char* methcla_version();
+
+//* Return true if using the pro version of methcla.
+static inline bool methcla_version_is_pro()
+{
+ return strstr(methcla_version(), "pro") != NULL;
+}
+
+//* Common audio driver options.
+typedef struct Methcla_AudioDriverOptions
+{
+ int sample_rate;
+ int num_inputs;
+ int num_outputs;
+ int buffer_size;
+} Methcla_AudioDriverOptions;
+
+//* Abstract audio driver type.
+typedef struct Methcla_AudioDriver Methcla_AudioDriver;
+
+//* Initialize audio options.
+METHCLA_EXPORT void methcla_audio_driver_options_init(Methcla_AudioDriverOptions* options);
+
+//* Return default audio driver for this platform.
+METHCLA_EXPORT Methcla_Error methcla_default_audio_driver(const Methcla_AudioDriverOptions* options, Methcla_AudioDriver** outDriver);
+
+//* An integral type for uniquely identifying requests sent to the engine.
+typedef int32_t Methcla_RequestId;
+
+enum
+{
+ //* Request id reserved for asynchronous notifications.
+ // Clients should not use this id when sending requests to the engine.
+ kMethcla_Notification = 0
+};
+
+//* Callback closure type for handling OSC packets coming from the engine.
+// Packets can be either responses to previously issued requests, or, if request_id is equal to kMethcla_Notification, an asynchronous notification.
+typedef struct Methcla_PacketHandler
+{
+ void* handle;
+ void (*handle_packet)(void* handle, Methcla_RequestId request_id, const void* packet, size_t size);
+} Methcla_PacketHandler;
+
+typedef struct Methcla_EngineOptions Methcla_EngineOptions;
+
+struct Methcla_EngineOptions
+{
+ Methcla_LogHandler log_handler;
+ Methcla_PacketHandler packet_handler;
+
+ size_t sample_rate;
+ size_t block_size;
+
+ size_t realtime_memory_size;
+ size_t max_num_nodes;
+ size_t max_num_audio_buses;
+
+ //* NULL terminated array of plugin library functions.
+ Methcla_LibraryFunction* plugin_libraries;
+};
+
+METHCLA_EXPORT void methcla_engine_options_init(Methcla_EngineOptions* options);
+
+//* Abstract type for the sound engine.
+typedef struct Methcla_Engine Methcla_Engine;
+
+//* Create a new engine with the given options and an audio driver.
+METHCLA_EXPORT Methcla_Error methcla_engine_new_with_driver(
+ const Methcla_EngineOptions* options,
+ Methcla_AudioDriver* driver,
+ Methcla_Engine** engine
+ );
+
+//* Free the resources associated with engine.
+//
+// Dereferencing engine after this function returns results in undefined behavior.
+METHCLA_EXPORT void methcla_engine_free(Methcla_Engine* engine);
+
+//* Return the last error code.
+// METHCLA_EXPORT Methcla_Error methcla_engine_error(const Methcla_Engine* engine);
+
+//* Start the engine.
+METHCLA_EXPORT Methcla_Error methcla_engine_start(Methcla_Engine* engine);
+
+//* Stop the engine.
+METHCLA_EXPORT Methcla_Error methcla_engine_stop(Methcla_Engine* engine);
+
+enum Methcla_EngineLogFlags
+{
+ kMethcla_EngineLogDefault = 0x00,
+ kMethcla_EngineLogDebug = 0x01,
+ kMethcla_EngineLogRequests = 0x02
+};
+
+//* Set flags for debug logging.
+METHCLA_EXPORT void methcla_engine_set_log_flags(Methcla_Engine* engine, Methcla_EngineLogFlags flags);
+
+//* Log a line using the registered log handler.
+METHCLA_EXPORT void methcla_engine_log_line(Methcla_Engine* engine, Methcla_LogLevel level, const char* message);
+
+//* Encode a Methcla_Time value as a 64 bit unsigned integer.
+METHCLA_EXPORT uint64_t methcla_time_to_uint64(Methcla_Time time);
+
+//* Decode a Methcla_Time value from a 64 bit unsigned integer.
+METHCLA_EXPORT Methcla_Time methcla_time_from_uint64(uint64_t time);
+
+//* Get the current time.
+METHCLA_EXPORT Methcla_Time methcla_engine_current_time(Methcla_Engine* engine);
+
+//* Send an OSC packet to the engine.
+METHCLA_EXPORT Methcla_Error methcla_engine_send(Methcla_Engine* engine, const void* packet, size_t size);
+
+//* Open a sound file.
+METHCLA_EXPORT Methcla_Error methcla_engine_soundfile_open(const Methcla_Engine* engine, const char* path, Methcla_FileMode mode, Methcla_SoundFile** file, Methcla_SoundFileInfo* info);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* METHCLA_ENGINE_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/engine.hpp b/java/libraries/sound/src/cpp/include/methcla/engine.hpp
new file mode 100644
index 000000000..f42b759c7
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/engine.hpp
@@ -0,0 +1,1146 @@
+// Copyright 2012-2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_ENGINE_HPP_INCLUDED
+#define METHCLA_ENGINE_HPP_INCLUDED
+
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+namespace Methcla
+{
+ static inline const char* version()
+ {
+ return methcla_version();
+ }
+
+ namespace Version
+ {
+ static inline bool isPro()
+ {
+ return methcla_version_is_pro();
+ }
+ };
+
+ inline static void dumpRequest(std::ostream& out, const OSCPP::Client::Packet& packet)
+ {
+ out << "Request (send): " << packet << std::endl;
+ }
+
+ class NodeId : public detail::Id
+ {
+ public:
+ NodeId(int32_t id)
+ : Id(id)
+ { }
+ NodeId()
+ : NodeId(-1)
+ { }
+ };
+
+ class GroupId : public NodeId
+ {
+ public:
+ // Inheriting constructors not supported by clang 3.2
+ // using NodeId::NodeId;
+ GroupId(int32_t id)
+ : NodeId(id)
+ { }
+ GroupId()
+ : NodeId()
+ { }
+ };
+
+ class SynthId : public NodeId
+ {
+ public:
+ SynthId(int32_t id)
+ : NodeId(id)
+ { }
+ SynthId()
+ : NodeId()
+ { }
+ };
+
+ class AudioBusId : public detail::Id
+ {
+ public:
+ AudioBusId(int32_t id)
+ : Id(id)
+ { }
+ AudioBusId()
+ : AudioBusId(0)
+ { }
+ };
+
+ // Node placement specification given a target.
+ class NodePlacement
+ {
+ NodeId m_target;
+ Methcla_NodePlacement m_placement;
+
+ public:
+ NodePlacement(NodeId target, Methcla_NodePlacement placement)
+ : m_target(target)
+ , m_placement(placement)
+ { }
+
+ NodePlacement(GroupId target)
+ : NodePlacement(target, kMethcla_NodePlacementTailOfGroup)
+ { }
+
+ NodeId target() const
+ {
+ return m_target;
+ }
+
+ Methcla_NodePlacement placement() const
+ {
+ return m_placement;
+ }
+
+ static NodePlacement head(GroupId target)
+ {
+ return NodePlacement(target, kMethcla_NodePlacementHeadOfGroup);
+ }
+
+ static NodePlacement tail(GroupId target)
+ {
+ return NodePlacement(target, kMethcla_NodePlacementTailOfGroup);
+ }
+
+ static NodePlacement before(NodeId target)
+ {
+ return NodePlacement(target, kMethcla_NodePlacementBeforeNode);
+ }
+
+ static NodePlacement after(NodeId target)
+ {
+ return NodePlacement(target, kMethcla_NodePlacementAfterNode);
+ }
+ };
+
+ enum BusMappingFlags
+ {
+ kBusMappingInternal = kMethcla_BusMappingInternal,
+ kBusMappingExternal = kMethcla_BusMappingExternal,
+ kBusMappingFeedback = kMethcla_BusMappingFeedback,
+ kBusMappingReplace = kMethcla_BusMappingReplace
+ };
+
+ static inline BusMappingFlags operator|(BusMappingFlags a, BusMappingFlags b)
+ {
+ return detail::combineFlags(a, b);
+ }
+
+ enum NodeDoneFlags
+ {
+ kNodeDoneDoNothing = kMethcla_NodeDoneDoNothing
+ , kNodeDoneFreeSelf = kMethcla_NodeDoneFreeSelf
+ , kNodeDoneFreePreceeding = kMethcla_NodeDoneFreePreceeding
+ , kNodeDoneFreeFollowing = kMethcla_NodeDoneFreeFollowing
+ , kNodeDoneFreeAllSiblings = kMethcla_NodeDoneFreeAllSiblings
+ , kNodeDoneFreeParent = kMethcla_NodeDoneFreeParent
+ };
+
+ static inline NodeDoneFlags operator|(NodeDoneFlags a, NodeDoneFlags b)
+ {
+ return detail::combineFlags(a, b);
+ }
+
+ struct NodeTreeStatistics
+ {
+ size_t numGroups;
+ size_t numSynths;
+
+ NodeTreeStatistics()
+ : numGroups(0)
+ , numSynths(0)
+ {}
+ };
+
+ struct RealtimeMemoryStatistics
+ {
+ size_t freeNumBytes;
+ size_t usedNumBytes;
+
+ RealtimeMemoryStatistics()
+ : freeNumBytes(0)
+ , usedNumBytes(0)
+ {}
+
+ size_t totalNumBytes() const
+ {
+ return freeNumBytes + usedNumBytes;
+ }
+ };
+
+ template class ResourceIdAllocator
+ {
+ public:
+ class Statistics
+ {
+ size_t m_capacity;
+ size_t m_allocated;
+
+ public:
+ Statistics(size_t capacity, size_t allocated)
+ : m_capacity(capacity)
+ , m_allocated(allocated)
+ { }
+ Statistics(const Statistics&) = default;
+
+ size_t capacity() const { return m_capacity; }
+ size_t allocated() const { return m_allocated; }
+ size_t available() const { return capacity() - allocated(); }
+ };
+
+ ResourceIdAllocator(T minValue, size_t n)
+ : m_offset(minValue)
+ , m_bits(n)
+ , m_pos(0)
+ , m_allocated(0)
+ { }
+
+ Statistics getStatistics()
+ {
+ std::lock_guard lock(m_mutex);
+ return Statistics(m_bits.size(), m_allocated);
+ }
+
+ Id alloc()
+ {
+ std::lock_guard lock(m_mutex);
+ for (size_t i=m_pos; i < m_bits.size(); i++) {
+ if (!m_bits[i]) {
+ m_bits[i] = true;
+ m_pos = (i+1) == m_bits.size() ? 0 : i+1;
+ m_allocated++;
+ return Id(m_offset + i);
+ }
+ }
+ for (size_t i=0; i < m_pos; i++) {
+ if (!m_bits[i]) {
+ m_bits[i] = true;
+ m_pos = i+1;
+ m_allocated++;
+ return Id(m_offset + i);
+ }
+ }
+ throw std::runtime_error("No free ids");
+ }
+
+ void free(Id id)
+ {
+ std::lock_guard lock(m_mutex);
+ T i = id.id() - m_offset;
+ if ((i >= 0) && (i < (T)m_bits.size()) && m_bits[i]) {
+ m_bits[i] = false;
+ m_allocated--;
+#if 0 // Don't throw exception for now
+ } else {
+ throw std::runtime_error("Invalid id");
+#endif
+ }
+ }
+
+ private:
+ T m_offset;
+ std::vector m_bits;
+ size_t m_pos;
+ size_t m_allocated;
+ // TODO: Make lock configurable?
+ std::mutex m_mutex;
+ };
+
+ class PacketPool
+ {
+ public:
+ PacketPool(const PacketPool&) = delete;
+ PacketPool& operator=(const PacketPool&) = delete;
+
+ PacketPool(size_t packetSize)
+ : m_packetSize(packetSize)
+ { }
+ ~PacketPool()
+ {
+ std::lock_guard lock(m_mutex);
+ while (!m_freeList.empty()) {
+ void* ptr = m_freeList.front();
+ delete [] (char*)ptr;
+ m_freeList.pop_front();
+ }
+ }
+
+ size_t packetSize() const
+ {
+ return m_packetSize;
+ }
+
+ void* alloc()
+ {
+ std::lock_guard lock(m_mutex);
+ if (m_freeList.empty())
+ return new char[m_packetSize];
+ void* result = m_freeList.back();
+ m_freeList.pop_back();
+ return result;
+ }
+
+ void free(void* ptr)
+ {
+ std::lock_guard lock(m_mutex);
+ m_freeList.push_back(ptr);
+ }
+
+ private:
+ size_t m_packetSize;
+ // TODO: Use boost::lockfree::queue for free list
+ std::list m_freeList;
+ std::mutex m_mutex;
+ };
+
+ class Packet
+ {
+ public:
+ Packet(PacketPool& pool)
+ : m_pool(pool)
+ , m_packet(pool.alloc(), pool.packetSize())
+ { }
+ ~Packet()
+ {
+ m_pool.free(m_packet.data());
+ }
+
+ Packet(const Packet&) = delete;
+ Packet& operator=(const Packet&) = delete;
+
+ const OSCPP::Client::Packet& packet() const
+ {
+ return m_packet;
+ }
+
+ OSCPP::Client::Packet& packet()
+ {
+ return m_packet;
+ }
+
+ private:
+ PacketPool& m_pool;
+ OSCPP::Client::Packet m_packet;
+ };
+
+ class Value
+ {
+ public:
+ enum Type
+ {
+ kInt,
+ kFloat,
+ kString
+ };
+
+ explicit Value(int x) : m_type(kInt), m_int(x) {}
+ explicit Value(bool x) : m_type(kInt), m_int(x) { }
+ explicit Value(float x) : m_type(kFloat), m_float(x) {}
+ explicit Value(double x) : Value((float)x) {}
+ explicit Value(const std::string& x) : m_type(kString), m_string(x) {}
+ explicit Value(const char* x) : Value(std::string(x)) {}
+
+ void put(OSCPP::Client::Packet& packet) const
+ {
+ switch (m_type) {
+ case kInt:
+ packet.int32(m_int);
+ break;
+ case kFloat:
+ packet.float32(m_float);
+ break;
+ case kString:
+ packet.string(m_string.c_str());
+ break;
+ }
+ }
+
+ private:
+ Type m_type;
+ int m_int;
+ float m_float;
+ std::string m_string;
+ };
+
+ typedef Methcla_LibraryFunction LibraryFunction;
+
+ template class Optional
+ {
+ bool m_isSet;
+ T m_value;
+
+ public:
+ Optional()
+ : m_isSet(false)
+ { }
+ Optional(const T& value)
+ : m_isSet(true)
+ , m_value(value)
+ { }
+ Optional(const Optional& other) = default;
+
+ bool isSet() const
+ {
+ return m_isSet;
+ }
+
+ const T& value(const T& def) const
+ {
+ return isSet() ? m_value : def;
+ }
+
+ const T& value() const
+ {
+ if (!isSet())
+ throw std::logic_error("Optional value unset");
+ return m_value;
+ }
+ };
+
+ typedef std::function LogHandler;
+
+ class AudioDriverOptions
+ {
+ public:
+ Optional sampleRate;
+ Optional numInputs;
+ Optional numOutputs;
+ Optional bufferSize;
+
+ operator Methcla_AudioDriverOptions() const
+ {
+ Methcla_AudioDriverOptions result;
+ methcla_audio_driver_options_init(&result);
+ result.sample_rate = sampleRate.value(-1);
+ result.num_inputs = numInputs.value(-1);
+ result.num_outputs = numOutputs.value(-1);
+ result.buffer_size = bufferSize.value(-1);
+ return result;
+ }
+ };
+
+ class EngineOptions
+ {
+ Methcla_EngineOptions m_options;
+ std::vector m_pluginLibraries;
+
+ public:
+ LogHandler logHandler;
+ Methcla_EngineLogFlags logFlags = kMethcla_EngineLogDefault;
+
+ size_t realtimeMemorySize = 1024*1024;
+ size_t maxNumNodes = 1024;
+ size_t maxNumAudioBuses = 1024;
+ size_t maxNumControlBuses = 4096;
+ size_t sampleRate = 44100;
+ size_t blockSize = 64;
+ std::list pluginLibraries;
+
+ AudioDriverOptions audioDriver;
+
+ EngineOptions& addLibrary(LibraryFunction pluginLibrary)
+ {
+ pluginLibraries.push_back(pluginLibrary);
+ return *this;
+ }
+
+ Methcla_EngineOptions& options()
+ {
+ methcla_engine_options_init(&m_options);
+
+ m_options.sample_rate = sampleRate;
+ m_options.block_size = blockSize;
+ m_options.realtime_memory_size = realtimeMemorySize;
+ m_options.max_num_nodes = maxNumNodes;
+ m_options.max_num_audio_buses = maxNumAudioBuses;
+
+ m_pluginLibraries.assign(pluginLibraries.begin(), pluginLibraries.end());
+ m_pluginLibraries.push_back(nullptr);
+
+ m_options.plugin_libraries = m_pluginLibraries.data();
+
+ return m_options;
+ }
+ };
+
+ static const Methcla_Time immediately = 0.;
+
+ typedef ResourceIdAllocator NodeIdAllocator;
+ typedef ResourceIdAllocator AudioBusIdAllocator;
+
+ class Request;
+
+ class EngineInterface
+ {
+ public:
+ virtual ~EngineInterface() { }
+
+ GroupId root() const
+ {
+ return GroupId(0);
+ }
+
+ virtual NodeIdAllocator& nodeIdAllocator() = 0;
+
+ virtual std::unique_ptr allocPacket() = 0;
+ virtual void sendPacket(const std::unique_ptr& packet) = 0;
+
+ inline void bundle(Methcla_Time time, std::function func);
+
+ inline GroupId group(const NodePlacement& placement);
+ inline void freeAll(GroupId group);
+ inline SynthId synth(const char* synthDef, const NodePlacement& placement, const std::vector& controls, const std::list& options=std::list());
+ inline void activate(SynthId synth);
+ inline void mapInput(SynthId synth, size_t index, AudioBusId bus, BusMappingFlags flags=kBusMappingInternal);
+ inline void mapOutput(SynthId synth, size_t index, AudioBusId bus, BusMappingFlags flags=kBusMappingInternal);
+ inline void set(NodeId node, size_t index, double value);
+ inline void free(NodeId node);
+ };
+
+ class Request
+ {
+ struct Flags
+ {
+ bool isMessage : 1;
+ bool isBundle : 1;
+ bool isClosed : 1;
+ };
+
+ EngineInterface* m_engine;
+ std::unique_ptr m_packet;
+ size_t m_bundleCount;
+ Flags m_flags;
+
+ private:
+ void beginMessage()
+ {
+ if (m_flags.isMessage)
+ throw std::runtime_error("Cannot add more than one message to non-bundle packet");
+ else if (m_flags.isBundle && m_flags.isClosed)
+ throw std::runtime_error("Cannot add message to closed top-level bundle");
+ else if (!m_flags.isBundle)
+ m_flags.isMessage = true;
+ }
+
+ OSCPP::Client::Packet& oscPacket()
+ {
+ return m_packet->packet();
+ }
+
+ public:
+ Request(EngineInterface* engine)
+ : m_engine(engine)
+ , m_packet(engine->allocPacket())
+ , m_bundleCount(0)
+ {
+ m_flags.isMessage = false;
+ m_flags.isBundle = false;
+ m_flags.isClosed = false;
+ }
+
+ Request(EngineInterface& engine)
+ : Request(&engine)
+ { }
+
+ Request(const Request&) = delete;
+ Request& operator=(const Request&) = delete;
+
+ //* Return size of request packet in bytes.
+ size_t size() const
+ {
+ return m_packet->packet().size();
+ }
+
+ void openBundle(Methcla_Time time=immediately)
+ {
+ if (m_flags.isMessage)
+ {
+ throw std::runtime_error("Cannot open bundle within message packet");
+ }
+ else
+ {
+ m_flags.isBundle = true;
+ m_bundleCount++;
+ oscPacket().openBundle(methcla_time_to_uint64(time));
+ }
+ }
+
+ // Close nested bundle
+ void closeBundle()
+ {
+ if (m_flags.isMessage)
+ {
+ throw std::runtime_error("closeBundle called on a message request");
+ }
+ else if (m_bundleCount == 0)
+ {
+ throw std::runtime_error("closeBundle without matching openBundle");
+ }
+ else
+ {
+ oscPacket().closeBundle();
+ m_bundleCount--;
+ if (m_bundleCount == 0)
+ m_flags.isClosed = true;
+ }
+ }
+
+ void bundle(Methcla_Time time, std::function func)
+ {
+ openBundle(time);
+ func(*this);
+ closeBundle();
+ }
+
+ //* Finalize request and send to the engine.
+ void send()
+ {
+ if (m_flags.isBundle && m_bundleCount > 0)
+ throw std::runtime_error("openBundle without matching closeBundle");
+ m_engine->sendPacket(m_packet);
+ }
+
+ GroupId group(const NodePlacement& placement)
+ {
+ beginMessage();
+
+ const NodeId nodeId(m_engine->nodeIdAllocator().alloc());
+
+ oscPacket()
+ .openMessage("/group/new", 3)
+ .int32(nodeId.id())
+ .int32(placement.target().id())
+ .int32(placement.placement())
+ .closeMessage();
+
+ return GroupId(nodeId.id());
+ }
+
+ void freeAll(GroupId group)
+ {
+ beginMessage();
+
+ oscPacket()
+ .openMessage("/group/freeAll", 1)
+ .int32(group.id())
+ .closeMessage();
+ }
+
+ SynthId synth(const char* synthDef, const NodePlacement& placement, const std::vector& controls, const std::list& options=std::list())
+ {
+ beginMessage();
+
+ const NodeId nodeId(m_engine->nodeIdAllocator().alloc());
+
+ oscPacket()
+ .openMessage("/synth/new", 4 + OSCPP::Tags::array(controls.size()) + OSCPP::Tags::array(options.size()))
+ .string(synthDef)
+ .int32(nodeId.id())
+ .int32(placement.target().id())
+ .int32(placement.placement())
+ .putArray(controls.begin(), controls.end());
+
+ oscPacket().openArray();
+ for (const auto& x : options) {
+ x.put(oscPacket());
+ }
+ oscPacket().closeArray();
+
+ oscPacket().closeMessage();
+
+ return SynthId(nodeId.id());
+ }
+
+ void activate(SynthId synth)
+ {
+ beginMessage();
+
+ oscPacket()
+ .openMessage("/synth/activate", 1)
+ .int32(synth.id())
+ .closeMessage();
+ }
+
+ void mapInput(SynthId synth, size_t index, AudioBusId bus, BusMappingFlags flags=kBusMappingInternal)
+ {
+ beginMessage();
+
+ oscPacket()
+ .openMessage("/synth/map/input", 4)
+ .int32(synth.id())
+ .int32(index)
+ .int32(bus.id())
+ .int32(flags)
+ .closeMessage();
+ }
+
+ void mapOutput(SynthId synth, size_t index, AudioBusId bus, BusMappingFlags flags=kBusMappingInternal)
+ {
+ beginMessage();
+
+ oscPacket()
+ .openMessage("/synth/map/output", 4)
+ .int32(synth.id())
+ .int32(index)
+ .int32(bus.id())
+ .int32(flags)
+ .closeMessage();
+ }
+
+ void set(NodeId node, size_t index, double value)
+ {
+ beginMessage();
+
+ oscPacket()
+ .openMessage("/node/set", 3)
+ .int32(node.id())
+ .int32(index)
+ .float32(value)
+ .closeMessage();
+ }
+
+ void free(NodeId node)
+ {
+ beginMessage();
+
+ oscPacket()
+ .openMessage("/node/free", 1)
+ .int32(node.id())
+ .closeMessage();
+ m_engine->nodeIdAllocator().free(node.id());
+ }
+
+ void whenDone(SynthId synth, NodeDoneFlags flags)
+ {
+ beginMessage();
+
+ oscPacket()
+ .openMessage("/synth/property/doneFlags/set", 2)
+ .int32(synth.id())
+ .int32(flags)
+ .closeMessage();
+ }
+ };
+
+ void EngineInterface::bundle(Methcla_Time time, std::function func)
+ {
+ Request request(this);
+ request.bundle(time, func);
+ request.send();
+ }
+
+ GroupId EngineInterface::group(const NodePlacement& placement)
+ {
+ Request request(this);
+ GroupId result = request.group(placement);
+ request.send();
+ return result;
+ }
+
+ void EngineInterface::freeAll(GroupId group)
+ {
+ Request request(this);
+ request.freeAll(group);
+ request.send();
+ }
+
+ SynthId EngineInterface::synth(const char* synthDef, const NodePlacement& placement, const std::vector& controls, const std::list& options)
+ {
+ Request request(this);
+ SynthId result = request.synth(synthDef, placement, controls, options);
+ request.send();
+ return result;
+ }
+
+ void EngineInterface::activate(SynthId synth)
+ {
+ Request request(this);
+ request.activate(synth);
+ request.send();
+ }
+
+ void EngineInterface::mapInput(SynthId synth, size_t index, AudioBusId bus, BusMappingFlags flags)
+ {
+ Request request(this);
+ request.mapInput(synth, index, bus, flags);
+ request.send();
+ }
+
+ void EngineInterface::mapOutput(SynthId synth, size_t index, AudioBusId bus, BusMappingFlags flags)
+ {
+ Request request(this);
+ request.mapOutput(synth, index, bus, flags);
+ request.send();
+ }
+
+ void EngineInterface::set(NodeId node, size_t index, double value)
+ {
+ Request request(this);
+ request.set(node, index, value);
+ request.send();
+ }
+
+ void EngineInterface::free(NodeId node)
+ {
+ Request request(this);
+ request.free(node);
+ request.send();
+ }
+
+ class Engine : public EngineInterface
+ {
+ public:
+ Engine(EngineOptions inOptions=EngineOptions(), Methcla_AudioDriver* driver=nullptr)
+ : m_logHandler(inOptions.logHandler)
+ , m_nodeIds(1, inOptions.maxNumNodes - 1)
+ , m_audioBusIds(0, inOptions.maxNumAudioBuses)
+ , m_requestId(kMethcla_Notification+1)
+ , m_notificationHandlerId(0)
+ , m_packets(8192)
+ {
+ Methcla_EngineOptions& options = inOptions.options();
+
+ if (m_logHandler != nullptr)
+ {
+ options.log_handler.handle = this;
+ options.log_handler.log_line = logLineCallback;
+ }
+
+ options.packet_handler.handle = this;
+ options.packet_handler.handle_packet = handlePacket;
+
+ if (driver == nullptr) {
+ Methcla_AudioDriverOptions driverOptions(inOptions.audioDriver);
+ detail::checkReturnCode(methcla_default_audio_driver(&driverOptions, &driver));
+ }
+
+ detail::checkReturnCode(
+ methcla_engine_new_with_driver(&options, driver, &m_engine)
+ );
+
+ methcla_engine_set_log_flags(m_engine, inOptions.logFlags);
+ }
+
+ ~Engine()
+ {
+ methcla_engine_free(m_engine);
+ }
+
+ operator const Methcla_Engine* () const
+ {
+ return m_engine;
+ }
+
+ operator Methcla_Engine* ()
+ {
+ return m_engine;
+ }
+
+ void start()
+ {
+ detail::checkReturnCode(methcla_engine_start(m_engine));
+ }
+
+ void stop()
+ {
+ detail::checkReturnCode(methcla_engine_stop(m_engine));
+ }
+
+ Methcla_Time currentTime()
+ {
+ return methcla_engine_current_time(m_engine);
+ }
+
+ void setLogFlags(Methcla_EngineLogFlags flags)
+ {
+ methcla_engine_set_log_flags(m_engine, flags);
+ }
+
+ void logLine(Methcla_LogLevel level, const char* message)
+ {
+ methcla_engine_log_line(m_engine, level, message);
+ }
+
+ void logLine(Methcla_LogLevel level, const std::string& message)
+ {
+ logLine(level, message.c_str());
+ }
+
+ NodeIdAllocator& nodeIdAllocator() override
+ {
+ return m_nodeIds;
+ }
+
+ AudioBusIdAllocator& audioBusId()
+ {
+ return m_audioBusIds;
+ }
+
+ std::unique_ptr allocPacket() override
+ {
+ return std::unique_ptr(new Packet(m_packets));
+ }
+
+ void sendPacket(const std::unique_ptr& packet) override
+ {
+ send(*packet);
+ }
+
+ typedef std::function NotificationHandler;
+ typedef uint64_t NotificationHandlerId;
+
+ NotificationHandlerId addNotificationHandler(NotificationHandler handler)
+ {
+ std::lock_guard lock(m_notificationHandlersMutex);
+ NotificationHandlerId handlerId = m_notificationHandlerId;
+ m_notificationHandlers[handlerId] = handler;
+ m_notificationHandlerId++;
+ return handlerId;
+ }
+
+ void removeNotificationHandler(NotificationHandlerId handlerId)
+ {
+ std::lock_guard lock(m_notificationHandlersMutex);
+ m_notificationHandlers.erase(handlerId);
+ }
+
+ NotificationHandler freeNodeIdHandler(NodeId nodeId)
+ {
+ return [this,nodeId](const OSCPP::Server::Message& msg) {
+ if (msg == "/node/ended")
+ {
+ NodeId otherNodeId = NodeId(msg.args().int32());
+ if (nodeId == otherNodeId)
+ {
+ nodeIdAllocator().free(nodeId);
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+ NotificationHandler freeNodeIdHandler(NodeId nodeId, std::function whenDone)
+ {
+ return [this,nodeId,whenDone](const OSCPP::Server::Message& msg) {
+ if (msg == "/node/ended")
+ {
+ NodeId otherNodeId = NodeId(msg.args().int32());
+ if (nodeId == otherNodeId)
+ {
+ nodeIdAllocator().free(nodeId);
+ whenDone(nodeId);
+ return true;
+ }
+ }
+ return false;
+ };
+ }
+
+ NodeTreeStatistics getNodeTreeStatistics()
+ {
+ const char* request = "/node/tree/statistics";
+ const Methcla_RequestId requestId = getRequestId();
+ std::unique_ptr packet = allocPacket();
+ packet->packet()
+ .openMessage(request, 1)
+ .int32(requestId)
+ .closeMessage();
+ detail::Result result;
+ withRequest(requestId, packet->packet(), [&request,&result](Methcla_RequestId, const OSCPP::Server::Message& response){
+ result.checkResponse(request, response);
+ OSCPP::Server::ArgStream args(response.args());
+ NodeTreeStatistics value;
+ value.numGroups = args.int32();
+ value.numSynths = args.int32();
+ result.set(value);
+ });
+ return result.get();
+ }
+
+ RealtimeMemoryStatistics getRealtimeMemoryStatistics()
+ {
+ const char* request = "/engine/realtime-memory/statistics";
+ const Methcla_RequestId requestId = getRequestId();
+ auto packet = allocPacket();
+ packet->packet()
+ .openMessage(request, 1)
+ .int32(requestId)
+ .closeMessage();
+ detail::Result result;
+ withRequest(requestId, packet->packet(), [&request,&result](Methcla_RequestId, const OSCPP::Server::Message& response){
+ result.checkResponse(request, response);
+ OSCPP::Server::ArgStream args(response.args());
+ RealtimeMemoryStatistics value;
+ value.freeNumBytes = args.int32();
+ value.usedNumBytes = args.int32();
+ result.set(value);
+ });
+ return result.get();
+ }
+
+ private:
+ static void logLineCallback(void* data, Methcla_LogLevel level, const char* message)
+ {
+ assert( data != nullptr );
+ static_cast(data)->m_logHandler(level, message);
+ }
+
+ static void handlePacket(void* data, Methcla_RequestId requestId, const void* packet, size_t size)
+ {
+ if (requestId == kMethcla_Notification)
+ static_cast(data)->handleNotification(packet, size);
+ else
+ static_cast(data)->handleReply(requestId, packet, size);
+ }
+
+ void handleNotification(const void* packet, size_t size)
+ {
+ // Parse notification packet
+ OSCPP::Server::Message message(OSCPP::Server::Packet(packet, size));
+
+ // Broadcast notification to handlers
+ std::lock_guard lock(m_notificationHandlersMutex);
+ for (auto it=m_notificationHandlers.begin(); it != m_notificationHandlers.end();)
+ {
+ if (it->second(message)) it = m_notificationHandlers.erase(it);
+ else it++;
+ }
+ }
+
+ void handleReply(Methcla_RequestId requestId, const void* packet, size_t size)
+ {
+ // Parse response packet
+ OSCPP::Server::Message message(OSCPP::Server::Packet(packet, size));
+
+ // Look up request id and invoke callback
+ std::lock_guard lock(m_responseHandlersMutex);
+
+ auto it = m_responseHandlers.find(requestId);
+ if (it != m_responseHandlers.end())
+ {
+ try
+ {
+ it->second(requestId, message);
+ m_responseHandlers.erase(it);
+ }
+ catch (...)
+ {
+ m_responseHandlers.erase(it);
+ throw;
+ }
+ }
+ }
+
+ void send(const void* packet, size_t size)
+ {
+ detail::checkReturnCode(methcla_engine_send(m_engine, packet, size));
+ }
+
+ void send(const OSCPP::Client::Packet& packet)
+ {
+ // dumpRequest(std::cout, packet);
+ send(packet.data(), packet.size());
+ }
+
+ void send(const Packet& packet)
+ {
+ send(packet.packet());
+ }
+
+ Methcla_RequestId getRequestId()
+ {
+ std::lock_guard lock(m_requestIdMutex);
+ Methcla_RequestId result = m_requestId;
+ if (result == kMethcla_Notification) {
+ result++;
+ }
+ m_requestId = result + 1;
+ return result;
+ }
+
+ typedef std::function ResponseHandler;
+
+ void addResponseHandler(Methcla_RequestId requestId, ResponseHandler handler)
+ {
+ std::lock_guard lock(m_responseHandlersMutex);
+ if (m_responseHandlers.find(requestId) != m_responseHandlers.end()) {
+ throw std::logic_error("Methcla::Engine::addResponseHandler: Duplicate request id");
+ }
+ m_responseHandlers[requestId] = handler;
+ }
+
+ void withRequest(Methcla_RequestId requestId, const OSCPP::Client::Packet& request, ResponseHandler handler)
+ {
+ addResponseHandler(requestId, handler);
+ send(request);
+ }
+
+ void execRequest(const char* requestAddress, Methcla_RequestId requestId, const OSCPP::Client::Packet& request)
+ {
+ detail::Result result;
+ withRequest(requestId, request, [requestAddress,&result](Methcla_RequestId, const OSCPP::Server::Message& response){
+ result.checkResponse(requestAddress, response);
+ result.set();
+ });
+ result.get();
+ }
+
+ private:
+ typedef std::unordered_map ResponseHandlers;
+ typedef std::unordered_map NotificationHandlers;
+
+ Methcla_Engine* m_engine;
+ LogHandler m_logHandler;
+ NodeIdAllocator m_nodeIds;
+ AudioBusIdAllocator m_audioBusIds;
+ Methcla_RequestId m_requestId;
+ std::mutex m_requestIdMutex;
+ ResponseHandlers m_responseHandlers;
+ std::mutex m_responseHandlersMutex;
+ NotificationHandlers m_notificationHandlers;
+ NotificationHandlerId m_notificationHandlerId;
+ std::mutex m_notificationHandlersMutex;
+ PacketPool m_packets;
+ };
+};
+
+#endif // METHCLA_ENGINE_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/file.h b/java/libraries/sound/src/cpp/include/methcla/file.h
new file mode 100644
index 000000000..532f64979
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/file.h
@@ -0,0 +1,121 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_FILE_H_INCLUDED
+#define METHCLA_FILE_H_INCLUDED
+
+#include
+#include
+#include
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef enum
+{
+ kMethcla_FileModeRead,
+ kMethcla_FileModeWrite
+} Methcla_FileMode;
+
+typedef enum
+{
+ kMethcla_SoundFileTypeUnknown,
+ kMethcla_SoundFileTypeAIFF,
+ kMethcla_SoundFileTypeWAV
+} Methcla_SoundFileType;
+
+typedef enum
+{
+ kMethcla_SoundFileFormatUnknown,
+ kMethcla_SoundFileFormatPCM16,
+ kMethcla_SoundFileFormatPCM24,
+ kMethcla_SoundFileFormatPCM32,
+ kMethcla_SoundFileFormatFloat
+} Methcla_SoundFileFormat;
+
+typedef struct
+{
+ int64_t frames;
+ unsigned int channels;
+ unsigned int samplerate;
+ Methcla_SoundFileType file_type;
+ Methcla_SoundFileFormat file_format;
+} Methcla_SoundFileInfo;
+
+typedef struct Methcla_SoundFile Methcla_SoundFile;
+
+struct Methcla_SoundFile
+{
+ void* handle;
+ Methcla_Error (*close)(const Methcla_SoundFile* file);
+ Methcla_Error (*seek)(const Methcla_SoundFile* file, int64_t numFrames);
+ Methcla_Error (*tell)(const Methcla_SoundFile* file, int64_t* numFrames);
+ Methcla_Error (*read_float)(const Methcla_SoundFile* file, float* buffer, size_t numFrames, size_t* outNumFrames);
+ Methcla_Error (*write_float)(const Methcla_SoundFile* file, const float* buffer, size_t numFrames, size_t* outNumFrames);
+};
+
+typedef struct Methcla_SoundFileAPI Methcla_SoundFileAPI;
+
+struct Methcla_SoundFileAPI
+{
+ void* handle;
+ Methcla_Error (*open)(const Methcla_SoundFileAPI* api, const char* path, Methcla_FileMode mode, Methcla_SoundFile** file, Methcla_SoundFileInfo* info);
+};
+
+static inline Methcla_Error methcla_soundfile_close(Methcla_SoundFile* file)
+{
+ if ((file == NULL) || (file->close == NULL))
+ return methcla_error_new(kMethcla_ArgumentError);
+ return file->close(file);
+}
+
+static inline Methcla_Error methcla_soundfile_seek(Methcla_SoundFile* file, int64_t numFrames)
+{
+ if ((file == NULL) || (file->seek == NULL))
+ return methcla_error_new(kMethcla_ArgumentError);
+ return file->seek(file, numFrames);
+}
+
+static inline Methcla_Error methcla_soundfile_tell(Methcla_SoundFile* file, int64_t* numFrames)
+{
+ if ((file == NULL) || (file->tell == NULL) || (numFrames == NULL))
+ return methcla_error_new(kMethcla_ArgumentError);
+ return file->tell(file, numFrames);
+}
+
+static inline Methcla_Error methcla_soundfile_read_float(Methcla_SoundFile* file, float* buffer, size_t numFrames, size_t* outNumFrames)
+{
+ if ((file == NULL) || (file->read_float == NULL) ||
+ (buffer == NULL) || (outNumFrames == NULL))
+ return methcla_error_new(kMethcla_ArgumentError);
+ return file->read_float(file, buffer, numFrames, outNumFrames);
+}
+
+static inline Methcla_Error methcla_soundfile_write_float(Methcla_SoundFile* file, const float* buffer, size_t numFrames, size_t* outNumFrames)
+{
+ if ((file == NULL) || (file->write_float == NULL) ||
+ (buffer == NULL) || (outNumFrames == NULL))
+ return methcla_error_new(kMethcla_ArgumentError);
+ return file->write_float(file, buffer, numFrames, outNumFrames);
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* METHCLA_FILE_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/file.hpp b/java/libraries/sound/src/cpp/include/methcla/file.hpp
new file mode 100644
index 000000000..f9b07fe78
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/file.hpp
@@ -0,0 +1,185 @@
+// Copyright 2012-2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_FILE_HPP_INCLUDED
+#define METHCLA_FILE_HPP_INCLUDED
+
+#include
+#include
+#include
+#include
+
+#include
+
+namespace Methcla
+{
+ class SoundFileInfo : public Methcla_SoundFileInfo
+ {
+ public:
+ SoundFileInfo()
+ {
+ frames = 0;
+ channels = 0;
+ samplerate = 0;
+ file_type = kMethcla_SoundFileTypeUnknown;
+ file_format = kMethcla_SoundFileFormatUnknown;
+ }
+
+ SoundFileInfo(const Methcla_SoundFileInfo& info)
+ {
+ frames = info.frames;
+ channels = info.channels;
+ samplerate = info.samplerate;
+ file_type = info.file_type;
+ file_format = info.file_format;
+ }
+
+ int64_t samples() const
+ {
+ return channels * frames;
+ }
+
+ template T duration() const
+ {
+ return (T)frames/(T)samplerate;
+ }
+ };
+
+ class SoundFile
+ {
+ Methcla_SoundFile* m_file;
+ SoundFileInfo m_info;
+
+ inline void ensureInitialized() const
+ {
+ if (!m_file)
+ throw std::logic_error("SoundFile has not been initialized");
+ }
+
+ public:
+ SoundFile()
+ : m_file(nullptr)
+ {}
+
+ SoundFile(Methcla_SoundFile* file, const Methcla_SoundFileInfo& info)
+ : m_file(file)
+ , m_info(info)
+ {}
+
+ SoundFile(const Engine& engine, const std::string& path)
+ {
+ detail::checkReturnCode(
+ methcla_engine_soundfile_open(engine, path.c_str(), kMethcla_FileModeRead, &m_file, &m_info)
+ );
+ }
+
+ SoundFile(const Engine& engine, const std::string& path, const SoundFileInfo& info)
+ : m_info(info)
+ {
+ detail::checkReturnCode(
+ methcla_engine_soundfile_open(engine, path.c_str(), kMethcla_FileModeWrite, &m_file, &m_info)
+ );
+ }
+
+ SoundFile(const Methcla_Host* host, const std::string& path)
+ {
+ detail::checkReturnCode(
+ methcla_host_soundfile_open(host, path.c_str(), kMethcla_FileModeRead, &m_file, &m_info)
+ );
+ }
+
+ SoundFile(const Methcla_Host* host, const std::string& path, const SoundFileInfo& info)
+ : m_info(info)
+ {
+ detail::checkReturnCode(
+ methcla_host_soundfile_open(host, path.c_str(), kMethcla_FileModeWrite, &m_file, &m_info)
+ );
+ }
+
+ // SoundFile is moveable
+ SoundFile(SoundFile&& other)
+ : m_file(std::move(other.m_file))
+ , m_info(std::move(other.m_info))
+ {
+ other.m_file = nullptr;
+ }
+
+ SoundFile& operator=(SoundFile&& other)
+ {
+ m_file = std::move(other.m_file);
+ m_info = std::move(other.m_info);
+ other.m_file = nullptr;
+ return *this;
+ }
+
+ // SoundFile is not copyable
+ SoundFile(const SoundFile&) = delete;
+ SoundFile& operator=(const SoundFile&) = delete;
+
+ ~SoundFile()
+ {
+ if (m_file != nullptr)
+ methcla_soundfile_close(m_file);
+ }
+
+ operator bool() const
+ {
+ return m_file != nullptr;
+ }
+
+ const SoundFileInfo& info() const
+ {
+ return m_info;
+ }
+
+ void close()
+ {
+ ensureInitialized();
+ detail::checkReturnCode(methcla_soundfile_close(m_file));
+ m_file = nullptr;
+ }
+
+ void seek(int64_t numFrames)
+ {
+ ensureInitialized();
+ detail::checkReturnCode(methcla_soundfile_seek(m_file, numFrames));
+ }
+
+ int64_t tell()
+ {
+ ensureInitialized();
+ int64_t numFrames;
+ detail::checkReturnCode(methcla_soundfile_tell(m_file, &numFrames));
+ return numFrames;
+ }
+
+ size_t read(float* buffer, size_t numFrames)
+ {
+ ensureInitialized();
+ size_t outNumFrames;
+ detail::checkReturnCode(methcla_soundfile_read_float(m_file, buffer, numFrames, &outNumFrames));
+ return outNumFrames;
+ }
+
+ size_t write(const float* buffer, size_t numFrames)
+ {
+ ensureInitialized();
+ size_t outNumFrames;
+ detail::checkReturnCode(methcla_soundfile_write_float(m_file, buffer, numFrames, &outNumFrames));
+ return outNumFrames;
+ }
+ };
+}
+
+#endif // METHCLA_FILE_HPP_INCLUDED
\ No newline at end of file
diff --git a/java/libraries/sound/src/cpp/include/methcla/log.h b/java/libraries/sound/src/cpp/include/methcla/log.h
new file mode 100644
index 000000000..6525c4649
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/log.h
@@ -0,0 +1,34 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_LOG_H_INCLUDED
+#define METHCLA_LOG_H_INCLUDED
+
+typedef enum Methcla_LogLevel
+{
+ kMethcla_LogError,
+ kMethcla_LogWarn,
+ kMethcla_LogInfo,
+ kMethcla_LogDebug
+} Methcla_LogLevel;
+
+typedef struct Methcla_LogHandler
+{
+ void* handle;
+ void (*log_line)(void* handle, Methcla_LogLevel level, const char* message);
+} Methcla_LogHandler;
+
+#endif /* METHCLA_LOG_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/log.hpp b/java/libraries/sound/src/cpp/include/methcla/log.hpp
new file mode 100644
index 000000000..51e0658d4
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/log.hpp
@@ -0,0 +1,81 @@
+// Copyright 2014 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_LOG_HPP_INCLUDED
+#define METHCLA_LOG_HPP_INCLUDED
+
+#include
+
+#include
+#include
+#include
+
+namespace Methcla {
+
+class LogStream
+{
+ Methcla_LogLevel m_level;
+ std::function m_callback;
+ std::stringstream* m_stream;
+
+public:
+ LogStream(std::function callback, Methcla_LogLevel messageLevel, Methcla_LogLevel currentLevel)
+ : m_level(messageLevel)
+ , m_callback(messageLevel <= currentLevel ? callback : nullptr)
+ , m_stream(nullptr)
+ {}
+
+ LogStream(std::function callback, Methcla_LogLevel messageLevel)
+ : LogStream(callback, messageLevel, messageLevel)
+ {}
+
+ LogStream(const LogStream& other)
+ : m_level(other.m_level)
+ , m_callback(other.m_callback)
+ , m_stream(other.m_stream ? new std::stringstream(other.m_stream->str()) : nullptr)
+ {}
+
+ ~LogStream()
+ {
+ if (m_stream)
+ {
+ try
+ {
+ if (m_callback)
+ m_callback(m_level, m_stream->str().c_str());
+ delete m_stream;
+ }
+ catch (...)
+ {
+ delete m_stream;
+ throw;
+ }
+ }
+ }
+
+ template LogStream& operator<<(const T& x)
+ {
+ if (m_callback)
+ {
+ if (!m_stream)
+ m_stream = new std::stringstream();
+ *m_stream << x;
+ }
+ return *this;
+ }
+};
+
+} // namespace Methcla
+
+#endif // METHCLA_LOG_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/platform/pepper.hpp b/java/libraries/sound/src/cpp/include/methcla/platform/pepper.hpp
new file mode 100644
index 000000000..5d5413f5a
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/platform/pepper.hpp
@@ -0,0 +1,27 @@
+// Copyright 2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_PLATFORM_PEPPER_HPP_INCLUDED
+#define METHCLA_PLATFORM_PEPPER_HPP_INCLUDED
+
+#include
+#include
+#include "ppapi/cpp/instance_handle.h"
+
+METHCLA_EXPORT Methcla_AudioDriver* methcla_platform_pepper_audio_driver_new(
+ const Methcla_AudioDriverOptions* options,
+ const pp::InstanceHandle& instance
+ );
+
+#endif // METHCLA_PLATFORM_PEPPER_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/platform/rtaudio.hpp b/java/libraries/sound/src/cpp/include/methcla/platform/rtaudio.hpp
new file mode 100644
index 000000000..d1b39f625
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/platform/rtaudio.hpp
@@ -0,0 +1,24 @@
+// Copyright 2014 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_PLATFORM_RTAUDIO_HPP_INCLUDED
+#define METHCLA_PLATFORM_RTAUDIO_HPP_INCLUDED
+
+#include
+
+METHCLA_EXPORT Methcla_AudioDriver* methcla_rtaudio_driver_new(
+ const Methcla_AudioDriverOptions* options
+ );
+
+#endif // METHCLA_PLATFORM_RTAUDIO_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugin.h b/java/libraries/sound/src/cpp/include/methcla/plugin.h
new file mode 100644
index 000000000..2ff03dd6a
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugin.h
@@ -0,0 +1,322 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGIN_H_INCLUDED
+#define METHCLA_PLUGIN_H_INCLUDED
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define METHCLA_PLUGINS_URI "http://methc.la/plugins"
+
+//* Realtime interface.
+typedef struct Methcla_World Methcla_World;
+
+//* Non-realtime interface.
+typedef struct Methcla_Host Methcla_Host;
+
+//* Synth handle managed by a plugin.
+typedef void Methcla_Synth;
+
+//* Callback function type for performing commands in the non-realtime context.
+typedef void (*Methcla_HostPerformFunction)(const Methcla_Host* host, void* data);
+
+//* Callback function type for performing commands in the realtime context.
+typedef void (*Methcla_WorldPerformFunction)(const Methcla_World* world, void* data);
+
+//* Realtime interface
+struct Methcla_World
+{
+ //* Handle for implementation specific data.
+ void* handle;
+
+ //* Return engine sample rate.
+ double (*samplerate)(const Methcla_World*);
+
+ //* Return maximum audio block size.
+ size_t (*block_size)(const Methcla_World* world);
+
+ //* Return the time at the start of the current audio block in seconds.
+ Methcla_Time (*current_time)(const struct Methcla_World* world);
+
+ // Realtime memory allocation
+ void* (*alloc)(const struct Methcla_World* world, size_t size);
+ void* (*alloc_aligned)(const struct Methcla_World* world, size_t alignment, size_t size);
+ void (*free)(const struct Methcla_World* world, void* ptr);
+
+ //* Schedule a command for execution in the non-realtime context.
+ void (*perform_command)(const Methcla_World* world, Methcla_HostPerformFunction perform, void* data);
+
+ //* Log a message and a newline character.
+ void (*log_line)(const Methcla_World* world, Methcla_LogLevel level, const char* message);
+
+ //* Free synth.
+ void (*synth_done)(const struct Methcla_World* world, Methcla_Synth* synth);
+};
+
+static inline double methcla_world_samplerate(const Methcla_World* world)
+{
+ assert(world && world->samplerate);
+ return world->samplerate(world);
+}
+
+static inline size_t methcla_world_block_size(const Methcla_World* world)
+{
+ assert(world && world->block_size);
+ return world->block_size(world);
+}
+
+static inline Methcla_Time methcla_world_current_time(const Methcla_World* world)
+{
+ assert(world);
+ assert(world->current_time);
+ return world->current_time(world);
+}
+
+static inline void* methcla_world_alloc(const Methcla_World* world, size_t size)
+{
+ assert(world && world->alloc);
+ return world->alloc(world, size);
+}
+
+static inline void* methcla_world_alloc_aligned(const Methcla_World* world, size_t alignment, size_t size)
+{
+ assert(world && world->alloc_aligned);
+ return world->alloc_aligned(world, alignment, size);
+}
+
+static inline void methcla_world_free(const Methcla_World* world, void* ptr)
+{
+ assert(world && world->free);
+ world->free(world, ptr);
+}
+
+static inline void methcla_world_perform_command(const Methcla_World* world, Methcla_HostPerformFunction perform, void* data)
+{
+ assert(world && world->perform_command);
+ assert(perform);
+ world->perform_command(world, perform, data);
+}
+
+static inline void methcla_world_log_line(const Methcla_World* world, Methcla_LogLevel level, const char* message)
+{
+ assert(world);
+ assert(world->log_line);
+ assert(message);
+ world->log_line(world, level, message);
+}
+
+static inline void methcla_world_synth_done(const Methcla_World* world, Methcla_Synth* synth)
+{
+ assert(world);
+ assert(world->synth_done);
+ assert(synth);
+ world->synth_done(world, synth);
+}
+
+typedef enum
+{
+ kMethcla_Input,
+ kMethcla_Output
+} Methcla_PortDirection;
+
+typedef enum
+{
+ kMethcla_ControlPort,
+ kMethcla_AudioPort
+} Methcla_PortType;
+
+typedef enum
+{
+ kMethcla_PortFlags = 0x0
+ , kMethcla_Trigger = 0x1
+} Methcla_PortFlags;
+
+typedef struct Methcla_PortDescriptor Methcla_PortDescriptor;
+
+struct Methcla_PortDescriptor
+{
+ Methcla_PortDirection direction;
+ Methcla_PortType type;
+ Methcla_PortFlags flags;
+};
+
+typedef uint16_t Methcla_PortCount;
+
+typedef void Methcla_SynthOptions;
+
+typedef struct Methcla_SynthDef Methcla_SynthDef;
+
+struct Methcla_SynthDef
+{
+ //* Synth definition URI.
+ const char* uri;
+
+ //* Size of an instance in bytes.
+ size_t instance_size;
+
+ //* Size of options struct in bytes.
+ size_t options_size;
+
+ //* Parse OSC options and fill options struct.
+ void (*configure)(const void* tag_buffer, size_t tag_size, const void* arg_buffer, size_t arg_size, Methcla_SynthOptions* options);
+
+ //* Get port descriptor at index.
+ bool (*port_descriptor)(const Methcla_SynthOptions* options, Methcla_PortCount index, Methcla_PortDescriptor* port);
+
+ //* Construct a synth instance at the location given.
+ void (*construct)(const Methcla_World* world, const Methcla_SynthDef* def, const Methcla_SynthOptions* options, Methcla_Synth* synth);
+
+ //* Connect port at index to data.
+ void (*connect)(Methcla_Synth* synth, Methcla_PortCount index, void* data);
+
+ //* Activate the synth instance just before starting to call `process`.
+ void (*activate)(const Methcla_World* world, Methcla_Synth* synth);
+
+ //* Process numFrames of audio samples.
+ void (*process)(const Methcla_World* world, Methcla_Synth* synth, size_t numFrames);
+
+ //* Destroy a synth instance.
+ void (*destroy)(const Methcla_World* world, Methcla_Synth* synth);
+};
+
+struct Methcla_Host
+{
+ //* Handle for implementation specific data.
+ void* handle;
+
+ //* Register a synth definition.
+ void (*register_synthdef)(const struct Methcla_Host* host, const Methcla_SynthDef* synthDef);
+
+ //* Register sound file API.
+ void (*register_soundfile_api)(const struct Methcla_Host* host, const Methcla_SoundFileAPI* api);
+
+ //* Allocate a block of memory
+ void* (*alloc)(const struct Methcla_Host* context, size_t size);
+
+ //* Allocate a block of aligned memory.
+ void* (*alloc_aligned)(const struct Methcla_Host* context, size_t alignment, size_t size);
+
+ //* Free a block of memory previously allocated by alloc or alloc_aligned.
+ void (*free)(const struct Methcla_Host* context, void* ptr);
+
+ //* Open sound file.
+ Methcla_Error (*soundfile_open)(const Methcla_Host* host, const char* path, Methcla_FileMode mode, Methcla_SoundFile** file, Methcla_SoundFileInfo* info);
+
+ //* Schedule a command for execution in the realtime context.
+ void (*perform_command)(const Methcla_Host* host, const Methcla_WorldPerformFunction perform, void* data);
+
+ //* Send an OSC notification packet to the client.
+ void (*notify)(const Methcla_Host* host, const void* packet, size_t size);
+
+ //* Log a message and a newline character.
+ void (*log_line)(const Methcla_Host* host, Methcla_LogLevel level, const char* message);
+};
+
+static inline void methcla_host_register_synthdef(const Methcla_Host* host, const Methcla_SynthDef* synthDef)
+{
+ assert(host && host->register_synthdef);
+ assert(synthDef);
+ host->register_synthdef(host, synthDef);
+}
+
+static inline void methcla_host_register_soundfile_api(const Methcla_Host* host, const Methcla_SoundFileAPI* api)
+{
+ assert(host && host->register_soundfile_api && api);
+ host->register_soundfile_api(host, api);
+}
+
+static inline void* methcla_host_alloc(const Methcla_Host* context, size_t size)
+{
+ assert(context);
+ assert(context->alloc);
+ return context->alloc(context, size);
+}
+
+static inline void* methcla_host_alloc_aligned(const Methcla_Host* context, size_t alignment, size_t size)
+{
+ assert(context);
+ assert(context->alloc_aligned);
+ return context->alloc_aligned(context, alignment, size);
+}
+
+static inline void methcla_host_free(const Methcla_Host* context, void* ptr)
+{
+ assert(context);
+ assert(context->free);
+ context->free(context, ptr);
+}
+
+static inline Methcla_Error methcla_host_soundfile_open(const Methcla_Host* host, const char* path, Methcla_FileMode mode, Methcla_SoundFile** file, Methcla_SoundFileInfo* info)
+{
+ assert(host && host->soundfile_open);
+ assert(path);
+ assert(file);
+ assert(info);
+ return host->soundfile_open(host, path, mode, file, info);
+}
+
+static inline void methcla_host_perform_command(const Methcla_Host* host, Methcla_WorldPerformFunction perform, void* data)
+{
+ assert(host && host->perform_command);
+ host->perform_command(host, perform, data);
+}
+
+static inline void methcla_host_log_line(const Methcla_Host* host, Methcla_LogLevel level, const char* message)
+{
+ assert(host);
+ assert(host->log_line);
+ assert(message);
+ host->log_line(host, level, message);
+}
+
+typedef struct Methcla_Library Methcla_Library;
+
+struct Methcla_Library
+{
+ //* Handle for implementation specific data.
+ void* handle;
+
+ //* Destroy the library and clean up associated resources.
+ void (*destroy)(const Methcla_Library* library);
+};
+
+typedef const Methcla_Library* (*Methcla_LibraryFunction)(const Methcla_Host* host, const char* bundlePath);
+
+static inline void methcla_library_destroy(const Methcla_Library* library)
+{
+ assert(library);
+ if (library->destroy)
+ library->destroy(library);
+}
+
+// #define MESCALINE_MAKE_INIT_FUNC(name) MethclaInit_##name
+// #define MESCALINE_INIT_FUNC(name) MESCALINE_MAKE_INIT_FUNC(name)
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* METHCLA_PLUGIN_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugin.hpp b/java/libraries/sound/src/cpp/include/methcla/plugin.hpp
new file mode 100644
index 000000000..219c3f5d6
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugin.hpp
@@ -0,0 +1,305 @@
+// Copyright 2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_PLUGIN_HPP_INCLUDED
+#define METHCLA_PLUGIN_HPP_INCLUDED
+
+#include
+#include
+#include
+
+#include
+#include
+
+// NOTE: This API is unstable and subject to change!
+
+namespace Methcla { namespace Plugin {
+
+ template class World
+ {
+ const Methcla_World* m_context;
+
+ public:
+ World(const Methcla_World* context)
+ : m_context(context)
+ { }
+
+ double sampleRate() const
+ {
+ return methcla_world_samplerate(m_context);
+ }
+
+ size_t blockSize() const
+ {
+ return methcla_world_block_size(m_context);
+ }
+
+ Methcla_Time currentTime() const
+ {
+ return methcla_world_current_time(m_context);
+ }
+
+ void* alloc(size_t size) const
+ {
+ return methcla_world_alloc(m_context, size);
+ }
+
+ void* allocAligned(size_t alignment, size_t size) const
+ {
+ return methcla_world_alloc_aligned(m_context, alignment, size);
+ }
+
+ void free(void* ptr)
+ {
+ methcla_world_free(m_context, ptr);
+ }
+
+ void performCommand(Methcla_HostPerformFunction perform, void* data)
+ {
+ methcla_world_perform_command(m_context, perform, data);
+ }
+
+ LogStream log(Methcla_LogLevel logLevel=kMethcla_LogInfo)
+ {
+ using namespace std::placeholders;
+ return LogStream(std::bind(m_context->log_line, m_context, _1, _2), logLevel);
+ }
+
+ void synthRetain(Synth* synth) const
+ {
+ methcla_world_synth_retain(m_context, synth);
+ }
+
+ void synthRelease(Synth* synth) const
+ {
+ methcla_world_synth_release(m_context, synth);
+ }
+
+ void synthDone(Synth* synth) const
+ {
+ methcla_world_synth_done(m_context, synth);
+ }
+ };
+
+ class HostContext
+ {
+ const Methcla_Host* m_context;
+
+ public:
+ HostContext(const Methcla_Host* context)
+ : m_context(context)
+ {}
+
+ LogStream log(Methcla_LogLevel logLevel=kMethcla_LogInfo)
+ {
+ using namespace std::placeholders;
+ return LogStream(std::bind(m_context->log_line, m_context, _1, _2), logLevel);
+ }
+ };
+
+ class NoPorts
+ {
+ public:
+ enum Port { };
+
+ static size_t numPorts() { return 0; }
+
+ static Methcla_PortDescriptor descriptor(Port)
+ {
+ Methcla_PortDescriptor result;
+ std::memset(&result, 0, sizeof(result));
+ return result;
+ }
+ };
+
+ class PortDescriptor
+ {
+ public:
+ static Methcla_PortDescriptor make(Methcla_PortDirection direction, Methcla_PortType type, Methcla_PortFlags flags=kMethcla_PortFlags)
+ {
+ Methcla_PortDescriptor pd;
+ pd.direction = direction;
+ pd.type = type;
+ pd.flags = flags;
+ return pd;
+ }
+
+ static Methcla_PortDescriptor audioInput(Methcla_PortFlags flags=kMethcla_PortFlags)
+ {
+ return make(kMethcla_Input, kMethcla_AudioPort, flags);
+ }
+
+ static Methcla_PortDescriptor audioOutput(Methcla_PortFlags flags=kMethcla_PortFlags)
+ {
+ return make(kMethcla_Output, kMethcla_AudioPort, flags);
+ }
+
+ static Methcla_PortDescriptor controlInput(Methcla_PortFlags flags=kMethcla_PortFlags)
+ {
+ return make(kMethcla_Input, kMethcla_ControlPort, flags);
+ }
+
+ static Methcla_PortDescriptor controlOutput(Methcla_PortFlags flags=kMethcla_PortFlags)
+ {
+ return make(kMethcla_Output, kMethcla_ControlPort, flags);
+ }
+ };
+
+ template class StaticSynthOptions
+ {
+ public:
+ typedef Options Type;
+
+ static void
+ configure( const void* tag_buffer
+ , size_t tag_buffer_size
+ , const void* arg_buffer
+ , size_t arg_buffer_size
+ , Methcla_SynthOptions* options )
+ {
+ OSCPP::Server::ArgStream args(
+ OSCPP::ReadStream(tag_buffer, tag_buffer_size),
+ OSCPP::ReadStream(arg_buffer, arg_buffer_size)
+ );
+ new (options) Type(args);
+ }
+
+ static bool
+ port_descriptor( const Methcla_SynthOptions*
+ , Methcla_PortCount index
+ , Methcla_PortDescriptor* port )
+ {
+ if (index < PortDescriptor::numPorts())
+ {
+ *port = PortDescriptor::descriptor(static_cast(index));
+ return true;
+ }
+ return false;
+ }
+ };
+
+ namespace detail
+ {
+ template
+ class IfSynthDefHasActivate
+ {
+ public:
+ static inline void exec(const Methcla_World*, Synth*) { }
+ };
+
+ template
+ class IfSynthDefHasActivate
+ {
+ public:
+ static inline void exec(const Methcla_World* context, Synth* synth)
+ { synth->activate(World(context)); }
+ };
+
+ template
+ class IfSynthDefHasCleanup
+ {
+ public:
+ static inline void exec(const Methcla_World*, Synth*) { }
+ };
+
+ template
+ class IfSynthDefHasCleanup
+ {
+ public:
+ static inline void exec(const Methcla_World* context, Synth* synth)
+ { synth->cleanup(World(context)); }
+ };
+ } // namespace detail
+
+ enum SynthDefFlags
+ {
+ kSynthDefDefaultFlags = 0x00,
+ kSynthDefHasActivate = 0x01,
+ kSynthDefHasCleanup = 0x02
+ };
+
+ template class SynthDef
+ {
+ static void
+ construct( const Methcla_World* context
+ , const Methcla_SynthDef* synthDef
+ , const Methcla_SynthOptions* options
+ , Methcla_Synth* synth )
+ {
+ assert(context != nullptr);
+ assert(options != nullptr);
+ new (synth) Synth(World(context), synthDef, *static_cast(options));
+ }
+
+ static void
+ connect( Methcla_Synth* synth
+ , Methcla_PortCount port
+ , void* data)
+ {
+ static_cast(synth)->connect(static_cast(port), data);
+ }
+
+ static void
+ activate(const Methcla_World* context, Methcla_Synth* synth)
+ {
+ detail::IfSynthDefHasActivate<
+ Synth,
+ (Flags & kSynthDefHasActivate) == kSynthDefHasActivate
+ >::exec(context, static_cast(synth));
+ }
+
+ static void
+ process(const Methcla_World* context, Methcla_Synth* synth, size_t numFrames)
+ {
+ static_cast(synth)->process(World(context), numFrames);
+ }
+
+ static void
+ destroy(const Methcla_World* context, Methcla_Synth* synth)
+ {
+ // Call cleanup method
+ detail::IfSynthDefHasActivate<
+ Synth,
+ (Flags & kSynthDefHasCleanup) == kSynthDefHasCleanup
+ >::exec(context, static_cast(synth));
+ // Call destructor
+ static_cast(synth)->~Synth();
+ }
+
+ public:
+ void operator()(const Methcla_Host* host, const char* uri)
+ {
+ static const Methcla_SynthDef kSynthDef =
+ {
+ uri,
+ sizeof(Synth),
+ sizeof(typename Options::Type),
+ Options::configure,
+ Options::port_descriptor,
+ construct,
+ connect,
+ activate,
+ process,
+ destroy
+ };
+ methcla_host_register_synthdef(host, &kSynthDef);
+ }
+ };
+
+ template
+ using StaticSynthDef
+ = SynthDef, Ports, Flags>;
+} }
+
+#endif // METHCLA_PLUGIN_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/ampfol.h b/java/libraries/sound/src/cpp/include/methcla/plugins/ampfol.h
new file mode 100644
index 000000000..8d4823326
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/ampfol.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_AMPLITUDE_FOLLOWER_H_INCLUDED
+#define METHCLA_PLUGINS_AMPLITUDE_FOLLOWER_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_amplitude_follower(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_AMPLITUDE_FOLLOWER_URI METHCLA_PLUGINS_URI "/amplidute_follower"
+
+#endif /* METHCLA_PLUGINS_AMPLITUDE_FOLLOWER_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/delay.h b/java/libraries/sound/src/cpp/include/methcla/plugins/delay.h
new file mode 100644
index 000000000..36ffee64a
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/delay.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_DELAY_H_INCLUDED
+#define METHCLA_PLUGINS_DELAY_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_delay(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_DELAY_URI METHCLA_PLUGINS_URI "/delay"
+
+#endif /* METHCLA_PLUGINS_DELAY_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/fft.h b/java/libraries/sound/src/cpp/include/methcla/plugins/fft.h
new file mode 100644
index 000000000..7ef3fde5b
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/fft.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_FFT_H_INCLUDED
+#define METHCLA_PLUGINS_FFT_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_fft(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_FFT_URI METHCLA_PLUGINS_URI "/fft"
+
+#endif /* METHCLA_PLUGINS_FFT_H_INCLUDED */
\ No newline at end of file
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/hpf.h b/java/libraries/sound/src/cpp/include/methcla/plugins/hpf.h
new file mode 100644
index 000000000..a9d0dcc43
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/hpf.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_HPF_H_INCLUDED
+#define METHCLA_PLUGINS_HPF_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_hpf(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_HPF_URI METHCLA_PLUGINS_URI "/hpf"
+
+#endif /* METHCLA_PLUGINS_HPF_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/lpf.h b/java/libraries/sound/src/cpp/include/methcla/plugins/lpf.h
new file mode 100644
index 000000000..8dd48df45
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/lpf.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_LPF_H_INCLUDED
+#define METHCLA_PLUGINS_LPF_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_lpf(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_LPF_URI METHCLA_PLUGINS_URI "/lpf"
+
+#endif /* METHCLA_PLUGINS_LPF_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/node-control.h b/java/libraries/sound/src/cpp/include/methcla/plugins/node-control.h
new file mode 100644
index 000000000..300389093
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/node-control.h
@@ -0,0 +1,27 @@
+/*
+ Copyright 2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_NODE_CONTROL_H_INCLUDED
+#define METHCLA_PLUGINS_NODE_CONTROL_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_node_control(const Methcla_Host*, const char*);
+
+#define METHCLA_PLUGINS_DONE_AFTER_URI METHCLA_PLUGINS_URI "/done-after"
+#define METHCLA_PLUGINS_ASR_ENVELOPE_URI METHCLA_PLUGINS_URI "/asr-envelope"
+
+#endif // METHCLA_PLUGINS_NODE_CONTROL_H_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/osc.h b/java/libraries/sound/src/cpp/include/methcla/plugins/osc.h
new file mode 100644
index 000000000..2449e082b
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/osc.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_OSC_H_INCLUDED
+#define METHCLA_PLUGINS_OSC_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_osc(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_OSC_URI METHCLA_PLUGINS_URI "/osc"
+
+#endif /* METHCLA_PLUGINS_OSC_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/pan.h b/java/libraries/sound/src/cpp/include/methcla/plugins/pan.h
new file mode 100644
index 000000000..5a1a7e468
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/pan.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_PAN_H_INCLUDED
+#define METHCLA_PLUGINS_PAN_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_pan(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_PAN_URI METHCLA_PLUGINS_URI "/pan"
+
+#endif /* METHCLA_PLUGINS_PAN_H_INCLUDED */
\ No newline at end of file
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/pan2.h b/java/libraries/sound/src/cpp/include/methcla/plugins/pan2.h
new file mode 100644
index 000000000..e1480ab7d
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/pan2.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_PAN2_H_INCLUDED
+#define METHCLA_PLUGINS_PAN2_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_pan2(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_PAN2_URI METHCLA_PLUGINS_URI "/pan2"
+
+#endif /* METHCLA_PLUGINS_PAN2_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/patch-cable.h b/java/libraries/sound/src/cpp/include/methcla/plugins/patch-cable.h
new file mode 100644
index 000000000..1c416bd23
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/patch-cable.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_PATCH_CABLE_H_INCLUDED
+#define METHCLA_PLUGINS_PATCH_CABLE_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_patch_cable(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_PATCH_CABLE_URI METHCLA_PLUGINS_URI "/patch-cable"
+
+#endif // METHCLA_PLUGINS_PATCH_CABLE_H_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/pro/disksampler.h b/java/libraries/sound/src/cpp/include/methcla/plugins/pro/disksampler.h
new file mode 100644
index 000000000..538065718
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/pro/disksampler.h
@@ -0,0 +1,15 @@
+// Copyright 2012-2013 Samplecount S.L.
+// All Rights Reserved.
+//
+// See the file LICENSE-PRO for licensing details.
+
+#ifndef METHCLA_PLUGINS_DISKSAMPLER_H_INCLUDED
+#define METHCLA_PLUGINS_DISKSAMPLER_H_INCLUDED
+
+#include
+
+#define METHCLA_PLUGINS_DISKSAMPLER "methcla_plugins_disksampler"
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_disksampler(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_DISKSAMPLER_URI METHCLA_PLUGINS_URI "/disksampler"
+
+#endif // METHCLA_PLUGINS_DISKSAMPLER_H_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/pro/soundfile_api_extaudiofile.h b/java/libraries/sound/src/cpp/include/methcla/plugins/pro/soundfile_api_extaudiofile.h
new file mode 100644
index 000000000..1f3541737
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/pro/soundfile_api_extaudiofile.h
@@ -0,0 +1,14 @@
+// Copyright 2012-2013 Samplecount S.L.
+// All Rights Reserved.
+//
+// See the file LICENSE-PRO for licensing details.
+
+#ifndef METHCLA_SOUNDFILEAPI_EXTAUDIOFILE_H_INCLUDED
+#define METHCLA_SOUNDFILEAPI_EXTAUDIOFILE_H_INCLUDED
+
+#include
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_soundfile_api_extaudiofile(const Methcla_Host*, const char*);
+
+#endif // METHCLA_SOUNDFILEAPI_EXTAUDIOFILE_H_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/pulse.h b/java/libraries/sound/src/cpp/include/methcla/plugins/pulse.h
new file mode 100644
index 000000000..0624df72d
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/pulse.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_PULSE_H_INCLUDED
+#define METHCLA_PLUGINS_PULSE_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_pulse(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_PULSE_URI METHCLA_PLUGINS_URI "/pulse"
+
+#endif /* METHCLA_PLUGINS_PULSE_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/sampler.h b/java/libraries/sound/src/cpp/include/methcla/plugins/sampler.h
new file mode 100644
index 000000000..4c2f666dd
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/sampler.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_SAMPLER_H_INCLUDED
+#define METHCLA_PLUGINS_SAMPLER_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_sampler(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_SAMPLER_URI METHCLA_PLUGINS_URI "/sampler"
+
+#endif /* METHCLA_PLUGINS_SAMPLER_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/saw.h b/java/libraries/sound/src/cpp/include/methcla/plugins/saw.h
new file mode 100644
index 000000000..0650798e0
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/saw.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_SAW_H_INCLUDED
+#define METHCLA_PLUGINS_SAW_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_saw(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_SAW_URI METHCLA_PLUGINS_URI "/saw"
+
+#endif /* METHCLA_PLUGINS_SAW_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/sine.h b/java/libraries/sound/src/cpp/include/methcla/plugins/sine.h
new file mode 100644
index 000000000..d40a4a207
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/sine.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_SINE_H_INCLUDED
+#define METHCLA_PLUGINS_SINE_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_sine(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_SINE_URI METHCLA_PLUGINS_URI "/sine"
+
+#endif /* METHCLA_PLUGINS_SINE_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_dummy.h b/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_dummy.h
new file mode 100644
index 000000000..3eb39f43d
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_dummy.h
@@ -0,0 +1,23 @@
+// Copyright 2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_SOUNDFILEAPI_DUMMY_H_INCLUDED
+#define METHCLA_SOUNDFILEAPI_DUMMY_H_INCLUDED
+
+#include
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_soundfile_api_dummy(const Methcla_Host*, const char*);
+
+#endif /* METHCLA_SOUNDFILEAPI_DUMMY_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_libsndfile.h b/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_libsndfile.h
new file mode 100644
index 000000000..0f908c711
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_libsndfile.h
@@ -0,0 +1,23 @@
+// Copyright 2013 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_SOUNDFILEAPI_LIBSNDFILE_H_INCLUDED
+#define METHCLA_SOUNDFILEAPI_LIBSNDFILE_H_INCLUDED
+
+#include
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_soundfile_api_libsndfile(const Methcla_Host*, const char*);
+
+#endif /* METHCLA_SOUNDFILEAPI_LIBSNDFILE_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_mpg123.h b/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_mpg123.h
new file mode 100644
index 000000000..d18d143a8
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/soundfile_api_mpg123.h
@@ -0,0 +1,23 @@
+// Copyright 2013-2014 Samplecount S.L.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#ifndef METHCLA_SOUNDFILEAPI_MPG123_H_INCLUDED
+#define METHCLA_SOUNDFILEAPI_MPG123_H_INCLUDED
+
+#include
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_soundfile_api_mpg123(const Methcla_Host*, const char*);
+
+#endif /* METHCLA_SOUNDFILEAPI_MPG123_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/tri.h b/java/libraries/sound/src/cpp/include/methcla/plugins/tri.h
new file mode 100644
index 000000000..0daa3b3b8
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/tri.h
@@ -0,0 +1,25 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_PLUGINS_TRI_H_INCLUDED
+#define METHCLA_PLUGINS_TRI_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_tri(const Methcla_Host*, const char*);
+#define METHCLA_PLUGINS_TRI_URI METHCLA_PLUGINS_URI "/tri"
+
+#endif /* METHCLA_PLUGINS_TRI_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/methcla/plugins/whitenoise.h b/java/libraries/sound/src/cpp/include/methcla/plugins/whitenoise.h
new file mode 100644
index 000000000..535f57482
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/plugins/whitenoise.h
@@ -0,0 +1,19 @@
+//
+// whitenoise.h
+//
+//
+// Created by wirsing on 13.12.13.
+//
+//
+
+
+#ifndef METHCLA_PLUGINS_WHITE_NOISE_H_INCLUDED
+#define METHCLA_PLUGINS_WHITE_NOISE_H_INCLUDED
+
+#include
+
+METHCLA_EXPORT const Methcla_Library* methcla_plugins_white_noise(const Methcla_Host*, const char*);
+
+#define METHCLA_PLUGINS_WHITE_NOISE_URI METHCLA_PLUGINS_URI "/white_noise"
+
+#endif // METHCLA_PLUGINS_WHITE_NOISE_H_INCLUDED
\ No newline at end of file
diff --git a/java/libraries/sound/src/cpp/include/methcla/types.h b/java/libraries/sound/src/cpp/include/methcla/types.h
new file mode 100644
index 000000000..728a3cc36
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/methcla/types.h
@@ -0,0 +1,46 @@
+/*
+ Copyright 2012-2013 Samplecount S.L.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+#ifndef METHCLA_TYPES_H_INCLUDED
+#define METHCLA_TYPES_H_INCLUDED
+
+enum Methcla_NodePlacement
+{
+ kMethcla_NodePlacementHeadOfGroup,
+ kMethcla_NodePlacementTailOfGroup,
+ kMethcla_NodePlacementBeforeNode,
+ kMethcla_NodePlacementAfterNode
+};
+
+enum Methcla_BusMappingFlags
+{
+ kMethcla_BusMappingInternal = 0x00
+ , kMethcla_BusMappingExternal = 0x01
+ , kMethcla_BusMappingFeedback = 0x02
+ , kMethcla_BusMappingReplace = 0x04
+};
+
+enum Methcla_NodeDoneFlags
+{
+ kMethcla_NodeDoneDoNothing = 0x00
+ , kMethcla_NodeDoneFreeSelf = 0x01
+ , kMethcla_NodeDoneFreePreceeding = 0x02
+ , kMethcla_NodeDoneFreeFollowing = 0x04
+ , kMethcla_NodeDoneFreeAllSiblings = 0x08
+ , kMethcla_NodeDoneFreeParent = 0x10
+};
+
+#endif /* METHCLA_TYPES_H_INCLUDED */
diff --git a/java/libraries/sound/src/cpp/include/oscpp/client.hpp b/java/libraries/sound/src/cpp/include/oscpp/client.hpp
new file mode 100644
index 000000000..04b4c3315
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/oscpp/client.hpp
@@ -0,0 +1,314 @@
+// oscpp library
+//
+// Copyright (c) 2004-2013 Stefan Kersten
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef OSCPP_CLIENT_HPP_INCLUDED
+#define OSCPP_CLIENT_HPP_INCLUDED
+
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace OSCPP {
+namespace Client {
+
+//! OSC packet construction.
+/*!
+ * Construct a valid OSC packet for transmitting over a transport medium.
+ */
+class Packet
+{
+ int32_t calcSize(const char* begin, const char* end)
+ {
+ // TODO: Make sure pointer difference fits into int32_t
+ return end - begin - 4;
+ }
+
+public:
+ //! Constructor.
+ /*!
+ */
+ Packet()
+ {
+ reset(0, 0);
+ }
+
+ //! Constructor.
+ /*!
+ */
+ Packet(void* buffer, size_t size)
+ {
+ reset(buffer, size);
+ }
+
+ //! Destructor.
+ virtual ~Packet() { }
+
+ //! Get packet buffer address.
+ /*!
+ * Return the start address of the packet currently under construction.
+ */
+ void* data() const
+ {
+ return m_buffer;
+ }
+
+ size_t capacity() const
+ {
+ return m_capacity;
+ }
+
+ //! Get packet content size.
+ /*!
+ * Return the size of the packet currently under construction.
+ */
+ size_t size() const
+ {
+ return m_args.consumed();
+ }
+
+ //! Reset packet state.
+ void reset(void* buffer, size_t size)
+ {
+ checkAlignment(&m_buffer, kAlignment);
+ m_buffer = buffer;
+ m_capacity = size;
+ m_args = WriteStream(m_buffer, m_capacity);
+ m_sizePosM = m_sizePosB = nullptr;
+ m_inBundle = 0;
+ }
+
+ void reset()
+ {
+ reset(m_buffer, m_capacity);
+ }
+
+ Packet& openBundle(uint64_t time)
+ {
+ if (m_inBundle > 0) {
+ // Remember previous size pos offset
+ // TODO: Make sure pointer difference fits into int32_t
+ const int32_t offset = m_sizePosB - m_args.begin();
+ char* curPos = m_args.pos();
+ m_args.skip(4);
+ // Record size pos
+ std::memcpy(curPos, &offset, 4);
+ m_sizePosB = curPos;
+ } else if (m_args.pos() != m_args.begin()) {
+ throw std::logic_error("Cannot open toplevel bundle in non-empty packet");
+ }
+
+ m_inBundle++;
+ m_args.putString("#bundle");
+ m_args.putUInt64(time);
+ return *this;
+ }
+
+ Packet& closeBundle()
+ {
+ if (m_inBundle > 0) {
+ if (m_inBundle > 1) {
+ // Get current stream pos
+ char* curPos = m_args.pos();
+
+ // Get previous bundle size stream pos
+ int32_t offset;
+ memcpy(&offset, m_sizePosB, 4);
+ // Get previous size pos
+ char* prevPos = m_args.begin() + offset;
+
+ const int32_t bundleSize = calcSize(m_sizePosB, curPos);
+ assert(bundleSize >= 0 && (size_t)bundleSize >= Size::bundle(0));
+ // Write bundle size
+ m_args.setPos(m_sizePosB);
+ m_args.putInt32(bundleSize);
+ m_args.setPos(curPos);
+
+ // record outer bundle size pos
+ m_sizePosB = prevPos;
+ }
+ m_inBundle--;
+ } else {
+ throw std::logic_error("closeBundle() without matching openBundle()");
+ }
+ return *this;
+ }
+
+ Packet& openMessage(const char* addr, size_t numTags)
+ {
+ if (m_inBundle > 0) {
+ // record message size pos
+ m_sizePosM = m_args.pos();
+ // advance arg stream
+ m_args.skip(4);
+ }
+ m_args.putString(addr);
+ size_t sigLen = numTags + 2;
+ m_tags = WriteStream(m_args, sigLen);
+ m_args.zero(align(sigLen));
+ m_tags.putChar(',');
+ return *this;
+ }
+
+ Packet& closeMessage()
+ {
+ if (m_inBundle > 0) {
+ // Get current stream pos
+ char* curPos = m_args.pos();
+ // write message size
+ m_args.setPos(m_sizePosM);
+ m_args.putInt32(calcSize(m_sizePosM, curPos));
+ // restore stream pos
+ m_args.setPos(curPos);
+ // reset tag stream
+ m_tags = WriteStream();
+ }
+ return *this;
+ }
+
+ //! Write integer message argument.
+ /*!
+ * Write a 32 bit integer message argument.
+ *
+ * \param arg 32 bit integer argument.
+ *
+ * \pre openMessage must have been called before with no intervening
+ * closeMessage.
+ *
+ * \throw OSCPP::XRunError stream buffer xrun.
+ */
+ Packet& int32(int32_t arg)
+ {
+ m_tags.putChar('i');
+ m_args.putInt32(arg);
+ return *this;
+ }
+
+ Packet& float32(float arg)
+ {
+ m_tags.putChar('f');
+ m_args.putFloat32(arg);
+ return *this;
+ }
+
+ Packet& string(const char* arg)
+ {
+ m_tags.putChar('s');
+ m_args.putString(arg);
+ return *this;
+ }
+
+ // @throw std::invalid_argument if blob size is greater than std::numeric_limits::max()
+ Packet& blob(const Blob& arg)
+ {
+ if (arg.size() > (size_t)std::numeric_limits::max())
+ throw std::invalid_argument("Blob size greater than maximum value representable by int32_t");
+ m_tags.putChar('b');
+ m_args.putInt32(arg.size());
+ m_args.putData(arg.data(), arg.size());
+ return *this;
+ }
+
+ Packet& openArray()
+ {
+ m_tags.putChar('[');
+ return *this;
+ }
+
+ Packet& closeArray()
+ {
+ m_tags.putChar(']');
+ return *this;
+ }
+
+ template Packet& put(T)
+ {
+ T::OSC_Client_Packet_put_unimplemented;
+ return *this;
+ }
+
+ template Packet& put(InputIterator begin, InputIterator end)
+ {
+ for (auto it = begin; it != end; it++) {
+ put(*it);
+ }
+ return *this;
+ }
+
+ template Packet& putArray(InputIterator begin, InputIterator end)
+ {
+ openArray();
+ put(begin, end);
+ closeArray();
+ return *this;
+ }
+
+private:
+ void* m_buffer;
+ size_t m_capacity;
+ WriteStream m_args; // packet stream
+ WriteStream m_tags; // current tag stream
+ char* m_sizePosM; // last message size position
+ char* m_sizePosB; // last bundle size position
+ size_t m_inBundle; // bundle nesting depth
+};
+
+template <> inline Packet& Packet::put(int32_t x) { return int32(x); }
+template <> inline Packet& Packet::put(float x) { return float32(x); }
+template <> inline Packet& Packet::put(const char* x) { return string(x); }
+template <> inline Packet& Packet::put(Blob x) { return blob(x); }
+
+template class StaticPacket : public Packet
+{
+public:
+ StaticPacket()
+ : Packet(reinterpret_cast(&m_buffer), buffer_size)
+ { }
+
+private:
+ typedef typename std::aligned_storage::type AlignedBuffer;
+ AlignedBuffer m_buffer;
+};
+
+class DynamicPacket : public Packet
+{
+public:
+ DynamicPacket(size_t buffer_size)
+ : Packet(static_cast(new char[buffer_size]), buffer_size)
+ { }
+
+ ~DynamicPacket()
+ {
+ delete [] static_cast(data());
+ }
+};
+
+}
+}
+
+#endif // OSCPP_CLIENT_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/oscpp/detail/endian.hpp b/java/libraries/sound/src/cpp/include/oscpp/detail/endian.hpp
new file mode 100644
index 000000000..11bb76727
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/oscpp/detail/endian.hpp
@@ -0,0 +1,85 @@
+// Copyright 2005 Caleb Epstein
+// Copyright 2006 John Maddock
+// Copyright 2010 Rene Rivera
+// Distributed under the Boost Software License, Version 1.0. (See accompany-
+// ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*
+ * Copyright (c) 1997
+ * Silicon Graphics Computer Systems, Inc.
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation. Silicon Graphics makes no
+ * representations about the suitability of this software for any
+ * purpose. It is provided "as is" without express or implied warranty.
+ */
+
+/*
+ * Copyright notice reproduced from , from
+ * which this code was originally taken.
+ *
+ * Modified by Caleb Epstein to use with GNU libc and to
+ * defined the BOOST_ENDIAN macro.
+ */
+
+/*
+ * Modifications for oscpp by Stefan Kersten
+ * - Change prefix from BOOST to OSCPP
+ * - Remove PDP endianness
+ * - Add OSCPP_BYTE_ORDER_* macros
+ */
+
+#ifndef OSCPP_ENDIAN_HPP_INCLUDED
+#define OSCPP_ENDIAN_HPP_INCLUDED
+
+#define OSCPP_BYTE_ORDER_BIG_ENDIAN 4321
+#define OSCPP_BYTE_ORDER_LITTLE_ENDIAN 1234
+
+// GNU libc offers the helpful header which defines
+// __BYTE_ORDER
+
+#if defined (__GLIBC__) || defined(__ANDROID__)
+# include
+# if (__BYTE_ORDER == __LITTLE_ENDIAN)
+# define OSCPP_LITTLE_ENDIAN
+# elif (__BYTE_ORDER == __BIG_ENDIAN)
+# define OSCPP_BIG_ENDIAN
+# else
+# error Unknown machine endianness detected.
+# endif
+# define OSCPP_BYTE_ORDER __BYTE_ORDER
+#elif defined(_BIG_ENDIAN) && !defined(_LITTLE_ENDIAN) || \
+ defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) || \
+ defined(_STLP_BIG_ENDIAN) && !defined(_STLP_LITTLE_ENDIAN)
+# define OSCPP_BIG_ENDIAN
+# define OSCPP_BYTE_ORDER OSCPP_BYTE_ORDER_BIG_ENDIAN
+#elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN) || \
+ defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) || \
+ defined(_STLP_LITTLE_ENDIAN) && !defined(_STLP_BIG_ENDIAN)
+# define OSCPP_LITTLE_ENDIAN
+# define OSCPP_BYTE_ORDER OSCPP_BYTE_ORDER_LITTLE_ENDIAN
+#elif defined(__sparc) || defined(__sparc__) \
+ || defined(_POWER) || defined(__powerpc__) \
+ || defined(__ppc__) || defined(__hpux) || defined(__hppa) \
+ || defined(_MIPSEB) || defined(_POWER) \
+ || defined(__s390__)
+# define OSCPP_BIG_ENDIAN
+# define OSCPP_BYTE_ORDER OSCPP_BYTE_ORDER_BIG_ENDIAN
+#elif defined(__i386__) || defined(__alpha__) \
+ || defined(__ia64) || defined(__ia64__) \
+ || defined(_M_IX86) || defined(_M_IA64) \
+ || defined(_M_ALPHA) || defined(__amd64) \
+ || defined(__amd64__) || defined(_M_AMD64) \
+ || defined(__x86_64) || defined(__x86_64__) \
+ || defined(_M_X64) || defined(__bfin__)
+
+# define OSCPP_LITTLE_ENDIAN
+# define OSCPP_BYTE_ORDER OSCPP_BYTE_ORDER_LITTLE_ENDIAN
+#else
+# error The file oscpp/endian.hpp needs to be set up for your CPU type.
+#endif
+
+#endif // OSCPP_ENDIAN_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/oscpp/detail/host.hpp b/java/libraries/sound/src/cpp/include/oscpp/detail/host.hpp
new file mode 100644
index 000000000..ec52fd0b5
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/oscpp/detail/host.hpp
@@ -0,0 +1,118 @@
+// oscpp library
+//
+// Copyright (c) 2004-2013 Stefan Kersten
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef OSCPP_HOST_HPP_INCLUDED
+#define OSCPP_HOST_HPP_INCLUDED
+
+#include
+#include
+#include
+
+namespace OSCPP
+{
+#if defined(__GNUC__)
+ inline static uint32_t bswap32(uint32_t x)
+ {
+ return __builtin_bswap32(x);
+ }
+ inline static uint64_t bswap64(uint64_t x)
+ {
+ return __builtin_bswap64(x);
+ }
+#elif defined(_WINDOWS_)
+# include
+ inline static uint32_t bswap32(uint32_t x)
+ {
+ return _byteswap_ulong(x);
+ }
+ inline static uint64_t bswap64(uint64_t x)
+ {
+ return _byteswap_uint64(x);
+ }
+#else
+ // Fallback implementation
+# warning Using unoptimized byte swap functions
+
+ inline static uint32_t bswap32(uint32_t x)
+ {
+ const uint32_t b1 = x << 24;
+ const uint32_t b2 = (x & 0x0000FF00) << 8;
+ const uint32_t b3 = (x & 0x00FF0000) >> 8;
+ const uint32_t b4 = x >> 24;
+ return b1 | b2 | b3 | b4;
+ }
+ inline static uint64_t bswap64(int64_t x)
+ {
+ const uint64_t w1 = oscpp_bswap(uint32_t(x & 0x00000000FFFFFFFF)) << 32;
+ const uint64_t w2 = oscpp_bswap(uint32_t(x >> 32));
+ return w1 | w2;
+ }
+#endif
+
+ enum ByteOrder
+ {
+ NetworkByteOrder,
+ HostByteOrder
+ };
+
+ template inline uint32_t convert32(uint32_t)
+ {
+ throw std::logic_error("Invalid byte order");
+ }
+
+ template<> inline uint32_t convert32(uint32_t x)
+ {
+#if defined(OSCPP_LITTLE_ENDIAN)
+ return bswap32(x);
+#else
+ return x;
+#endif
+ }
+
+ template<> inline uint32_t convert32(uint32_t x)
+ {
+ return x;
+ }
+
+ template inline uint64_t convert64(uint64_t)
+ {
+ throw std::logic_error("Invalid byte order");
+ }
+
+ template<> inline uint64_t convert64(uint64_t x)
+ {
+#if defined(OSCPP_LITTLE_ENDIAN)
+ return bswap64(x);
+#else
+ return x;
+#endif
+ }
+
+ template<> inline uint64_t convert64(uint64_t x)
+ {
+ return x;
+ }
+}
+
+#endif // OSCPP_HOST_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/oscpp/detail/stream.hpp b/java/libraries/sound/src/cpp/include/oscpp/detail/stream.hpp
new file mode 100644
index 000000000..41520290a
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/oscpp/detail/stream.hpp
@@ -0,0 +1,346 @@
+// oscpp library
+//
+// Copyright (c) 2004-2013 Stefan Kersten
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef OSCPP_STREAM_HPP_INCLUDED
+#define OSCPP_STREAM_HPP_INCLUDED
+
+#include
+#include
+#include
+#include
+
+#include
+#include
+#include
+#include
+
+namespace OSCPP {
+
+class Stream
+{
+public:
+ Stream()
+ {
+ m_begin = m_end = m_pos = 0;
+ }
+
+ Stream(void* data, size_t size)
+ {
+ m_begin = static_cast(data);
+ m_end = m_begin + size;
+ m_pos = m_begin;
+ }
+
+ Stream(const Stream& stream)
+ {
+ m_begin = m_pos = stream.m_pos;
+ m_end = stream.m_end;
+ }
+
+ Stream(const Stream& stream, size_t size)
+ {
+ m_begin = m_pos = stream.m_pos;
+ m_end = m_begin + size;
+ if (m_end > stream.m_end) throw UnderrunError();
+ }
+
+ void reset()
+ {
+ m_pos = m_begin;
+ }
+
+ const char* begin() const
+ {
+ return m_begin;
+ }
+
+ char* begin()
+ {
+ return m_begin;
+ }
+
+ const char* end() const
+ {
+ return m_end;
+ }
+
+ size_t capacity() const
+ {
+ return end() - begin();
+ }
+
+ const char* pos() const
+ {
+ return m_pos;
+ }
+
+ char* pos()
+ {
+ return m_pos;
+ }
+
+ void setPos(char* pos)
+ {
+ assert((pos >= m_begin) && (pos <= m_end));
+ m_pos = pos;
+ }
+
+ void advance(size_t n)
+ {
+ m_pos += n;
+ }
+
+ bool atEnd() const
+ {
+ return pos() == end();
+ }
+
+ size_t consumed() const
+ {
+ return pos() - begin();
+ }
+
+ size_t consumable() const
+ {
+ return end() - pos();
+ }
+
+ inline void checkAlignment(size_t n) const
+ {
+ OSCPP::checkAlignment(pos(), n);
+ }
+
+protected:
+ char* m_begin;
+ char* m_end;
+ char* m_pos;
+};
+
+class WriteStream: public Stream
+{
+public:
+ WriteStream()
+ : Stream()
+ { }
+
+ WriteStream(void* data, size_t size)
+ : Stream(data, size)
+ { }
+
+ WriteStream(const WriteStream& stream)
+ : Stream(stream)
+ { }
+
+ WriteStream(const WriteStream& stream, size_t size)
+ : Stream(stream, size)
+ { }
+
+ // throw (OverflowError)
+ inline void checkWritable(size_t n) const
+ {
+ if (consumable() < n)
+ throw OverflowError(n - consumable());
+ }
+
+ void skip(size_t n)
+ {
+ checkWritable(n);
+ advance(n);
+ }
+
+ void zero(size_t n)
+ {
+ checkWritable(n);
+ std::memset(m_pos, 0, n);
+ advance(n);
+ }
+
+ void putChar(char c)
+ {
+ checkWritable(1);
+ *pos() = c;
+ advance(1);
+ }
+
+ void putInt32(int32_t x)
+ {
+ checkWritable(4);
+ checkAlignment(4);
+ uint32_t uh;
+ memcpy(&uh, &x, 4);
+ const uint32_t un = convert32(uh);
+ std::memcpy(pos(), &un, 4);
+ advance(4);
+ }
+
+ void putUInt64(uint64_t x)
+ {
+ checkWritable(8);
+ const uint64_t un = convert64(x);
+ std::memcpy(pos(), &un, 8);
+ advance(8);
+ }
+
+ void putFloat32(float f)
+ {
+ checkWritable(4);
+ checkAlignment(4);
+ uint32_t uh;
+ std::memcpy(&uh, &f, 4);
+ const uint32_t un = convert32(uh);
+ std::memcpy(pos(), &un, 4);
+ advance(4);
+ }
+
+ void putData(const void* data, size_t size)
+ {
+ const size_t padding = OSCPP::padding(size);
+ const size_t n = size + padding;
+ checkWritable(n);
+ std::memcpy(pos(), data, size);
+ std::memset(pos()+size, 0, padding);
+ advance(n);
+ }
+
+ void putString(const char* s)
+ {
+ putData(s, strlen(s)+1);
+ }
+};
+
+
+class ReadStream : public Stream
+{
+public:
+ ReadStream()
+ { }
+
+ ReadStream(const void* data, size_t size)
+ : Stream(const_cast(data), size)
+ { }
+
+ ReadStream(const ReadStream& stream)
+ : Stream(stream)
+ { }
+
+ ReadStream(const ReadStream& stream, size_t size)
+ : Stream(stream, size)
+ { }
+
+ // throw (UnderrunError)
+ void checkReadable(size_t n) const
+ {
+ if (consumable() < n) throw UnderrunError();
+ }
+
+ // throw (UnderrunError)
+ void skip(size_t n)
+ {
+ checkReadable(n);
+ advance(n);
+ }
+
+ // throw (UnderrunError)
+ inline char peekChar() const
+ {
+ checkReadable(1);
+ return *pos();
+ }
+
+ // throw (UnderrunError)
+ inline char getChar()
+ {
+ const char x = peekChar();
+ advance(1);
+ return x;
+ }
+
+ // throw (UnderrunError)
+ inline int32_t peekInt32() const
+ {
+ checkReadable(4);
+ checkAlignment(4);
+ uint32_t un;
+ std::memcpy(&un, pos(), 4);
+ const uint32_t uh = convert32(un);
+ int32_t x;
+ std::memcpy(&x, &uh, 4);
+ return x;
+ }
+
+ // throw (UnderrunError)
+ inline int32_t getInt32()
+ {
+ const int32_t x = peekInt32();
+ advance(4);
+ return x;
+ }
+
+ // throw (UnderrunError)
+ inline uint64_t getUInt64()
+ {
+ checkReadable(8);
+ uint64_t un;
+ std::memcpy(&un, pos(), 8);
+ advance(8);
+ return convert64(un);
+ }
+
+ // throw (UnderrunError)
+ inline float getFloat32()
+ {
+ checkReadable(4);
+ checkAlignment(4);
+ uint32_t un;
+ std::memcpy(&un, pos(), 4);
+ advance(4);
+ const uint32_t uh = convert32(un);
+ float f;
+ std::memcpy(&f, &uh, 4);
+ return f;
+ }
+
+ // throw (UnderrunError, ParseError)
+ const char* getString()
+ {
+ checkReadable(4); // min string length
+
+ const char* ptr = static_cast(pos()) + 3;
+ const char* end = static_cast(this->end());
+
+ while (true) {
+ if (ptr >= end) throw UnderrunError();
+ if (*ptr == '\0') break;
+ ptr += 4;
+ }
+
+ const char* x = pos();
+ advance(ptr - pos() + 1);
+
+ return x;
+ }
+};
+}
+
+#endif // OSCPP_STREAM_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/oscpp/error.hpp b/java/libraries/sound/src/cpp/include/oscpp/error.hpp
new file mode 100644
index 000000000..bea43e74b
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/oscpp/error.hpp
@@ -0,0 +1,84 @@
+// oscpp library
+//
+// Copyright (c) 2004-2013 Stefan Kersten
+//
+// Permission is hereby granted, free of charge, to any person or organization
+// obtaining a copy of the software and accompanying documentation covered by
+// this license (the "Software") to use, reproduce, display, distribute,
+// execute, and transmit the Software, and to prepare derivative works of the
+// Software, and to permit third-parties to whom the Software is furnished to
+// do so, all subject to the following:
+//
+// The copyright notices in the Software and this entire statement, including
+// the above license grant, this restriction and the following disclaimer,
+// must be included in all copies of the Software, in whole or in part, and
+// all derivative works of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+// DEALINGS IN THE SOFTWARE.
+
+#ifndef OSCPP_ERROR_HPP_INCLUDED
+#define OSCPP_ERROR_HPP_INCLUDED
+
+#include
+#include
+
+namespace OSCPP {
+
+class Error : public std::exception
+{
+public:
+ Error(const std::string& what)
+ : m_what(what)
+ { }
+
+ virtual ~Error() noexcept
+ { }
+
+ const char* what() const noexcept override
+ {
+ return m_what.c_str();
+ }
+
+private:
+ std::string m_what;
+};
+
+class UnderrunError : public Error
+{
+public:
+ UnderrunError()
+ : Error(std::string("Buffer underrun"))
+ { }
+};
+
+class OverflowError : public Error
+{
+public:
+ OverflowError(size_t bytes)
+ : Error(std::string("Buffer overflow")),
+ m_bytes(bytes)
+ { }
+
+ size_t numBytes() const { return m_bytes; }
+
+private:
+ size_t m_bytes;
+};
+
+class ParseError : public Error
+{
+public:
+ ParseError(const std::string& what="Parse error")
+ : Error(what)
+ { }
+};
+
+}
+
+#endif // OSCPP_ERROR_HPP_INCLUDED
diff --git a/java/libraries/sound/src/cpp/include/oscpp/print.hpp b/java/libraries/sound/src/cpp/include/oscpp/print.hpp
new file mode 100644
index 000000000..448e20b61
--- /dev/null
+++ b/java/libraries/sound/src/cpp/include/oscpp/print.hpp
@@ -0,0 +1,166 @@
+// OSCpp library
+//
+// Copyright (c) 2004-2011 Stefan Kersten