File: sine_mixer.cc

package info (click to toggle)
din 5.2.1-3
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 2,152 kB
  • ctags: 2,490
  • sloc: cpp: 9,369; sh: 6,563; ansic: 2,977; tcl: 1,770; makefile: 285
file content (128 lines) | stat: -rw-r--r-- 3,096 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/*
 * This file is part of din.
 *
 * din is copyright (c) 2006 - 2012 S Jagannathan <jag@dinisnoise.org>
 * For more information, please visit http://dinisnoise.org
 *
 * din is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * din is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with din.  If not, see <http://www.gnu.org/licenses/>.
 *
*/
#include "sine_mixer.h"
#include "viewwin.h"
#include "input.h"
#include "console.h"
#include "dingl.h"
#include <iostream>
#include <math.h>
using namespace std;

extern console cons;

sine_mixer::sine_mixer () : sine_levels ("sine_levels") {
  num_harmonics (sine_levels.nlev);
}

sine_mixer::~sine_mixer () {}

void sine_mixer::num_harmonics (int h) {
  nharmonics = h;
  if (nharmonics < 1) nharmonics = 1;
  prep_harmonics ();
}

void sine_mixer::prep_harmonics () {

  harmonics.clear ();

  for (int i = 0, j = 1; i < nharmonics; ++i, ++j) {
    harmonics.push_back (vector<float>());
    vector<float>& harmonic = harmonics[i];
    harmonic.clear ();
    float dx = 2 * pi * j / (NUM_SINE_SAMPLES - 1);
    float x = 0;
    for (int p = 0; p < NUM_SINE_SAMPLES; ++p) {
      harmonic.push_back (sin(x));
      x += dx;
    }
  }

  nonorm.clear ();
  for (int i = 0; i < NUM_SINE_SAMPLES; ++i) nonorm.push_back(0);

  mix ();

}

void sine_mixer::mix () {

  for (int p = 0, q = nonorm.size (); p < q; ++p) nonorm[p] = 0;

  for (int i = 0; i < nharmonics; ++i) {
    float lev = sine_levels.values[i];
    if (lev != 0) {
      vector<float>& harmonic = harmonics[i];
      for (int p = 0, q = nonorm.size (); p < q; ++p) nonorm[p] += (lev * harmonic[p]);
    }
  }

  normalise ();

}

void sine_mixer::normalise () {
  norm = nonorm;
  int n = norm.size ();
  if (n) {
    float max = fabs (norm [0]);
    for (int i = 0; i < n; ++i) {
      float v = fabs (norm[i]);
      if (v > max) max = v;
    }
    if (max != 0) for (int p = 0; p < n; ++p) norm[p] /= max;
  }
}

bool sine_mixer::handle_input () {
  bool result = sine_levels.handle_input ();
  if (result) {mix (); return true;}
  return false;
}

void sine_mixer::draw () {
  sine_levels.draw ();
}

void sine_mixer::make_curve (multi_curve& c) {
  float dx = 1. / (NUM_SINE_SAMPLES - 1);
  float x = 0;
  c.clear (0);
  for (int i = 0, j = norm.size(); i < j; ++i) {
    float y = norm[i];
    c.add_vertex (x, y);
    c.add_left_tangent (x, y);
    c.add_right_tangent (x, y);
    x += dx;
  }
  c.evaluate ();
}

void sine_mixer::set_sine_samples (int s) {

  NUM_SINE_SAMPLES = s;
  if (NUM_SINE_SAMPLES < MIN_SINE_SAMPLES) NUM_SINE_SAMPLES = MIN_SINE_SAMPLES;

  extern sine_mixer sinemixer;
  sinemixer.prep_harmonics ();

}