/[svn]/linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp
ViewVC logotype

Contents of /linuxsampler/trunk/src/engines/sfz/SfzSignalUnitRack.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2218 - (show annotations) (download)
Thu Jul 28 08:05:57 2011 UTC (12 years, 8 months ago) by iliev
File size: 6387 byte(s)
* sfz engine: use the newly introduced signal units model

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2011 Grigor Iliev *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the Free Software *
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, *
20 * MA 02111-1307 USA *
21 ***************************************************************************/
22
23 #include "SfzSignalUnitRack.h"
24 #include "Voice.h"
25
26 namespace LinuxSampler { namespace sfz {
27
28 SfzSignalUnit::SfzSignalUnit(SfzSignalUnitRack* rack): SignalUnit(rack), pVoice(rack->pVoice) {
29
30 }
31
32 double SfzSignalUnit::GetSampleRate() {
33 return pVoice->GetSampleRate() / CONFIG_DEFAULT_SUBFRAGMENT_SIZE;
34 }
35
36
37 void EGv1Unit::Trigger() {
38 ::sfz::Region* const pRegion = pVoice->pRegion;
39 // the length of the decay and release curves are dependent on the velocity
40 const double velrelease = 1 / pVoice->GetVelocityRelease(pVoice->MIDIVelocity);
41
42 EG.trigger(uint(pRegion->ampeg_start * 10),
43 std::max(0.0, pRegion->ampeg_attack + pRegion->ampeg_vel2attack * velrelease),
44 std::max(0.0, pRegion->ampeg_hold + pRegion->ampeg_vel2hold * velrelease),
45 std::max(0.0, pRegion->ampeg_decay + pRegion->ampeg_vel2decay * velrelease),
46 uint(std::min(std::max(0.0, 10 * (pRegion->ampeg_sustain + pRegion->ampeg_vel2sustain * velrelease)), 1000.0)),
47 std::max(0.0, pRegion->ampeg_release + pRegion->ampeg_vel2release * velrelease),
48 GetSampleRate());
49 }
50
51 void EGv2Unit::Trigger() {
52 EG.trigger(*pEGInfo, GetSampleRate(), pVoice->MIDIVelocity);
53 }
54
55
56 EndpointUnit::EndpointUnit(SfzSignalUnitRack* rack): EndpointSignalUnit(rack) {
57
58 }
59
60 SfzSignalUnitRack* const EndpointUnit::GetRack() {
61 return static_cast<SfzSignalUnitRack* const>(pRack);
62 }
63
64 void EndpointUnit::Trigger() {
65
66 }
67
68 bool EndpointUnit::Active() {
69 if (GetRack()->suVolEG.Active()) return true;
70
71 bool b = false;
72 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
73 if (GetRack()->volEGs[i]->Active()) { b = true; break; }
74 }
75
76 return b;
77 }
78
79 float EndpointUnit::GetVolume() {
80 float vol = GetRack()->suVolEG.Active() ? GetRack()->suVolEG.GetLevel() : 0;
81
82 for (int i = 0; i < GetRack()->volEGs.size(); i++) {
83 EGv2Unit* eg = GetRack()->volEGs[i];
84 if (!eg->Active()) continue;
85 vol += eg->GetLevel() * (eg->pEGInfo->amplitude / 100.0f);
86 }
87
88 return vol;
89 }
90
91 float EndpointUnit::GetFilterCutoff() {
92 return 1;
93 }
94
95 float EndpointUnit::GetPitch() {
96 return 1;
97 }
98
99 float EndpointUnit::GetResonance() {
100 return 1;
101 }
102
103
104 SfzSignalUnitRack::SfzSignalUnitRack(Voice* voice)
105 : SignalUnitRack(MaxUnitCount), pVoice(voice), suEndpoint(this), suVolEG(this),
106 EGs(maxEgCount), volEGs(maxEgCount), pitchEGs(maxEgCount)
107 {
108 suEndpoint.pVoice = suVolEG.pVoice = voice;
109
110 for (int i = 0; i < EGs.capacity(); i++) {
111 EGs[i] = new EGv2Unit(this);
112 EGs[i]->pVoice = voice;
113 }
114 }
115
116 SfzSignalUnitRack::~SfzSignalUnitRack() {
117 for (int i = 0; i < maxEgCount; i++) {
118 delete EGs[i]; EGs[i] = NULL;
119 }
120 }
121
122 void SfzSignalUnitRack::Trigger() {
123 EGs.clear();
124 volEGs.clear();
125 pitchEGs.clear();
126
127 ::sfz::Region* const pRegion = pVoice->pRegion;
128
129 for (int i = 0 ; i < pRegion->eg.size() ; i++) {
130 if (pRegion->eg[i].node.size() == 0) continue;
131
132 if(EGs.size() < EGs.capacity()) {
133 EGv2Unit eg(this);
134 eg.pEGInfo = &(pRegion->eg[i]);
135 EGs.increment()->Copy(eg);
136 } else { std::cerr << "Maximum number of EGs reached!" << std::endl; break; }
137
138
139
140 if (pRegion->eg[i].amplitude > 0) {
141 if(volEGs.size() < volEGs.capacity()) volEGs.add(EGs[EGs.size() - 1]);
142 else std::cerr << "Maximum number of EGs reached!" << std::endl;
143 }
144 }
145
146 if (pRegion->ampeg_sustain == -1) {
147 if (volEGs.size() > 0) pRegion->ampeg_sustain = 0;
148 else pRegion->ampeg_sustain = 100;
149 }
150
151 Units.clear();
152
153 Units.add(&suVolEG);
154
155 for (int i = 0 ; i < EGs.size() ; i++) {
156 Units.add(EGs[i]);
157 }
158
159 Units.add(&suEndpoint);
160
161 SignalUnitRack::Trigger();
162 }
163
164 EndpointSignalUnit* SfzSignalUnitRack::GetEndpointUnit() {
165 return &suEndpoint;
166 }
167
168 void SfzSignalUnitRack::EnterFadeOutStage() {
169 suVolEG.EG.enterFadeOutStage();
170
171 for (int i = 0; i < volEGs.size(); i++) {
172 volEGs[i]->EG.enterFadeOutStage();
173 }
174 }
175
176 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC