(root)/wip/src/triggered_note.cc - Rev 2308
Rev 2302 |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* triggered_note.cc
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
* DIN Is Noise is released under GNU Public License 2.0
* For more information, please visit https://dinisnoise.org/
*/
#include "triggered_note.h"
#include "chrono.h"
#include "main.h"
#include "utils.h"
#include "color.h"
#include "just.h"
#include <cmath>
extern int SAMPLE_RATE;
extern float SAMPLE_DURATION;
extern float MIN_TIME;
triggered_note::triggered_note (const note& n, float vmax, float xx, float yy, int _what, int _bin, int _just, float _sep, int k, int pmx) {
tn = n;
start_hz = tn.hz;
volume.now = 0;
volume.max = vmax;
state = ATTACK;
abs_attack = 0;
decay_time = 0;
decay_start_volume = 0;
abs_decay = 0;
x = xx; y = yy;
key = k;
prev_mousex = pmx;
bend = 1;
bend_x = 0;
what = _what;
if (what == NOISE) {
nsr.set_samples (SAMPLE_RATE / tn.hz);
nsr.set_spread (volume.max);
volume.mult = volume.max;
r = 1.0f; g = r; b = g;
} else {
volume.mult = 1.0f;
set_rnd_color (r, g, b);
}
binaural = _bin;
just = _just;
sep.hz = _sep;
}
void triggered_note::setup (multi_curve* wav, multi_curve* atk, multi_curve* dk) {
sol (wav);
player.set_wave (&sol);
if (binaural) {
sol2 (wav);
player2.set_wave (&sol2);
hz2step (sep.hz, sep.val);
if (just == just::RANDOM) just = get_rand_bit ();
if (just) { // R justified
player2.fill_pitch (tn.step);
player.fill_pitch (tn.step - sep.val);
} else { // L justified
player.fill_pitch (tn.step);
player2.fill_pitch (tn.step + sep.val);
}
} else {
player.fill_pitch (tn.step);
}
attack (atk);
decay (dk);
startt = ui_clk ();
}
void triggered_note::eval (float* L, float* R, float* wav, float* vol, int n, float attack_time, float decay_time, gotog& __gotog ) {
float& vn_1 = vol[n-1];
switch (state) {
case ATTACK:
if (equals (attack_time, 0.0f)) attack_time = MIN_TIME;
delta_attack = SAMPLE_DURATION * 1.0f / attack_time;
attack (abs_attack, delta_attack, n, vol, _atmin, __gotog); // solve attack curve to get bunch of volumes (range 0 to 1)
if (what == NOTE) {
for (int i = 0; i < n; ++i) vol[i] *= volume.max; // scale volume
if (binaural) {
player.master (L, wav, n, vol);
player2.master (R, wav, n, vol);
} else {
player.master (L, R, wav, n, vol);
}
volume.now = vn_1;
} else {
nsr (L, R, n, vol);
volume.now = vn_1 * volume.max;
}
decay_start_volume = vn_1;
break;
case DECAY:
if (equals (decay_time, 0.0f)) decay_time = MIN_TIME;
decay_time = fabs (decay_start_volume) * volume.mult / volume.max * decay_time;
delta_decay = SAMPLE_DURATION * 1.0f / decay_time;
decay (abs_decay, delta_decay, n, vol, _atmin, _atmax);
for (int i = 0; i < n; ++i) vol[i] *= decay_start_volume;
if (what == NOTE) {
if (binaural) {
player.master (L, wav, n, vol);
player2.master (R, wav, n, vol);
} else {
player.master (L, R, wav, n, vol);
}
volume.now = vn_1;
} else {
nsr (L, R, n, vol);
volume.now = vn_1 * volume.max;
}
float x, y; decay.mcrv->get_vertex (decay.mcrv->last_vertex, x, y);
if (abs_decay >= x) state = FINISHED;
break;
}
}
void triggered_note::eval (float attack_time) {
if (state == ATTACK) {
float now = ui_clk ();
float dt = now - startt;
if (dt < attack_time) ; else start_decay ();
}
}
void triggered_note::start_decay () {
if (state == ATTACK) {
state = DECAY;
if (equals (volume.max, 0.0f) || equals (decay_start_volume, 0.0f))
state = FINISHED;
else
abs_decay = 0;
}
}
void triggered_note::set_freq (float f) {
if (what == NOTE) {
tn.set_freq (f);
if (binaural) {
if (just) {
player2.set_interpolated_pitch (tn.step - sep.val);
player.set_interpolated_pitch (tn.step);
} else {
player.set_interpolated_pitch (tn.step);
player2.set_interpolated_pitch (tn.step + sep.val);
}
} else {
player.set_interpolated_pitch (tn.step);
}
} else
nsr.set_samples (SAMPLE_RATE / f);
}
int triggered_note::update_solver (multi_curve& crv, const string& nam) {
sol.update ();
if (binaural) sol2.update ();
int ret = 0;
if (crv.num_vertices) {
player.set_mix (crv, nam);
ret = player.mixer.active;
if (binaural) {
player2.set_mix (crv, nam);
ret &= player2.mixer.active;
}
}
return ret;
}
void update_triggered_notes (std::list<triggered_note>& tl) {
for (note_iterator i = tl.begin (), j = tl.end (); i != j; ++i) {
triggered_note& ti = *i;
ti.player.realloc ();
}
}
void update_triggered_noises (std::list<triggered_note>& tl) {
for (note_iterator i = tl.begin (), j = tl.end (); i != j; ++i) {
triggered_note& ti = *i;
ti.nsr.warp (&noiser::interp);
}
}