(root)/wip/src/sine_mixer.cc - Rev 1242
Rev 1120 |
Rev 1274 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| RSS feed
/*
* sine_mixer.cc
* DIN Is Noise is copyright (c) 2006-2019 Jagannathan Sampath
* For more information, please visit http://dinisnoise.org/
*/
#include "dingl.h"
#include "input.h"
#include "viewwin.h"
#include "sine_mixer.h"
#include "ui_list.h"
#include "viewwin.h"
#include "vector2d.h"
#include "circler.h"
#include "log.h"
#include "console.h"
#include <math.h>
using namespace std;
extern ui_list uis;
extern viewport view;
extern const float PI;
extern const float TWO_PI;
extern int MILLION;
extern curve_library sin_lib;
extern int line_height;
sine_mixer::sine_mixer () : cp_sin ("sine_mixer_sin.crv"), sin_ed ("sine_mixer_sin.ed"), sine_levels ("sine_levels") {
plugin::name = "Sine_Mixer";
mouse_slider_listener::name = "Harmonics";
shapeform = 0;
type = 0;
orient = mouse_slider_listener::X;
sin_ed.add (&cp_sin.crv, this);
sin_ed.attach_library (&sin_lib);
}
void sine_mixer::load_params () {
ifstream f (make_fname().c_str(), ios::in);
string ignore;
f >> ignore >> num_points >> ignore >> make_shapeform >> ignore >> type;
NUM_SINE_SAMPLES = num_points + 1;
}
void sine_mixer::save_params () {
ofstream f (make_fname().c_str(), ios::out);
string ignore;
f << "num_points " << int (sp_points.f_value) << " make_shapeform " << cb_make_shapeform.state << " type " << type << endl;
}
sine_mixer::~sine_mixer () {
save_params ();
widget_save ("d_sine_mixer", ctrls);
dlog << "--- destroyed sine mixer ---" << endl;
}
void sine_mixer::num_harmonics (int h) {
nharmonics = h;
if (nharmonics < 1) nharmonics = 1;
prep_harmonics ();
}
void sine_mixer::prep_harmonics () {
harmonics.resize (nharmonics);
float df = TWO_PI / (NUM_SINE_SAMPLES - 1);
funktion& f_sin = *pf_sin;
for (int i = 0, j = 1; i < nharmonics; ++i, ++j) {
vector< point<float> >& harmonic = harmonics[i];
harmonic.resize (NUM_SINE_SAMPLES);
float dx = j * df;
float x = 0;
for (int p = 0; p < NUM_SINE_SAMPLES; ++p) {
point<float>& hp = harmonic[p];
hp.x = cos(x);
hp.y = f_sin (x, TWO_PI);
x += dx;
if (x > TWO_PI) x -= TWO_PI;
}
}
norm.resize (NUM_SINE_SAMPLES);
mix ();
}
void sine_mixer::mix () {
for (int p = 0; p < NUM_SINE_SAMPLES; ++p) { point<float>& pi = norm[p]; pi.x = pi.y = 0;}
ss.str(""); ss << plugin::name;
for (int i = 0; i < nharmonics; ++i) {
float lev = sine_levels.values[i];
if (lev > 0) {
vector< point<float> >& harmonic = harmonics[i];
for (int p = 0; p < NUM_SINE_SAMPLES; ++p) {
point<float>& np = norm[p];
point<float>& hp = harmonic[p];
np.x += (lev * hp.x);
np.y += (lev * hp.y);
}
ss << '_' << (i+1);
}
}
normalise ();
}
void sine_mixer::normalise () {
int n = NUM_SINE_SAMPLES;
if (n) {
point<float>& np0 = norm[0];
float maxy = fabs (np0.y), maxx = fabs (np0.x);
for (int i = 0; i < n; ++i) {
point<float>& pi = norm[i];
float vx = fabs (pi.x), vy = fabs (pi.y);
if (vx > maxx) maxx = vx;
if (vy > maxy) maxy = vy;
}
if (maxx != 0) for (int p = 0; p < n; ++p) norm[p].x /= maxx;
if (maxy != 0) for (int p = 0; p < n; ++p) norm[p].y /= maxy;
}
}
void sine_mixer::render () {
undo = !cb_auto_apply.state;
shapeform = cb_make_shapeform.state;
int ns = norm.size ();
points.resize (ns);
if (shapeform) {
for (int i = 0; i < ns; ++i) {
point<float>& ni = norm[i];
point<float>& pi = points[i];
pi.x = ni.x;
pi.y = ni.y;
}
} else {
float x = 0;
float dx = 1.0f / (NUM_SINE_SAMPLES - 1);
for (int i = 0; i < ns; ++i) {
point<float>& ni = norm[i];
point<float>& pi = points[i];
pi.x = x;
pi.y = ni.y;
x += dx;
}
}
gen_pts ();
}
void sine_mixer::setup () {
plugin::setup ();
widget* _ctrls [] = {&sine_levels, &sp_points, &cb_make_shapeform, &ol_sin, &b_edit, &cb_paint_harmonics, &fb_mover, &b_lshift, &b_rshift, &b_slide, &cb_wrap};
for (int i = 0; i < 11; ++i) {
ctrls.push_back (_ctrls[i]);
//_ctrls[i]->set_moveable(1);
}
num_ctrls = ctrls.size ();
load_params ();
sp_points.set_text ("Points");
sp_points.set_limits (1, MILLION);
sp_points.set_value (num_points);
sp_points.set_delta (1);
sp_points.set_listener (this);
sine_levels.set_listener (this);
cb_make_shapeform.set_text ("Make shapeform");
cb_make_shapeform.set_state (make_shapeform);
cb_make_shapeform.set_listener (this);
cb_paint_harmonics.set_text ("Paint harmonics");
cb_paint_harmonics.set_listener (this);
ol_sin.set_listener (this);
fb_mover.movlis = this;
widget_load ("d_sine_mixer", ctrls);
fb_mover.set_pos (sine_levels.extents.right + sine_levels.elem_width, sine_levels.extents.bottom);
fb_mover.set_moveable (1);
//ol_sin.add_child (&b_edit);
b_edit.set_text ("Edit");
b_lshift.set_pos (fb_mover.extents.left, b_lshift.extents.bottom);
b_lshift.set_text ("<<");
b_rshift.set_text (">>");
b_slide.set_text ("Slide");
cb_wrap.set_text ("Wrap");
cb_wrap.set_state (sine_levels.wrap);
cb_wrap.set_listener (this);
button* bw [] = {&b_edit, &b_lshift, &b_rshift, &b_slide};
for (int i = 0; i < 4; ++i) {
button* bwi = bw[i];
bwi->set_listener (this);
}
b_lshift.click_repeat = b_rshift.click_repeat = 1;
set_type ();
num_harmonics (sine_levels.nlev);
render ();
}
void sine_mixer::set_type () {
if (type) {
pf_sin = &cp_sin;
ol_sin.option.set_text (" Custom sin");
b_edit.set_color (clr.r, clr.g, clr.b);
b_edit.set_listener (this);
} else {
pf_sin = &st_sin;
ol_sin.option.set_text (" Standard sin");
b_edit.set_color (0.25f, 0.25f, 0.25f);
b_edit.set_listener (0);
}
int spacer = 10; b_edit.set_pos (ol_sin.option.extents.right + spacer, ol_sin.option.extents.bottom);
}
void sine_mixer::changed (field& f) {
if (&f == &sp_points.f_value) {
set_samples (f);
do_render ();
}
}
void sine_mixer::changed (levels& l) {
mix ();
do_render ();
}
void sine_mixer::changed (checkbutton& cb) {
if (&cb == &cb_make_shapeform) {
render ();
apply_not_auto_apply ();
} else if (&cb == &cb_paint_harmonics) {
sine_levels.paint = cb_paint_harmonics.state;
} else if (&cb == &cb_wrap) {
sine_levels.wrap = cb_wrap.state;
} else plugin::changed (cb);
}
void sine_mixer::set_samples (int s) {
NUM_SINE_SAMPLES = s + 1;
if (NUM_SINE_SAMPLES < MIN_SINE_SAMPLES) NUM_SINE_SAMPLES = MIN_SINE_SAMPLES;
prep_harmonics ();
}
void sine_mixer::apply_not_auto_apply () {
if (cb_auto_apply.state) {
plugin::mix = undo = 1;
uis.crved->apply_plugin (this);
plugin::mix = undo = 0;
} else uis.crved->apply_plugin (this);
}
void sine_mixer::picked (label& lbl, int dir) {
type = !type;
set_type ();
prep_harmonics ();
render ();
}
void sine_mixer::shift_apply () {
mix ();
render ();
apply_not_auto_apply ();
}
void sine_mixer::clicked (button& b) {
if (&b == &b_edit) {
uis.set_current (&sin_ed);
return;
} else if (&b == &b_lshift) {
if (sine_levels.lshift ()) shift_apply ();
} else if (&b == &b_rshift) {
if (sine_levels.rshift ()) shift_apply ();
} else if (&b == &b_slide) {
extern mouse_slider mouse_slider0;
if (is_mouse_slider_active ())
return;
else {
mouse_slider0.add (this);
activate_mouse_slider ();
}
} else plugin::clicked (b);
}
void sine_mixer::edited (curve_editor* e, int i) {
cp_sin.sol.update ();
curve_listener::edited (e, i);
prep_harmonics ();
render ();
}
void sine_mixer::moved () {
if (sine_levels.extents.top > fb_mover.extents.bottom) {
sine_levels.height = sine_levels.extents.height = sine_levels.extents.top - fb_mover.extents.bottom;
sine_levels.set_pos (sine_levels.posx, fb_mover.posy);
sine_levels.reheight ();
}
fb_mover.set_pos (sine_levels.extents.right + sine_levels.elem_width, fb_mover.extents.bottom);
}
void sine_mixer::moused (int dx) {
if (dx > 0) sine_levels.rshift (); else sine_levels.lshift ();
shift_apply ();
}