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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2114 - (show annotations) (download)
Tue Aug 10 12:05:19 2010 UTC (13 years, 8 months ago) by persson
File size: 4504 byte(s)
* sfz engine: improved support for exclusive groups (group, off_by and
  off_mode)
* minor valgrind fixes

1 /***************************************************************************
2 * *
3 * LinuxSampler - modular, streaming capable sampler *
4 * *
5 * Copyright (C) 2010 Andreas Persson *
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., 51 Franklin St, Fifth Floor, Boston, *
20 * MA 02110-1301 USA *
21 ***************************************************************************/
22
23 #include "EG.h"
24
25 #include "../../common/global_private.h"
26
27 namespace LinuxSampler { namespace sfz {
28
29 // Modeled after output from Rapture Demo 1.0, which means the
30 // stages are using a pow function and the "curve" parameter of
31 // the stage is ignored. The "shape" parameter decides the slope
32 // of the stage, a value of 1.0 or 0.0 means linear shape. The
33 // length of the stages are dependent on the velocity.
34
35 // TODO: add support for loops
36 // TODO: optimization: use segment_lin for linear stages
37 // TODO: support cancel_release events?
38
39 void EG::update(event_t Event, uint SampleRate) {
40 if (atEnd(Event)) return;
41
42 // ignore duplicated release events
43 if (Event == event_release) {
44 if (GotRelease) return;
45 GotRelease = true;
46 }
47
48 if (Event == event_stage_end || Event == event_release) {
49 if (Stage == eg->node.size() - 1) {
50 enterFadeOutStage();
51 } else if (Stage == eg->sustain && Stage != 0 &&
52 Event != event_release) {
53 enterSustainStage();
54 } else {
55 if (Event == event_release) {
56 Stage = eg->sustain;
57 } else {
58 Level = eg->node[Stage].level;
59 }
60
61 Stage++;
62
63 float shape = eg->node[Stage].shape;
64 if (shape < 0.000001) shape = 1;
65
66 float xd = eg->node[Stage].time * SampleRate * TimeCoeff;
67 float yd = eg->node[Stage].level - Level;
68
69 if (eg->node[Stage - 1].shape > 0.999999 ||
70 eg->node[Stage - 1].shape < 0.000001) {
71 Exp = 1 / shape;
72 Offset = Level;
73 X = 0;
74 XDelta = 1 / xd;
75 Coeff = yd;
76 } else {
77 Exp = shape;
78 Offset = eg->node[Stage].level;
79 X = 1;
80 XDelta = -1 / xd;
81 Coeff = -yd;
82 }
83 Segment = segment_pow;
84 StepsLeft = int(xd);
85 }
86 }
87 }
88
89 void EG::trigger(::sfz::EG& eg, uint SampleRate, uint8_t Velocity) {
90 Stage = 0;
91 this->eg = &eg;
92 TimeCoeff = exp(0.0054578518 * Velocity); // pow(2, Velcocity / 127)
93 GotRelease = false;
94
95 enterFirstStage();
96 update(event_stage_end, SampleRate);
97 }
98
99 void EG::enterSustainStage() {
100 Segment = segment_lin;
101 Coeff = 0.0f; // don't change the envelope level in this stage
102 const int intMax = (unsigned int) -1 >> 1;
103 StepsLeft = intMax; // we use the highest value possible (we refresh StepsLeft in update() in case)
104 Level = eg->node[Stage].level;
105 }
106 }} // namespace LinuxSampler::sfz

  ViewVC Help
Powered by ViewVC