Subversion Repositories DIN Is Noise

Rev

Rev 2302 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
964 jag 1
/*
2
* play.cc
2302 jag 3
* DIN Is Noise is copyright (c) 2006-2025 Jagannathan Sampath
1713 jag 4
* DIN Is Noise is released under GNU Public License 2.0
1479 jag 5
* For more information, please visit https://dinisnoise.org/
964 jag 6
*/
7
 
8
#include "audio.h"
9
#include "play.h"
10
#include "multi_curve.h"
11
#include <string.h>
12
 
13
void play::init () {
14
  sol = 0;
15
  x = 0.0f;
16
  dx = 0.0f;
17
  vol = 0.0f;
18
  pdx = pvol = 0;
19
  alloc ();
20
  pdx [0] = 0.0f; pdx [n_1] = 1.0f;
21
  pvol [0] = 0.0f; pvol [n_1] = 1.0f;
22
}
23
 
24
void play::alloc () {
25
  n = aout.samples_per_channel;
26
  n_1 = n - 1;
27
  da = 1.0f / n_1;
28
  if (pdx) delete [] pdx;
29
  if (pvol) delete [] pvol;
30
  pdx = new float [n];
31
  pvol = new float [n];
32
  int sz = n * sizeof (float);
33
  memset (pdx, 0, sz);
34
  memset (pvol, 0, sz);
35
}
36
 
37
void play::realloc () {
38
  alloc ();
39
  fill_pitch (dx);
40
  fill_volume (vol);
41
}
42
 
43
play::play (solver *w) {
44
  init ();
45
  set_wave (w);
46
}
47
 
48
play::play () {
49
  init ();
50
}
51
 
52
play::play (const play& p) {
53
  sol = p.sol;
54
  x = p.x;
55
  dx = p.dx;
56
  vol = p.vol;
57
  n = p.n;
58
  n_1 = p.n_1;
59
  da = p.da;
60
  pdx = new float [n];
61
  pvol = new float [n];
62
  for (int i = 0; i < n; ++i) {
63
    pdx [i] = p.pdx [i];
64
    pvol [i] = p.pvol [i];
65
  }
66
}
67
 
68
play::~play () {
69
  if (pdx) delete[] pdx;
70
  if (pvol) delete[] pvol;
71
}
72
 
73
void play::fill_pitch (float xd) {
74
  for (int i = 0; i < n; ++i) pdx[i] = xd;
75
  dx = xd;
76
}
77
 
78
void play::fill_volume (float v) {
79
  for (int i = 0; i < n; ++i) pvol[i] = v;
80
  vol = v;
81
}
82
 
83
void play::interpolate_buffer (float* buf, float s, float e) {
84
  float a = 0;
85
  float es = e - s;
86
  for (int i = 0; i < n; ++i) {
87
    buf[i] = s + a * es;
88
    a += da;
89
  }
90
}
91
 
92
void play::set_interpolated_volume (float v) {
93
  interpolate_buffer (pvol, vol, v);
94
  vol = v;
95
}
96
 
97
void play::set_interpolated_pitch (float xd) {
98
  interpolate_buffer (pdx, dx, xd);
99
  dx = xd;
100
}
101
 
102
void play::set_interpolated_pitch (float xd, int check) {
103
  if ((pdx[0] == pdx[n_1]) && (pdx[0] == xd)) return; // pitch is same
104
  else
105
    if (xd == dx)
106
      for (int i = 0; i < n; ++i) pdx[i] = dx; // same as last pitch so just fill ie no interpolation needed 
107
    else
108
      set_interpolated_pitch (xd);
109
}
110
 
111
void play::set_interpolated_volume (float v, int check) {
112
  if ((pvol[0]==pvol[n_1]) && (pvol[0]==v)) return; // volume is same
113
  else
114
    if (v == vol)
115
      for (int i = 0; i < n; ++i) pvol[i] = v; // same as last volume so just fill ie no interpolation needed
116
    else
117
      set_interpolated_volume (v);
118
}
119
 
120
void play::gen_wav_and_mix (float* wav, int n) {
121
  (*sol) (x, pdx, n, wav);
122
  if (mixer.active) {
123
    mixer.gen_mix (aout.mix, n);
124
    mixer.do_mix (wav, aout.mix, aout.mixa, n);
125
  }
126
}
127
 
128
void play::master (float* L, float* R, float* wav, int n, float* vola)  { // master with volume array
129
  gen_wav_and_mix (wav, n); // mix waveforms
130
  operator() (L, n, wav, vola); // multiply volumes
131
  memcpy (R, L, aout.samples_channel_size); // copy to R
132
}
133
 
134
void play::master (float* L, float* R, float* wav, int n, float vol)  { // master with volume
135
  gen_wav_and_mix (wav, n); // mix waveforms
136
  operator() (L, n, wav, vol); // apply volume
137
  memcpy (R, L, aout.samples_channel_size); // copy to R
138
}
139
 
2266 jag 140
 
141
void play::master (float* L, float* wav, int n, float vol)  { // master with volume
142
  gen_wav_and_mix (wav, n); // mix waveforms
143
  operator() (L, n, wav, vol); // apply volume
144
}
145
 
2267 jag 146
 
147
void play::master (float* L, float* wav, int n, float* vola)  { // master with volume array
148
  gen_wav_and_mix (wav, n); // mix waveforms
149
  operator() (L, n, wav, vola); // apply volume
150
}
151
 
2334 jag 152
void play::gen_wav_fm (solver& _sol, float& _x, float* wav, float* fm, int n) {
153
  // generate waveform samples with FM 
964 jag 154
  _sol (_x, pdx, n, fm, wav);
155
}
156
 
157
void play::gen_wav_am (float* out, float* wav, float* am, int n) { // apply AM to waveform samples
158
  for (int i = 0; i < n; ++i) out[i] = ((pvol[i] + am[i]) * wav[i]);
159
}
160
 
161
void play::gen_wav_fm_am_mix (float* out, int n) { // generate waveform samples, apply AM and FM and mix (if present)
162
  gen_wav_fm (*sol, x, aout.result, aout.fms, n);
163
  gen_wav_am (out, aout.result, aout.ams, n);
164
  if (mixer.active) {
165
    mixer.gen_fm (aout.result, n, aout.fms);
166
    gen_wav_am (aout.mix, aout.result, aout.ams, n);
167
    mixer.do_mix (out, aout.mix, aout.mixa, n);
168
  }
169
}
170
 
171
void play::gen_wav_mix (float* out, float* vola, int n) {
172
  gen_wav_and_mix (aout.result, n);
173
  operator() (out, n, aout.result, vola);
174
}
175
 
176
void play::gen_wav_mix (float* out, float vol, int n) {
177
  gen_wav_and_mix (aout.result, n);
178
  operator() (out, n, aout.result, vol);
179
}
180
 
1799 jag 181
void play::set_mix (multi_curve& crv, const std::string& nam) {
964 jag 182
  mixer.setup (crv, x, dx);
1799 jag 183
  mixer.name = nam;
964 jag 184
}