summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libs/ardour/iec1ppmdsp.cc113
-rw-r--r--libs/ardour/iec2ppmdsp.cc113
-rw-r--r--libs/ardour/kmeterdsp.cc137
-rw-r--r--libs/audiographer/private/gdither/gdither.cc2
-rw-r--r--libs/plugins/reasonablesynth.lv2/lv2.c238
-rw-r--r--libs/plugins/reasonablesynth.lv2/rsynth.c828
6 files changed, 713 insertions, 718 deletions
diff --git a/libs/ardour/iec1ppmdsp.cc b/libs/ardour/iec1ppmdsp.cc
index 842d33b8b5..f4dcc4b39a 100644
--- a/libs/ardour/iec1ppmdsp.cc
+++ b/libs/ardour/iec1ppmdsp.cc
@@ -20,81 +20,74 @@
#include <math.h>
#include "ardour/iec1ppmdsp.h"
-
float Iec1ppmdsp::_w1;
float Iec1ppmdsp::_w2;
float Iec1ppmdsp::_w3;
float Iec1ppmdsp::_g;
+Iec1ppmdsp::Iec1ppmdsp (void)
+ : _z1 (0)
+ , _z2 (0)
+ , _m (0)
+ , _res (true)
+{}
-Iec1ppmdsp::Iec1ppmdsp (void) :
- _z1 (0),
- _z2 (0),
- _m (0),
- _res (true)
-{
-}
-
+Iec1ppmdsp::~Iec1ppmdsp (void) {}
-Iec1ppmdsp::~Iec1ppmdsp (void)
+void
+Iec1ppmdsp::process (float const* p, int n)
{
+ float z1, z2, m, t;
+
+ z1 = _z1 > 20 ? 20 : (_z1 < 0 ? 0 : _z1);
+ z2 = _z2 > 20 ? 20 : (_z2 < 0 ? 0 : _z2);
+ m = _res ? 0: _m;
+ _res = false;
+
+ n /= 4;
+ while (n--) {
+ z1 *= _w3;
+ z2 *= _w3;
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = z1 + z2;
+ if (t > m) m = t;
+ }
+
+ _z1 = z1 + 1e-10f;
+ _z2 = z2 + 1e-10f;
+ _m = m;
}
-
-void Iec1ppmdsp::process (float const *p, int n)
+float
+Iec1ppmdsp::read (void)
{
- float z1, z2, m, t;
-
- z1 = _z1 > 20 ? 20 : (_z1 < 0 ? 0 : _z1);
- z2 = _z2 > 20 ? 20 : (_z2 < 0 ? 0 : _z2);
- m = _res ? 0: _m;
- _res = false;
-
- n /= 4;
- while (n--)
- {
- z1 *= _w3;
- z2 *= _w3;
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = z1 + z2;
- if (t > m) m = t;
- }
-
- _z1 = z1 + 1e-10f;
- _z2 = z2 + 1e-10f;
- _m = m;
-}
-
-
-float Iec1ppmdsp::read (void)
-{
- _res = true;
- return _g * _m;
+ _res = true;
+ return _g * _m;
}
-void Iec1ppmdsp::reset ()
+void
+Iec1ppmdsp::reset ()
{
- _z1 = _z2 = _m = .0f;
- _res = true;
+ _z1 = _z2 = _m = .0f;
+ _res = true;
}
-void Iec1ppmdsp::init (float fsamp)
+void
+Iec1ppmdsp::init (float fsamp)
{
- _w1 = 450.0f / fsamp;
- _w2 = 1300.0f / fsamp;
- _w3 = 1.0f - 5.4f / fsamp;
- _g = 0.5108f;
+ _w1 = 450.0f / fsamp;
+ _w2 = 1300.0f / fsamp;
+ _w3 = 1.0f - 5.4f / fsamp;
+ _g = 0.5108f;
}
-
-/* vi:set ts=8 sts=8 sw=4: */
diff --git a/libs/ardour/iec2ppmdsp.cc b/libs/ardour/iec2ppmdsp.cc
index d65f51b3fa..28b9aa9611 100644
--- a/libs/ardour/iec2ppmdsp.cc
+++ b/libs/ardour/iec2ppmdsp.cc
@@ -20,81 +20,74 @@
#include <math.h>
#include "ardour/iec2ppmdsp.h"
-
float Iec2ppmdsp::_w1;
float Iec2ppmdsp::_w2;
float Iec2ppmdsp::_w3;
float Iec2ppmdsp::_g;
+Iec2ppmdsp::Iec2ppmdsp (void)
+ : _z1 (0)
+ , _z2 (0)
+ , _m (0)
+ , _res (true)
+{}
-Iec2ppmdsp::Iec2ppmdsp (void) :
- _z1 (0),
- _z2 (0),
- _m (0),
- _res (true)
-{
-}
-
+Iec2ppmdsp::~Iec2ppmdsp (void) {}
-Iec2ppmdsp::~Iec2ppmdsp (void)
+void
+Iec2ppmdsp::process (float const* p, int n)
{
+ float z1, z2, m, t;
+
+ z1 = _z1 > 20 ? 20 : (_z1 < 0 ? 0 : _z1);
+ z2 = _z2 > 20 ? 20 : (_z2 < 0 ? 0 : _z2);
+ m = _res ? 0: _m;
+ _res = false;
+
+ n /= 4;
+ while (n--) {
+ z1 *= _w3;
+ z2 *= _w3;
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = fabsf (*p++);
+ if (t > z1) z1 += _w1 * (t - z1);
+ if (t > z2) z2 += _w2 * (t - z2);
+ t = z1 + z2;
+ if (t > m) m = t;
+ }
+
+ _z1 = z1 + 1e-10f;
+ _z2 = z2 + 1e-10f;
+ _m = m;
}
-
-void Iec2ppmdsp::process (float const *p, int n)
+float
+Iec2ppmdsp::read (void)
{
- float z1, z2, m, t;
-
- z1 = _z1 > 20 ? 20 : (_z1 < 0 ? 0 : _z1);
- z2 = _z2 > 20 ? 20 : (_z2 < 0 ? 0 : _z2);
- m = _res ? 0: _m;
- _res = false;
-
- n /= 4;
- while (n--)
- {
- z1 *= _w3;
- z2 *= _w3;
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = fabsf (*p++);
- if (t > z1) z1 += _w1 * (t - z1);
- if (t > z2) z2 += _w2 * (t - z2);
- t = z1 + z2;
- if (t > m) m = t;
- }
-
- _z1 = z1 + 1e-10f;
- _z2 = z2 + 1e-10f;
- _m = m;
-}
-
-
-float Iec2ppmdsp::read (void)
-{
- _res = true;
- return _g * _m;
+ _res = true;
+ return _g * _m;
}
-void Iec2ppmdsp::reset ()
+void
+Iec2ppmdsp::reset ()
{
- _z1 = _z2 = _m = .0f;
- _res = true;
+ _z1 = _z2 = _m = .0f;
+ _res = true;
}
-void Iec2ppmdsp::init (float fsamp)
+void
+Iec2ppmdsp::init (float fsamp)
{
- _w1 = 200.0f / fsamp;
- _w2 = 860.0f / fsamp;
- _w3 = 1.0f - 4.0f / fsamp;
- _g = 0.5141f;
+ _w1 = 200.0f / fsamp;
+ _w2 = 860.0f / fsamp;
+ _w3 = 1.0f - 4.0f / fsamp;
+ _g = 0.5141f;
}
-
-/* vi:set ts=8 sts=8 sw=4: */
diff --git a/libs/ardour/kmeterdsp.cc b/libs/ardour/kmeterdsp.cc
index add026797d..5b5331660e 100644
--- a/libs/ardour/kmeterdsp.cc
+++ b/libs/ardour/kmeterdsp.cc
@@ -20,93 +20,82 @@
#include <math.h>
#include "ardour/kmeterdsp.h"
-
float Kmeterdsp::_omega;
+Kmeterdsp::Kmeterdsp (void)
+ : _z1 (0)
+ , _z2 (0)
+ , _rms (0)
+ , _flag (false)
+{}
-Kmeterdsp::Kmeterdsp (void) :
- _z1 (0),
- _z2 (0),
- _rms (0),
- _flag (false)
-{
-}
-
-
-Kmeterdsp::~Kmeterdsp (void)
-{
-}
+Kmeterdsp::~Kmeterdsp (void) {}
-void Kmeterdsp::init (int fsamp)
+void
+Kmeterdsp::init (int fsamp)
{
- _omega = 9.72f / fsamp; // ballistic filter coefficient
+ _omega = 9.72f / fsamp; // ballistic filter coefficient
}
-void Kmeterdsp::process (float const *p, int n)
+void
+Kmeterdsp::process (float const* p, int n)
{
- // Called by JACK's process callback.
- //
- // p : pointer to sample buffer
- // n : number of samples to process
-
- float s, z1, z2;
-
- // Get filter state.
- z1 = _z1 > 50 ? 50 : (_z1 < 0 ? 0 : _z1);
- z2 = _z2 > 50 ? 50 : (_z2 < 0 ? 0 : _z2);
-
- // Perform filtering. The second filter is evaluated
- // only every 4th sample - this is just an optimisation.
- n /= 4; // Loop is unrolled by 4.
- while (n--)
- {
- s = *p++;
- s *= s;
- z1 += _omega * (s - z1); // Update first filter.
- s = *p++;
- s *= s;
- z1 += _omega * (s - z1); // Update first filter.
- s = *p++;
- s *= s;
- z1 += _omega * (s - z1); // Update first filter.
- s = *p++;
- s *= s;
- z1 += _omega * (s - z1); // Update first filter.
- z2 += 4 * _omega * (z1 - z2); // Update second filter.
- }
-
- if (isnan(z1)) z1 = 0;
- if (isnan(z2)) z2 = 0;
- // Save filter state. The added constants avoid denormals.
- _z1 = z1 + 1e-20f;
- _z2 = z2 + 1e-20f;
-
- s = sqrtf (2.0f * z2);
-
- if (_flag) // Display thread has read the rms value.
- {
- _rms = s;
- _flag = false;
- }
- else
- {
- // Adjust RMS value and update maximum since last read().
- if (s > _rms) _rms = s;
- }
+ float s, z1, z2;
+
+ // Get filter state.
+ z1 = _z1 > 50 ? 50 : (_z1 < 0 ? 0 : _z1);
+ z2 = _z2 > 50 ? 50 : (_z2 < 0 ? 0 : _z2);
+
+ // Perform filtering. The second filter is evaluated
+ // only every 4th sample - this is just an optimisation.
+ n /= 4; // Loop is unrolled by 4.
+ while (n--) {
+ s = *p++;
+ s *= s;
+ z1 += _omega * (s - z1); // Update first filter.
+ s = *p++;
+ s *= s;
+ z1 += _omega * (s - z1); // Update first filter.
+ s = *p++;
+ s *= s;
+ z1 += _omega * (s - z1); // Update first filter.
+ s = *p++;
+ s *= s;
+ z1 += _omega * (s - z1); // Update first filter.
+ z2 += 4 * _omega * (z1 - z2); // Update second filter.
+ }
+
+ if (isnan(z1)) z1 = 0;
+ if (isnan(z2)) z2 = 0;
+
+ // Save filter state. The added constants avoid denormals.
+ _z1 = z1 + 1e-20f;
+ _z2 = z2 + 1e-20f;
+
+ s = sqrtf (2.0f * z2);
+
+ if (_flag) {
+ // Display thread has read the rms value.
+ _rms = s;
+ _flag = false;
+ } else {
+ // Adjust RMS value and update maximum since last read().
+ if (s > _rms) _rms = s;
+ }
}
/* Returns highest _rms value since last call */
-float Kmeterdsp::read ()
+float
+Kmeterdsp::read ()
{
- float rv= _rms;
- _flag = true; // Resets _rms in next process().
- return rv;
+ float rv= _rms;
+ _flag = true; // Resets _rms in next process().
+ return rv;
}
-void Kmeterdsp::reset ()
+void
+Kmeterdsp::reset ()
{
- _z1 = _z2 = _rms = .0f;
- _flag = false;
+ _z1 = _z2 = _rms = .0f;
+ _flag = false;
}
-
-/* vi:set ts=8 sts=8 sw=4: */
diff --git a/libs/audiographer/private/gdither/gdither.cc b/libs/audiographer/private/gdither/gdither.cc
index fd057ded37..08694ebc10 100644
--- a/libs/audiographer/private/gdither/gdither.cc
+++ b/libs/audiographer/private/gdither/gdither.cc
@@ -480,5 +480,3 @@ void gdither_runf(GDither s, uint32_t channel, uint32_t length,
s->clamp_l);
}
}
-
-/* vi:set ts=8 sts=4 sw=4: */
diff --git a/libs/plugins/reasonablesynth.lv2/lv2.c b/libs/plugins/reasonablesynth.lv2/lv2.c
index bc3715ac4e..f8bbcdee2d 100644
--- a/libs/plugins/reasonablesynth.lv2/lv2.c
+++ b/libs/plugins/reasonablesynth.lv2/lv2.c
@@ -42,82 +42,82 @@ static uint32_t synth_sound (void *, uint32_t written, uint32_t nframes, fl
#include "rsynth.c"
typedef enum {
- RSY_MIDIIN = 0,
- RSY_OUTL,
- RSY_OUTR
+ RSY_MIDIIN = 0,
+ RSY_OUTL,
+ RSY_OUTR
} PortIndex;
typedef struct {
- const LV2_Atom_Sequence* midiin;
- float* outL;
- float* outR;
+ const LV2_Atom_Sequence* midiin;
+ float* outL;
+ float* outR;
- LV2_URID_Map* map;
- LV2_URID midi_MidiEvent;
+ LV2_URID_Map* map;
+ LV2_URID midi_MidiEvent;
- double SampleRateD;
- void *synth;
- bool xmas;
+ double SampleRateD;
+ void *synth;
+ bool xmas;
} RSynth;
/* main LV2 */
static LV2_Handle
-instantiate(const LV2_Descriptor* descriptor,
- double rate,
- const char* bundle_path,
- const LV2_Feature* const* features)
+instantiate (const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
{
- (void) descriptor; /* unused variable */
- (void) bundle_path; /* unused variable */
-
- if (rate < 8000) {
- fprintf(stderr, "RSynth.lv2 error: unsupported sample-rate (must be > 8k)\n");
- return NULL;
- }
- RSynth* self = (RSynth*)calloc(1, sizeof(RSynth));
- if(!self) {
- return NULL;
- }
-
- self->SampleRateD = rate;
-
- int i;
- for (i=0; features[i]; ++i) {
- if (!strcmp(features[i]->URI, LV2_URID__map)) {
- self->map = (LV2_URID_Map*)features[i]->data;
- }
- }
-
- if (!self->map) {
- fprintf(stderr, "RSynth.lv2 error: Host does not support urid:map\n");
- free(self);
- return NULL;
- }
-
- self->midi_MidiEvent = self->map->map(self->map->handle, LV2_MIDI__MidiEvent);
-
- self->synth = synth_alloc();
- synth_init(self->synth, rate);
+ (void) descriptor; /* unused variable */
+ (void) bundle_path; /* unused variable */
+
+ if (rate < 8000) {
+ fprintf(stderr, "RSynth.lv2 error: unsupported sample-rate (must be > 8k)\n");
+ return NULL;
+ }
+ RSynth* self = (RSynth*)calloc(1, sizeof(RSynth));
+ if(!self) {
+ return NULL;
+ }
+
+ self->SampleRateD = rate;
+
+ int i;
+ for (i=0; features[i]; ++i) {
+ if (!strcmp(features[i]->URI, LV2_URID__map)) {
+ self->map = (LV2_URID_Map*)features[i]->data;
+ }
+ }
+
+ if (!self->map) {
+ fprintf(stderr, "RSynth.lv2 error: Host does not support urid:map\n");
+ free(self);
+ return NULL;
+ }
+
+ self->midi_MidiEvent = self->map->map(self->map->handle, LV2_MIDI__MidiEvent);
+
+ self->synth = synth_alloc();
+ synth_init(self->synth, rate);
#ifndef PLATFORM_WINDOWS // easter egg is for sane platforms with native support for localtime_r only
- struct tm date;
- time_t now;
- time(&now);
- localtime_r(&now, &date);
- if (getenv("ITSXMAS") || (date.tm_mon == 11 /*dec*/ && date.tm_mday == 25)) {
- printf("reasonable synth.lv2 says: happy holidays!\n");
- self->xmas = true;
- }
+ struct tm date;
+ time_t now;
+ time(&now);
+ localtime_r(&now, &date);
+ if (getenv("ITSXMAS") || (date.tm_mon == 11 /*dec*/ && date.tm_mday == 25)) {
+ printf("reasonable synth.lv2 says: happy holidays!\n");
+ self->xmas = true;
+ }
#endif
- return (LV2_Handle)self;
+ return (LV2_Handle)self;
}
static void
-connect_port(LV2_Handle handle,
- uint32_t port,
- void* data)
+connect_port (LV2_Handle handle,
+ uint32_t port,
+ void* data)
{
RSynth* self = (RSynth*)handle;
@@ -135,76 +135,76 @@ connect_port(LV2_Handle handle,
}
static void
-run(LV2_Handle handle, uint32_t n_samples)
+run (LV2_Handle handle, uint32_t n_samples)
{
- RSynth* self = (RSynth*)handle;
- float* audio[2];
-
- audio[0] = self->outL;
- audio[1] = self->outR;
-
- uint32_t written = 0;
-
- /* Process incoming MIDI events */
- if (self->midiin) {
- LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((uintptr_t)((&(self->midiin)->body) + 1)); // lv2_atom_sequence_begin
- while( // !lv2_atom_sequence_is_end
- (const uint8_t*)ev < ((const uint8_t*) &(self->midiin)->body + (self->midiin)->atom.size)
- )
- {
- if (ev->body.type == self->midi_MidiEvent) {
+ RSynth* self = (RSynth*)handle;
+ float* audio[2];
+
+ audio[0] = self->outL;
+ audio[1] = self->outR;
+
+ uint32_t written = 0;
+
+ /* Process incoming MIDI events */
+ if (self->midiin) {
+ LV2_Atom_Event const* ev = (LV2_Atom_Event const*)((uintptr_t)((&(self->midiin)->body) + 1)); // lv2_atom_sequence_begin
+ while( // !lv2_atom_sequence_is_end
+ (const uint8_t*)ev < ((const uint8_t*) &(self->midiin)->body + (self->midiin)->atom.size)
+ )
+ {
+ if (ev->body.type == self->midi_MidiEvent) {
#ifdef DEBUG_MIDI_EVENT // debug midi messages in synth -- not rt-safe(!)
- printf ("%5d (%d):", ev->time.frames, ev->body.size);
- for (uint8_t i = 0; i < ev->body.size; ++i) {
- printf (" %02x", ((const uint8_t*)(ev+1))[i]);
- }
- printf ("\n");
+ printf ("%5d (%d):", ev->time.frames, ev->body.size);
+ for (uint8_t i = 0; i < ev->body.size; ++i) {
+ printf (" %02x", ((const uint8_t*)(ev+1))[i]);
+ }
+ printf ("\n");
#endif
- if (written + BUFFER_SIZE_SAMPLES < ev->time.frames
- && ev->time.frames < n_samples) {
- /* first synthesize sound up until the message timestamp */
- written = synth_sound(self->synth, written, ev->time.frames, audio);
- }
- /* send midi message to synth */
- if (self->xmas) {
- synth_parse_xmas(self->synth, (const uint8_t*)(ev+1), ev->body.size);
- } else {
- synth_parse_midi(self->synth, (const uint8_t*)(ev+1), ev->body.size);
- }
- }
- ev = (LV2_Atom_Event const*) // lv2_atom_sequence_next()
- ((uintptr_t)((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7)));
- }
- }
-
- /* synthesize [remaining] sound */
- synth_sound(self->synth, written, n_samples, audio);
+ if (written + BUFFER_SIZE_SAMPLES < ev->time.frames
+ && ev->time.frames < n_samples) {
+ /* first synthesize sound up until the message timestamp */
+ written = synth_sound(self->synth, written, ev->time.frames, audio);
+ }
+ /* send midi message to synth */
+ if (self->xmas) {
+ synth_parse_xmas(self->synth, (const uint8_t*)(ev+1), ev->body.size);
+ } else {
+ synth_parse_midi(self->synth, (const uint8_t*)(ev+1), ev->body.size);
+ }
+ }
+ ev = (LV2_Atom_Event const*) // lv2_atom_sequence_next()
+ ((uintptr_t)((const uint8_t*)ev + sizeof(LV2_Atom_Event) + ((ev->body.size + 7) & ~7)));
+ }
+ }
+
+ /* synthesize [remaining] sound */
+ synth_sound(self->synth, written, n_samples, audio);
}
static void
cleanup(LV2_Handle handle)
{
- RSynth* self = (RSynth*)handle;
- synth_free(self->synth);
- free(handle);
+ RSynth* self = (RSynth*)handle;
+ synth_free(self->synth);
+ free(handle);
}
static const void*
extension_data(const char* uri)
{
- (void) uri; /* unused variable */
- return NULL;
+ (void) uri; /* unused variable */
+ return NULL;
}
static const LV2_Descriptor descriptor = {
- RSY_URI,
- instantiate,
- connect_port,
- NULL,
- run,
- NULL,
- cleanup,
- extension_data
+ RSY_URI,
+ instantiate,
+ connect_port,
+ NULL,
+ run,
+ NULL,
+ cleanup,
+ extension_data
};
#if defined(COMPILER_MSVC)
@@ -215,12 +215,10 @@ __attribute__ ((visibility ("default")))
const LV2_Descriptor*
lv2_descriptor(uint32_t idx)
{
- switch (idx) {
- case 0:
- return &descriptor;
- default:
- return NULL;
- }
+ switch (idx) {
+ case 0:
+ return &descriptor;
+ default:
+ return NULL;
+ }
}
-
-/* vi:set ts=8 sts=2 sw=2 et: */
diff --git a/libs/plugins/reasonablesynth.lv2/rsynth.c b/libs/plugins/reasonablesynth.lv2/rsynth.c
index 5848bee14c..cee4042b94 100644
--- a/libs/plugins/reasonablesynth.lv2/rsynth.c
+++ b/libs/plugins/reasonablesynth.lv2/rsynth.c
@@ -1,6 +1,6 @@
-/* reasonable simple synth
+/* reasonably simple synth
*
- * Copyright (C) 2013 Robin Gareus <robin@gareus.org>
+ * Copyright (C) 2013, 2019 Robin Gareus <robin@gareus.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -42,65 +42,67 @@
/* internal MIDI event abstraction */
enum RMIDI_EV_TYPE {
- INVALID=0,
- NOTE_ON,
- NOTE_OFF,
- PROGRAM_CHANGE,
- CONTROL_CHANGE,
+ INVALID=0,
+ NOTE_ON,
+ NOTE_OFF,
+ PROGRAM_CHANGE,
+ CONTROL_CHANGE,
};
struct rmidi_event_t {
- enum RMIDI_EV_TYPE type;
- uint8_t channel; /**< the MIDI channel number 0-15 */
- union {
- struct {
- uint8_t note;
- uint8_t velocity;
- } tone;
- struct {
- uint8_t param;
- uint8_t value;
- } control;
- } d;
+ enum RMIDI_EV_TYPE type;
+ uint8_t channel; /**< the MIDI channel number 0-15 */
+ union {
+ struct {
+ uint8_t note;
+ uint8_t velocity;
+ } tone;
+ struct {
+ uint8_t param;
+ uint8_t value;
+ } control;
+ } d;
};
typedef struct {
- uint32_t tme[3]; // attack, decay, release times [settings:ms || internal:samples]
- float vol[2]; // attack, sustain volume [0..1]
- uint32_t off[3]; // internal use (added attack,decay,release times)
+ uint32_t tme[3]; // attack, decay, release times [settings:ms || internal:samples]
+ float vol[2]; // attack, sustain volume [0..1]
+ uint32_t off[3]; // internal use (added attack,decay,release times)
} ADSRcfg;
typedef struct _RSSynthChannel {
- uint32_t keycomp;
- uint32_t adsr_cnt[128];
- float adsr_amp[128];
- float phase[128]; // various use, zero'ed on note-on
- int8_t miditable[128]; // internal, note-on/off velocity
- int8_t midimsgs [128]; // internal, note-off + on in same cycle, sustained-off
- int8_t sustain; // sustain pedal pressed
- ADSRcfg adsr;
- void (*synthesize) (struct _RSSynthChannel* sc,
- const uint8_t note, const float vol, const float pc,
- const size_t n_samples, float* left, float* right);
+ uint32_t keycomp;
+ uint32_t adsr_cnt[128];
+ float adsr_amp[128];
+ float phase[128]; // various use, zero'ed on note-on
+ int8_t miditable[128]; // internal, note-on/off velocity
+ int8_t midimsgs [128]; // internal, note-off + on in same cycle, sustained-off
+ int8_t sustain; // sustain pedal pressed
+ ADSRcfg adsr;
+ void (*synthesize) (struct _RSSynthChannel* sc,
+ const uint8_t note, const float vol, const float pc,
+ const size_t n_samples, float* left, float* right);
} RSSynthChannel;
typedef void (*SynthFunction) (RSSynthChannel* sc,
- const uint8_t note, const float vol, const float pc,
- const size_t n_samples, float* left, float* right);
+ const uint8_t note,
+ const float vol,
+ const float pc,
+ const size_t n_samples,
+ float* left, float* right);
typedef struct {
- uint32_t boffset;
- float buf [2][BUFFER_SIZE_SAMPLES];
- RSSynthChannel sc[16];
- float freqs[128];
- float kcgain;
- float kcfilt;
- double rate;
- uint32_t xmas_on;
- uint32_t xmas_off;
+ uint32_t boffset;
+ float buf [2][BUFFER_SIZE_SAMPLES];
+ RSSynthChannel sc[16];
+ float freqs[128];
+ float kcgain;
+ float kcfilt;
+ double rate;
+ uint32_t xmas_on;
+ uint32_t xmas_off;
} RSSynthesizer;
-
/* initialize ADSR values
*
* @param rate sample-rate
@@ -110,286 +112,298 @@ typedef struct {
* @param avol attack gain [0..1]
* @param svol sustain volume level [0..1]
*/
-static void init_adsr(ADSRcfg *adsr, const double rate,
- const uint32_t a, const uint32_t d, const uint32_t r,
- const float avol, const float svol) {
-
- adsr->vol[0] = avol;
- adsr->vol[1] = svol;
- adsr->tme[0] = a * rate / 1000.0;
- adsr->tme[1] = d * rate / 1000.0;
- adsr->tme[2] = r * rate / 1000.0;
-
- assert(adsr->tme[0] > 32);
- assert(adsr->tme[1] > 32);
- assert(adsr->tme[2] > 32);
- assert(adsr->vol[0] >=0 && adsr->vol[1] <= 1.0);
- assert(adsr->vol[1] >=0 && adsr->vol[1] <= 1.0);
-
- adsr->off[0] = adsr->tme[0];
- adsr->off[1] = adsr->tme[1] + adsr->off[0];
- adsr->off[2] = adsr->tme[2] + adsr->off[1];
+static void
+init_adsr (ADSRcfg *adsr, const double rate,
+ const uint32_t a, const uint32_t d, const uint32_t r,
+ const float avol, const float svol)
+{
+ adsr->vol[0] = avol;
+ adsr->vol[1] = svol;
+ adsr->tme[0] = a * rate / 1000.0;
+ adsr->tme[1] = d * rate / 1000.0;
+ adsr->tme[2] = r * rate / 1000.0;
+
+ assert(adsr->tme[0] > 32);
+ assert(adsr->tme[1] > 32);
+ assert(adsr->tme[2] > 32);
+ assert(adsr->vol[0] >=0 && adsr->vol[1] <= 1.0);
+ assert(adsr->vol[1] >=0 && adsr->vol[1] <= 1.0);
+
+ adsr->off[0] = adsr->tme[0];
+ adsr->off[1] = adsr->tme[1] + adsr->off[0];
+ adsr->off[2] = adsr->tme[2] + adsr->off[1];
}
/* calculate per-sample, per-key envelope */
-static inline float adsr_env(RSSynthChannel *sc, const uint8_t note) {
-
- if (sc->adsr_cnt[note] < sc->adsr.off[0]) {
- // attack
- const uint32_t p = ++sc->adsr_cnt[note];
- if (p == sc->adsr.tme[0]) {
- sc->adsr_amp[note] = sc->adsr.vol[0];
- return sc->adsr.vol[0];
- } else {
- const float d = sc->adsr.vol[0] - sc->adsr_amp[note];
- return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[0]) * d;
- }
- }
- else if (sc->adsr_cnt[note] < sc->adsr.off[1]) {
- // decay
- const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[0];
- if (p == sc->adsr.tme[1]) {
- sc->adsr_amp[note] = sc->adsr.vol[1];
- return sc->adsr.vol[1];
- } else {
- const float d = sc->adsr.vol[1] - sc->adsr_amp[note];
- return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[1]) * d;
- }
- }
- else if (sc->adsr_cnt[note] == sc->adsr.off[1]) {
- // sustain
- return sc->adsr.vol[1];
- }
- else if (sc->adsr_cnt[note] < sc->adsr.off[2]) {
- // release
- const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[1];
- if (p == sc->adsr.tme[2]) {
- sc->adsr_amp[note] = 0;
- return 0;
- } else {
- const float d = 0 - sc->adsr_amp[note];
- return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[2]) * d;
- }
- }
- else {
- sc->adsr_cnt[note] = 0;
- return 0;
- }
+static inline float
+adsr_env(RSSynthChannel *sc, const uint8_t note)
+{
+ if (sc->adsr_cnt[note] < sc->adsr.off[0]) {
+ // attack
+ const uint32_t p = ++sc->adsr_cnt[note];
+ if (p == sc->adsr.tme[0]) {
+ sc->adsr_amp[note] = sc->adsr.vol[0];
+ return sc->adsr.vol[0];
+ } else {
+ const float d = sc->adsr.vol[0] - sc->adsr_amp[note];
+ return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[0]) * d;
+ }
+ }
+ else if (sc->adsr_cnt[note] < sc->adsr.off[1]) {
+ // decay
+ const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[0];
+ if (p == sc->adsr.tme[1]) {
+ sc->adsr_amp[note] = sc->adsr.vol[1];
+ return sc->adsr.vol[1];
+ } else {
+ const float d = sc->adsr.vol[1] - sc->adsr_amp[note];
+ return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[1]) * d;
+ }
+ }
+ else if (sc->adsr_cnt[note] == sc->adsr.off[1]) {
+ // sustain
+ return sc->adsr.vol[1];
+ }
+ else if (sc->adsr_cnt[note] < sc->adsr.off[2]) {
+ // release
+ const uint32_t p = ++sc->adsr_cnt[note] - sc->adsr.off[1];
+ if (p == sc->adsr.tme[2]) {
+ sc->adsr_amp[note] = 0;
+ return 0;
+ } else {
+ const float d = 0 - sc->adsr_amp[note];
+ return sc->adsr_amp[note] + (p / (float) sc->adsr.tme[2]) * d;
+ }
+ }
+ else {
+ sc->adsr_cnt[note] = 0;
+ return 0;
+ }
}
-
/*****************************************************************************/
/* piano like sound w/slight stereo phase */
-static void synthesize_sineP (RSSynthChannel* sc,
- const uint8_t note, const float vol, const float fq,
- const size_t n_samples, float* left, float* right) {
-
- size_t i;
- float phase = sc->phase[note];
-
- for (i=0; i < n_samples; ++i) {
- float env = adsr_env(sc, note);
- if (sc->adsr_cnt[note] == 0) break;
- const float amp = vol * env;
- if (amp > 1e-10) {
- left[i] += amp * sinf(2.0 * M_PI * phase);
- left[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0);
- left[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0);
- left[i] += .080 * amp * sinf(2.0 * M_PI * phase * 4.0);
- //left[i] -= .007 * amp * sinf(2.0 * M_PI * phase * 5.0);
- //left[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0);
- left[i] += .020 * amp * sinf(2.0 * M_PI * phase * 7.0);
- phase += fq;
- right[i] += amp * sinf(2.0 * M_PI * phase);
- right[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0);
- right[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0);
- right[i] -= .080 * amp * sinf(2.0 * M_PI * phase * 4.0);
- //right[i] += .007 * amp * sinf(2.0 * M_PI * phase * 5.0);
- //right[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0);
- right[i] -= .020 * amp * sinf(2.0 * M_PI * phase * 7.0);
- } else {
- phase += fq;
- }
- if (phase > 1.0) phase -= 2.0;
- }
- sc->phase[note] = phase;
+static void
+synthesize_sineP (RSSynthChannel* sc,
+ const uint8_t note, const float vol, const float fq,
+ const size_t n_samples, float* left, float* right)
+{
+ size_t i;
+ float phase = sc->phase[note];
+
+ for (i=0; i < n_samples; ++i) {
+ float env = adsr_env(sc, note);
+ if (sc->adsr_cnt[note] == 0) break;
+ const float amp = vol * env;
+ if (amp > 1e-10) {
+ left[i] += amp * sinf(2.0 * M_PI * phase);
+ left[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0);
+ left[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0);
+ left[i] += .080 * amp * sinf(2.0 * M_PI * phase * 4.0);
+ //left[i] -= .007 * amp * sinf(2.0 * M_PI * phase * 5.0);
+ //left[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0);
+ left[i] += .020 * amp * sinf(2.0 * M_PI * phase * 7.0);
+ phase += fq;
+ right[i] += amp * sinf(2.0 * M_PI * phase);
+ right[i] += .300 * amp * sinf(2.0 * M_PI * phase * 2.0);
+ right[i] += .150 * amp * sinf(2.0 * M_PI * phase * 3.0);
+ right[i] -= .080 * amp * sinf(2.0 * M_PI * phase * 4.0);
+ //right[i] += .007 * amp * sinf(2.0 * M_PI * phase * 5.0);
+ //right[i] += .010 * amp * sinf(2.0 * M_PI * phase * 6.0);
+ right[i] -= .020 * amp * sinf(2.0 * M_PI * phase * 7.0);
+ } else {
+ phase += fq;
+ }
+ if (phase > 1.0) phase -= 2.0;
+ }
+ sc->phase[note] = phase;
}
-static const ADSRcfg piano_adsr = {{ 5, 800, 100}, { 1.0, 0.0}, {0,0,0}};
+static const ADSRcfg piano_adsr = {{ 5, 800, 100}, { 1.0, 0.0}, {0, 0, 0}};
/*****************************************************************************/
/* process note - move through ADSR states, count active keys,.. */
-static void process_key (void *synth,
- const uint8_t chn, const uint8_t note,
- const size_t n_samples, float *left, float *right)
+static void
+process_key (void *synth,
+ const uint8_t chn, const uint8_t note,
+ const size_t n_samples,
+ float *left, float *right)
{
- RSSynthesizer* rs = (RSSynthesizer*)synth;
- RSSynthChannel* sc = &rs->sc[chn];
- const int8_t vel = sc->miditable[note];
- const int8_t msg = sc->midimsgs[note];
- const float vol = /* master_volume */ 0.1f * abs(vel) / 127.f;
- const float phase = sc->phase[note];
- const int8_t sus = sc->sustain;
- sc->midimsgs[note] &= ~3;
-
- if (phase == -10 && vel > 0) {
- // new note on
- sc->midimsgs[note] &= ~4;
- assert(sc->adsr_cnt[note] == 0);
- sc->adsr_amp[note] = 0;
- sc->adsr_cnt[note] = 0;
- sc->phase[note] = 0;
- sc->keycomp++;
- //printf("[On] Now %d keys active on chn %d\n", sc->keycomp, chn);
- }
- else if (phase >= -1.0 && phase <= 1.0 && vel > 0) {
- // sustain note or re-start note while adsr in progress:
- if (sc->adsr_cnt[note] > sc->adsr.off[1] || msg == 3 || msg == 5 || msg == 7) {
- sc->midimsgs[note] &= ~4;
- // x-fade to attack
- sc->adsr_amp[note] = adsr_env(sc, note);
- sc->adsr_cnt[note] = 0;
- }
- }
- else if (phase >= -1.0 && phase <= 1.0 && vel < 0) {
- sc->midimsgs[note] |= 4;
- // note off
- if (sc->adsr_cnt[note] <= sc->adsr.off[1] && !sus) {
- if (sc->adsr_cnt[note] != sc->adsr.off[1]) {
- // x-fade to release
- sc->adsr_amp[note] = adsr_env(sc, note);
- }
- sc->adsr_cnt[note] = sc->adsr.off[1] + 1;
- }
- else if (sus && sc->adsr_cnt[note] == sc->adsr.off[1]) {
- sc->adsr_cnt[note] = sc->adsr.off[1] + 1;
- }
- }
- else {
- //printf("FORCE NOTE OFF: %d %d\n", vel, sus);
- /* note-on + off in same cycle */
- sc->miditable[note] = 0;
- sc->adsr_cnt[note] = 0;
- sc->phase[note] = -10;
- return;
- }
- //printf("NOTE: %d (%d %d %d)\n", sc->adsr_cnt[note], sc->adsr.off[0], sc->adsr.off[1], sc->adsr.off[2]);
-
- // synthesize actual sound
- sc->synthesize(sc, note, vol, rs->freqs[note], n_samples, left, right);
-
- if (sc->adsr_cnt[note] == 0) {
- //printf("Note %d,%d released\n", chn, note);
- sc->midimsgs[note] = 0;
- sc->miditable[note] = 0;
- sc->adsr_amp[note] = 0;
- sc->phase[note] = -10;
- sc->keycomp--;
- //printf("[off] Now %d keys active on chn %d\n", sc->keycomp, chn);
- }
+ RSSynthesizer* rs = (RSSynthesizer*)synth;
+ RSSynthChannel* sc = &rs->sc[chn];
+ const int8_t vel = sc->miditable[note];
+ const int8_t msg = sc->midimsgs[note];
+ const float vol = /* master_volume */ 0.1f * abs(vel) / 127.f;
+ const float phase = sc->phase[note];
+ const int8_t sus = sc->sustain;
+ sc->midimsgs[note] &= ~3;
+
+ if (phase == -10 && vel > 0) {
+ // new note on
+ sc->midimsgs[note] &= ~4;
+ assert(sc->adsr_cnt[note] == 0);
+ sc->adsr_amp[note] = 0;
+ sc->adsr_cnt[note] = 0;
+ sc->phase[note] = 0;
+ sc->keycomp++;
+ //printf("[On] Now %d keys active on chn %d\n", sc->keycomp, chn);
+ }
+ else if (phase >= -1.0 && phase <= 1.0 && vel > 0) {
+ // sustain note or re-start note while adsr in progress:
+ if (sc->adsr_cnt[note] > sc->adsr.off[1] || msg == 3 || msg == 5 || msg == 7) {
+ sc->midimsgs[note] &= ~4;
+ // x-fade to attack
+ sc->adsr_amp[note] = adsr_env(sc, note);
+ sc->adsr_cnt[note] = 0;
+ }
+ }
+ else if (phase >= -1.0 && phase <= 1.0 && vel < 0) {
+ sc->midimsgs[note] |= 4;
+ // note off
+ if (sc->adsr_cnt[note] <= sc->adsr.off[1] && !sus) {
+ if (sc->adsr_cnt[note] != sc->adsr.off[1]) {
+ // x-fade to release
+ sc->adsr_amp[note] = adsr_env(sc, note);
+ }
+ sc->adsr_cnt[note] = sc->adsr.off[1] + 1;
+ }
+ else if (sus && sc->adsr_cnt[note] == sc->adsr.off[1]) {
+ sc->adsr_cnt[note] = sc->adsr.off[1] + 1;
+ }
+ }
+ else {
+ //printf("FORCE NOTE OFF: %d %d\n", vel, sus);
+ /* note-on + off in same cycle */
+ sc->miditable[note] = 0;
+ sc->adsr_cnt[note] = 0;
+ sc->phase[note] = -10;
+ return;
+ }
+ //printf("NOTE: %d (%d %d %d)\n", sc->adsr_cnt[note], sc->adsr.off[0], sc->adsr.off[1], sc->adsr.off[2]);
+
+ // synthesize actual sound
+ sc->synthesize(sc, note, vol, rs->freqs[note], n_samples, left, right);
+
+ if (sc->adsr_cnt[note] == 0) {
+ //printf("Note %d,%d released\n", chn, note);
+ sc->midimsgs[note] = 0;
+ sc->miditable[note] = 0;
+ sc->adsr_amp[note] = 0;
+ sc->phase[note] = -10;
+ sc->keycomp--;
+ //printf("[off] Now %d keys active on chn %d\n", sc->keycomp, chn);
+ }
}
/* synthesize a BUFFER_SIZE_SAMPLES's of audio-data */
-static void synth_fragment (void *synth, const size_t n_samples, float *left, float *right) {
- RSSynthesizer* rs = (RSSynthesizer*)synth;
- memset (left, 0, n_samples * sizeof(float));
- memset (right, 0, n_samples * sizeof(float));
- uint8_t keycomp = 0;
- int c,k;
- size_t i;
-
- for (c=0; c < 16; ++c) {
- for (k=0; k < 128; ++k) {
- if (rs->sc[c].miditable[k] == 0) continue;
- process_key(synth, c, k, n_samples, left, right);
- }
- keycomp += rs->sc[c].keycomp;
- }
+static void
+synth_fragment (void *synth, const size_t n_samples, float *left, float *right)
+{
+ RSSynthesizer* rs = (RSSynthesizer*)synth;
+ memset (left, 0, n_samples * sizeof(float));
+ memset (right, 0, n_samples * sizeof(float));
+ uint8_t keycomp = 0;
+ int c,k;
+ size_t i;
+
+ for (c=0; c < 16; ++c) {
+ for (k=0; k < 128; ++k) {
+ if (rs->sc[c].miditable[k] == 0) continue;
+ process_key(synth, c, k, n_samples, left, right);
+ }
+ keycomp += rs->sc[c].keycomp;
+ }
#if 1 // key-compression
- float kctgt = 8.0 / (float)(keycomp + 7.0);
- if (kctgt < .5) kctgt = .5;
- if (kctgt > 1.0) kctgt = 1.0;
- const float _w = rs->kcfilt;
- for (i=0; i < n_samples; ++i) {
- rs->kcgain += _w * (kctgt - rs->kcgain);
- left[i] *= rs->kcgain;
- right[i] *= rs->kcgain;
- }
- rs->kcgain += 1e-12;
+ float kctgt = 8.0 / (float)(keycomp + 7.0);
+ if (kctgt < .5) kctgt = .5;
+ if (kctgt > 1.0) kctgt = 1.0;
+ const float _w = rs->kcfilt;
+ for (i=0; i < n_samples; ++i) {
+ rs->kcgain += _w * (kctgt - rs->kcgain);
+ left[i] *= rs->kcgain;
+ right[i] *= rs->kcgain;
+ }
+ rs->kcgain += 1e-12;
#endif
}
-static void synth_reset_channel(RSSynthChannel* sc) {
- int k;
- for (k=0; k < 128; ++k) {
- sc->adsr_cnt[k] = 0;
- sc->adsr_amp[k] = 0;
- sc->phase[k] = -10;
- sc->miditable[k] = 0;
- sc->midimsgs[k] = 0;
- }
- sc->keycomp = 0;
+static void
+synth_reset_channel(RSSynthChannel* sc)
+{
+ for (int k = 0; k < 128; ++k) {
+ sc->adsr_cnt[k] = 0;
+ sc->adsr_amp[k] = 0;
+ sc->phase[k] = -10;
+ sc->miditable[k] = 0;
+ sc->midimsgs[k] = 0;
+ }
+ sc->keycomp = 0;
}
-static void synth_reset(void *synth) {
- RSSynthesizer* rs = (RSSynthesizer*)synth;
- int c;
- for (c=0; c < 16; ++c) {
- synth_reset_channel(&(rs->sc[c]));
- }
- rs->kcgain = 0;
+static void
+synth_reset(void *synth)
+{
+ RSSynthesizer* rs = (RSSynthesizer*)synth;
+ int c;
+ for (c=0; c < 16; ++c) {
+ synth_reset_channel(&(rs->sc[c]));
+ }
+ rs->kcgain = 0;
}
-static void synth_load(RSSynthChannel *sc, const double rate,
- SynthFunction synthesize,
- ADSRcfg const * const adsr) {
- synth_reset_channel(sc);
- init_adsr(&sc->adsr, rate,
- adsr->tme[0], adsr->tme[1], adsr->tme[2],
- adsr->vol[0], adsr->vol[1]);
- sc->synthesize = synthesize;
+static void
+synth_load (RSSynthChannel *sc, const double rate,
+ SynthFunction synthesize,
+ ADSRcfg const * const adsr)
+{
+ synth_reset_channel(sc);
+ init_adsr(&sc->adsr, rate,
+ adsr->tme[0], adsr->tme[1], adsr->tme[2],
+ adsr->vol[0], adsr->vol[1]);
+ sc->synthesize = synthesize;
}
-
/**
* internal abstraction of MIDI data handling
*/
-static void synth_process_midi_event(void *synth, struct rmidi_event_t *ev) {
- RSSynthesizer* rs = (RSSynthesizer*)synth;
- switch(ev->type) {
- case NOTE_ON:
- rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 1;
- if (rs->sc[ev->channel].miditable[ev->d.tone.note] <= 0)
- rs->sc[ev->channel].miditable[ev->d.tone.note] = ev->d.tone.velocity;
- break;
- case NOTE_OFF:
- rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 2;
- if (rs->sc[ev->channel].miditable[ev->d.tone.note] > 0)
- rs->sc[ev->channel].miditable[ev->d.tone.note] *= -1.0;
- break;
- case PROGRAM_CHANGE:
- break;
- case CONTROL_CHANGE:
- if (ev->d.control.param == 0x00 || ev->d.control.param == 0x20) {
- /* 0x00 and 0x20 are used for BANK select */
- } else if (ev->d.control.param == 64) {
- /* damper pedal*/
- rs->sc[ev->channel].sustain = ev->d.control.value < 64 ? 0: 1;
- } else if (ev->d.control.param == 121) {
- /* reset all controllers */
- } else if (ev->d.control.param == 120 || ev->d.control.param == 123) {
- /* Midi panic: 120: all sound off, 123: all notes off*/
- synth_reset_channel(&(rs->sc[ev->channel]));
- } else if (ev->d.control.param >= 120) {
- /* params 122-127 are reserved - skip them. */
- }
- break;
- default:
- break;
- }
+static void
+synth_process_midi_event(void *synth, struct rmidi_event_t *ev)
+{
+ RSSynthesizer* rs = (RSSynthesizer*)synth;
+ switch(ev->type) {
+ case NOTE_ON:
+ rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 1;
+ if (rs->sc[ev->channel].miditable[ev->d.tone.note] <= 0)
+ rs->sc[ev->channel].miditable[ev->d.tone.note] = ev->d.tone.velocity;
+ break;
+ case NOTE_OFF:
+ rs->sc[ev->channel].midimsgs[ev->d.tone.note] |= 2;
+ if (rs->sc[ev->channel].miditable[ev->d.tone.note] > 0)
+ rs->sc[ev->channel].miditable[ev->d.tone.note] *= -1.0;
+ break;
+ case PROGRAM_CHANGE:
+ break;
+ case CONTROL_CHANGE:
+ if (ev->d.control.param == 0x00 || ev->d.control.param == 0x20) {
+ /* 0x00 and 0x20 are used for BANK select */
+ } else if (ev->d.control.param == 64) {
+ /* damper pedal*/
+ rs->sc[ev->channel].sustain = ev->d.control.value < 64 ? 0: 1;
+ } else if (ev->d.control.param == 121) {
+ /* reset all controllers */
+ } else if (ev->d.control.param == 120 || ev->d.control.param == 123) {
+ /* Midi panic: 120: all sound off, 123: all notes off*/
+ synth_reset_channel(&(rs->sc[ev->channel]));
+ } else if (ev->d.control.param >= 120) {
+ /* params 122-127 are reserved - skip them. */
+ }
+ break;
+ default:
+ break;
+ }
}
/******************************************************************************
@@ -406,27 +420,29 @@ static void synth_process_midi_event(void *synth, struct rmidi_event_t *ev) {
* @param out pointer to stereo output buffers
* @return end of buffer (written + nframes)
*/
-static uint32_t synth_sound (void *synth, uint32_t written, const uint32_t nframes, float **out) {
- RSSynthesizer* rs = (RSSynthesizer*)synth;
+static uint32_t
+synth_sound (void *synth, uint32_t written, const uint32_t nframes, float **out)
+{
+ RSSynthesizer* rs = (RSSynthesizer*)synth;
- while (written < nframes) {
- uint32_t nremain = nframes - written;
+ while (written < nframes) {
+ uint32_t nremain = nframes - written;
- if (rs->boffset >= BUFFER_SIZE_SAMPLES) {
- const uint32_t tosynth = MIN(BUFFER_SIZE_SAMPLES, nremain);
- rs->boffset = BUFFER_SIZE_SAMPLES - tosynth;
- synth_fragment(rs, tosynth, &(rs->buf[0][rs->boffset]), &(rs->buf[1][rs->boffset]));
- }
+ if (rs->boffset >= BUFFER_SIZE_SAMPLES) {
+ const uint32_t tosynth = MIN(BUFFER_SIZE_SAMPLES, nremain);
+ rs->boffset = BUFFER_SIZE_SAMPLES - tosynth;
+ synth_fragment(rs, tosynth, &(rs->buf[0][rs->boffset]), &(rs->buf[1][rs->boffset]));
+ }
- uint32_t nread = MIN(nremain, (BUFFER_SIZE_SAMPLES - rs->boffset));
+ uint32_t nread = MIN(nremain, (BUFFER_SIZE_SAMPLES - rs->boffset));
- memcpy(&out[0][written], &rs->buf[0][rs->boffset], nread*sizeof(float));
- memcpy(&out[1][written], &rs->buf[1][rs->boffset], nread*sizeof(float));
+ memcpy(&out[0][written], &rs->buf[0][rs->boffset], nread*sizeof(float));
+ memcpy(&out[1][written], &rs->buf[1][rs->boffset], nread*sizeof(float));
- written += nread;
- rs->boffset += nread;
- }
- return written;
+ written += nread;
+ rs->boffset += nread;
+ }
+ return written;
}
/**
@@ -436,80 +452,84 @@ static uint32_t synth_sound (void *synth, uint32_t written, const uint32_t nfram
* @param data 8bit midi message
* @param size number of bytes in the midi-message
*/
-static void synth_parse_midi(void *synth, const uint8_t *data, const size_t size) {
- if (size < 2 || size > 3) return;
- // All messages need to be 3 bytes; except program-changes: 2bytes.
- if (size == 2 && (data[0] & 0xf0) != 0xC0) return;
-
- struct rmidi_event_t ev;
-
- ev.channel = data[0]&0x0f;
- switch (data[0] & 0xf0) {
- case 0x80:
- ev.type=NOTE_OFF;
- ev.d.tone.note=data[1]&0x7f;
- ev.d.tone.velocity=data[2]&0x7f;
- break;
- case 0x90:
- ev.type=NOTE_ON;
- ev.d.tone.note=data[1]&0x7f;
- ev.d.tone.velocity=data[2]&0x7f;
- if (ev.d.tone.velocity == 0) {
- ev.type=NOTE_OFF;
- }
- break;
- case 0xB0:
- ev.type=CONTROL_CHANGE;
- ev.d.control.param=data[1]&0x7f;
- ev.d.control.value=data[2]&0x7f;
- break;
- case 0xC0:
- ev.type=PROGRAM_CHANGE;
- ev.d.control.value=data[1]&0x7f;
- break;
- default:
- return;
- }
- synth_process_midi_event(synth, &ev);
+static void
+synth_parse_midi (void *synth, const uint8_t *data, const size_t size)
+{
+ if (size < 2 || size > 3) return;
+ // All messages need to be 3 bytes; except program-changes: 2bytes.
+ if (size == 2 && (data[0] & 0xf0) != 0xC0) return;
+
+ struct rmidi_event_t ev;
+
+ ev.channel = data[0]&0x0f;
+ switch (data[0] & 0xf0) {
+ case 0x80:
+ ev.type=NOTE_OFF;
+ ev.d.tone.note=data[1]&0x7f;
+ ev.d.tone.velocity=data[2]&0x7f;
+ break;
+ case 0x90:
+ ev.type=NOTE_ON;
+ ev.d.tone.note=data[1]&0x7f;
+ ev.d.tone.velocity=data[2]&0x7f;
+ if (ev.d.tone.velocity == 0) {
+ ev.type=NOTE_OFF;
+ }
+ break;
+ case 0xB0:
+ ev.type=CONTROL_CHANGE;
+ ev.d.control.param=data[1]&0x7f;
+ ev.d.control.value=data[2]&0x7f;
+ break;
+ case 0xC0:
+ ev.type=PROGRAM_CHANGE;
+ ev.d.control.value=data[1]&0x7f;
+ break;
+ default:
+ return;
+ }
+ synth_process_midi_event(synth, &ev);
}
static const uint8_t jingle[] = { 71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,71 ,69 ,69 ,71 ,69 ,74 ,71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,74 ,74 ,72 ,69 ,67 ,62 ,62 ,71 ,69 ,67 ,62 ,62 ,62 ,62 ,71 ,69 ,67 ,64 ,64 ,64 ,72 ,71 ,69 ,66 ,74 ,76 ,74 ,72 ,69 ,71 ,62 ,62 ,71 ,69 ,67 ,62 ,62 ,62 ,62 ,71 ,69 ,67 ,64 ,64 ,64 ,72 ,71 ,69 ,74 ,74 ,74 ,74 ,76 ,74 ,72 ,69 ,67 ,74 ,71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,71 ,69 ,69 ,71 ,69 ,74 ,71 ,71 ,71 ,71 ,71 ,71 ,71 ,74 ,67 ,69 ,71 ,72 ,72 ,72 ,72 ,72 ,71 ,71 ,71 ,71 ,74 ,74 ,72 ,69 ,67 };
-static void synth_parse_xmas(void *synth, const uint8_t *data, const size_t size) {
- RSSynthesizer* rs = (RSSynthesizer*)synth;
- if (size < 2 || size > 3) return;
- // All messages need to be 3 bytes; except program-changes: 2bytes.
- if (size == 2 && (data[0] & 0xf0) != 0xC0) return;
-
- struct rmidi_event_t ev;
-
- ev.channel = data[0]&0x0f;
- switch (data[0] & 0xf0) {
- case 0x80:
- ev.type=NOTE_OFF;
- ev.d.tone.note=jingle[rs->xmas_off++];
- ev.d.tone.velocity=data[2]&0x7f;
- if (rs->xmas_off >= sizeof(jingle)) rs->xmas_off = 0;
- break;
- case 0x90:
- ev.type=NOTE_ON;
- ev.d.tone.note=jingle[rs->xmas_on++];
- ev.d.tone.velocity=data[2]&0x7f;
- if (rs->xmas_on >= sizeof(jingle)) rs->xmas_on = 0;
- break;
- case 0xB0:
- ev.type=CONTROL_CHANGE;
- ev.d.control.param=data[1]&0x7f;
- ev.d.control.value=data[2]&0x7f;
- break;
- case 0xC0:
- ev.type=PROGRAM_CHANGE;
- ev.d.control.value=data[1]&0x7f;
- break;
- default:
- return;
- }
- synth_process_midi_event(synth, &ev);
+static void
+synth_parse_xmas(void *synth, const uint8_t *data, const size_t size)
+{
+ RSSynthesizer* rs = (RSSynthesizer*)synth;
+ if (size < 2 || size > 3) return;
+ // All messages need to be 3 bytes; except program-changes: 2bytes.
+ if (size == 2 && (data[0] & 0xf0) != 0xC0) return;
+
+ struct rmidi_event_t ev;
+
+ ev.channel = data[0]&0x0f;
+ switch (data[0] & 0xf0) {
+ case 0x80:
+ ev.type=NOTE_OFF;
+ ev.d.tone.note=jingle[rs->xmas_off++];
+ ev.d.tone.velocity=data[2]&0x7f;
+ if (rs->xmas_off >= sizeof(jingle)) rs->xmas_off = 0;
+ break;
+ case 0x90:
+ ev.type=NOTE_ON;
+ ev.d.tone.note=jingle[rs->xmas_on++];
+ ev.d.tone.velocity=data[2]&0x7f;
+ if (rs->xmas_on >= sizeof(jingle)) rs->xmas_on = 0;
+ break;
+ case 0xB0:
+ ev.type=CONTROL_CHANGE;
+ ev.d.control.param=data[1]&0x7f;
+ ev.d.control.value=data[2]&0x7f;
+ break;
+ case 0xC0:
+ ev.type=PROGRAM_CHANGE;
+ ev.d.control.value=data[1]&0x7f;
+ break;
+ default:
+ return;
+ }
+ synth_process_midi_event(synth, &ev);
}
/**
* initialize the synth
@@ -519,24 +539,25 @@ static void synth_parse_xmas(void *synth, const uint8_t *data, const size_t size
* @param synth synth-handle
* @param rate sample-rate
*/
-static void synth_init(void *synth, double rate) {
- RSSynthesizer* rs = (RSSynthesizer*)synth;
- rs->rate = rate;
- rs->boffset = BUFFER_SIZE_SAMPLES;
- const float tuning = 440;
- int c,k;
- for (k=0; k < 128; k++) {
- rs->freqs[k] = (tuning / 32.0f) * powf(2, (k - 9.0) / 12.0) / rate;
- assert(rs->freqs[k] < M_PI/2); // otherwise spatialization may phase out..
- }
- rs->kcfilt = 12.0 / rate;
- synth_reset(synth);
-
- for (c=0; c < 16; c++) {
- synth_load(&rs->sc[c], rate, &synthesize_sineP, &piano_adsr);
- }
- rs->xmas_on = 0;
- rs->xmas_off = 0;
+static void
+synth_init(void* synth, double rate) {
+ RSSynthesizer* rs = (RSSynthesizer*)synth;
+ rs->rate = rate;
+ rs->boffset = BUFFER_SIZE_SAMPLES;
+ const float tuning = 440;
+ int c,k;
+ for (k=0; k < 128; k++) {
+ rs->freqs[k] = (tuning / 32.0f) * powf(2, (k - 9.0) / 12.0) / rate;
+ assert(rs->freqs[k] < M_PI/2); // otherwise spatialization may phase out..
+ }
+ rs->kcfilt = 12.0 / rate;
+ synth_reset(synth);
+
+ for (c=0; c < 16; c++) {
+ synth_load(&rs->sc[c], rate, &synthesize_sineP, &piano_adsr);
+ }
+ rs->xmas_on = 0;
+ rs->xmas_off = 0;
}
/**
@@ -549,15 +570,18 @@ static void synth_init(void *synth, double rate) {
*
* @return synth-handle
*/
-static void * synth_alloc(void) {
- return calloc(1, sizeof(RSSynthesizer));
+static void*
+synth_alloc(void)
+{
+ return calloc(1, sizeof(RSSynthesizer));
}
/**
* release synth data structure
* @param synth synth-handle
*/
-static void synth_free(void *synth) {
- free(synth);
+static void
+synth_free(void *synth)
+{
+ free(synth);
}
-/* vi:set ts=8 sts=2 sw=2 et: */