-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathSoundModelPoly.cpp
182 lines (145 loc) · 4.44 KB
/
SoundModelPoly.cpp
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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include "SoundModelMono.h"
#include "SoundModelPoly.h"
#include <cstring>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace SYNTHPI;
using namespace audio;
SoundModelPoly::SoundModelPoly(const int poly, const int samplerate)
{
VoiceNo=poly;
for (int i = 0; i < VoiceNo; i++) {
soundModelList.push_back(new SoundModelMono);
}
lastSoundModel.resize(VoiceNo);
midiNoteList.resize(VoiceNo);
}
std::vector<sample_t> SoundModelPoly::getSamples(int nSamples){
std::vector<sample_t> temp(nSamples);
// Clear object polybuffer and set the size
polybuffer.clear();
polybuffer.resize(nSamples);
for(unsigned int j = 0; j<soundModelList.size(); j++) {
temp=soundModelList[j]->getSamples(nSamples);
for (unsigned int i = 0; i < nSamples; i++) {
polybuffer[i] += temp[i];
}
}
// Dezipper the audio output by changing the output gain progressively along the outbut buffer length,
// does the same for the filter cutoff and Q factor
float gain_step = (target_vol-master_vol)/nSamples;
float Fc_step = (target_Fc-Fc)/nSamples;
float Q_step = (target_Q-Q)/nSamples;
if (slope==true){
for(unsigned int i = 0; i < nSamples; i++) {
auto coeffs12=filter12.calculate_coeffs(Q,Fc,samplerate);
auto coeffs24=filter24.calculate_coeffs(Q,Fc,samplerate);
polybuffer[i] = filter24.process(filter12.process(polybuffer[i])) * master_vol;
master_vol += gain_step;
Fc+=Fc_step;
Q+=Q_step;
}
}
else{
for(unsigned int i = 0; i < nSamples; i++) {
auto coeffs12=filter12.calculate_coeffs(Q,Fc,samplerate);
polybuffer[i] = filter12.process(polybuffer[i]) * master_vol;
master_vol += gain_step;
Fc+=Fc_step;
Q+=Q_step;
}
}
master_vol = target_vol;
Fc=target_Fc;
Q=target_Q;
return polybuffer;
}
void SoundModelPoly::setNoteOn(int midinote) { //add note priority here
int active=0;
for(unsigned int i = 0; i < soundModelList.size(); i++)
if (soundModelList[i]->isPlaying()){
active++;
}
if (active==VoiceNo){ //if all voices are playing turn the oldest voice off
setNoteOff(midiNoteList[lastSoundModel[0]]);
//soundModelList[]->setNoteOn(midinote);
//midiNoteList[lastSoundModel[0]]=midinote;
//return;
}
for(unsigned int i = 0; i < soundModelList.size(); i++){
if(soundModelList[i]->isPlaying()==false) {
soundModelList[i]->setNoteOn(midinote);
midiNoteList[i]=midinote;
lastSoundModel.push_back(i);
return;
}
}
return;
}
void SoundModelPoly::setNoteOff(int midinote) {
for(unsigned int i = 0; i < midiNoteList.size(); i++){
if (midiNoteList[i]==midinote){
soundModelList[i]->setNoteOff(midinote);
std::vector<int>::iterator it = std::find(lastSoundModel.begin(), lastSoundModel.end(), i);
position = std::distance(lastSoundModel.begin(), it);
lastSoundModel.erase(lastSoundModel.begin()+position);
return;
}
}
//return;
}
bool SoundModelPoly::isPlaying() {
for(unsigned int i = 0; i < soundModelList.size(); i++) {
if(soundModelList[i]->isPlaying()) {
return true;
}
}
return false;
}
void SoundModelPoly::updateVolume(unsigned int parameter) {
target_vol=0.4*(static_cast<float>(parameter)/127.0);
}
void SoundModelPoly::updateWavemix(unsigned int parameter){
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateWavemix(parameter);
}
}
void SoundModelPoly::updateBank(int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateBank(parameter);
}
}
void SoundModelPoly::updateAttack(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateAttack(parameter);
}
}
void SoundModelPoly::updateDecay(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateDecay(parameter);
}
}
void SoundModelPoly::updateSustain(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateSustain(parameter);
}
}
void SoundModelPoly::updateRelease(unsigned int parameter) {
for (unsigned int i=0; i<soundModelList.size();i++){
soundModelList[i]->updateRelease(parameter);
}
}
void SoundModelPoly::updateCutoff(unsigned int parameter){
target_Fc=80.0+powf(18000.0,(static_cast<float>(parameter)/127.0));
}
void SoundModelPoly::updateRes(unsigned int parameter){
target_Q=0.707+5.0*(static_cast<float>(parameter)/127.0);
}
void SoundModelPoly::updateSlope(unsigned int parameter){
if (parameter > 63){
slope = true;
}else{
slope=false;
}
}