/[svn]/linuxsampler/trunk/src/eg_vca.cpp
ViewVC logotype

Annotation of /linuxsampler/trunk/src/eg_vca.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 30 - (hide annotations) (download)
Sun Jan 11 16:43:54 2004 UTC (20 years, 3 months ago) by schoenebeck
File size: 5044 byte(s)
* implemented amplitude envelope generator
* src/voice.cpp: some .gig instruments still sounded detuned, I hope
  finally to have this fixed now

1 schoenebeck 30 /***************************************************************************
2     * *
3     * LinuxSampler - modular, streaming capable sampler *
4     * *
5     * Copyright (C) 2003 by Benno Senoner and Christian Schoenebeck *
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 "eg_vca.h"
24    
25     EG_VCA::EG_VCA() {
26     Stage = stage_end;
27     Level = 0.0;
28     }
29    
30     /**
31     * Will be called by the voice for every audio fragment to let the EG
32     * queue it's modulation changes for the current audio fragment.
33     */
34     void EG_VCA::ProcessFragment() {
35     if (Stage == stage_sustain) return; // nothing to do
36    
37     for (int to_process_total = ModulationSystem::GetFragmentSize(); to_process_total;) {
38     int iSample = 0;
39     switch (Stage) {
40     case stage_attack: {
41     int to_process = Min(to_process_total, AttackStepsLeft);
42     int process_end = iSample + to_process;
43     AttackStepsLeft -= to_process;
44     to_process_total -= to_process;
45     for (; iSample < process_end; iSample++) {
46     Level += AttackCoeff;
47     ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample] *= Level;
48     }
49     if (!AttackStepsLeft) {
50     Stage = (ReleaseSignalReceived) ? stage_release : stage_sustain;
51     }
52     break;
53     }
54     case stage_sustain: {
55     return;
56     }
57     case stage_release: {
58     int process_end = iSample + to_process_total;
59     for (; iSample < process_end; iSample++) {
60     Level -= Level * ReleaseCoeff;
61     ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample] *= Level;
62     }
63     if (Level <= EG_ENVELOPE_LIMIT) Stage = stage_end;
64     return;
65     }
66     case stage_end: {
67     int process_end = iSample + to_process_total;
68     for (; iSample < process_end; iSample++) {
69     ModulationSystem::pDestinationParameter[ModulationSystem::destination_vca][iSample] *= Level;
70     }
71     return;
72     }
73     }
74     }
75     }
76    
77     /**
78     * Will be called by the voice when the key / voice was triggered.
79     *
80     * @param PreAttack - Preattack value for the envelope (0 - 1000 permille)
81     * @param AttackTime - Attack time for the envelope (0.000 - 60.000s)
82     * @param ReleaseTIme - Release time for the envelope (0.000 - 60.000s)
83     */
84     void EG_VCA::Trigger(uint PreAttack, double AttackTime, double ReleaseTime) {
85     ReleaseSignalReceived = false;
86     Stage = stage_attack;
87    
88     // calculate attack stage parameters
89     AttackStepsLeft = (long) (AttackTime * ModulationSystem::GetSampleRate());
90     if (AttackStepsLeft) {
91     Level = PreAttack;
92     AttackCoeff = (1.0 - PreAttack) / AttackStepsLeft;
93     }
94     else {
95     Level = 1.0;
96     AttackCoeff = 0.0;
97     }
98    
99     // calcuate release stage parameters
100     if (ReleaseTime < EG_MIN_RELEASE_TIME) ReleaseTime = EG_MIN_RELEASE_TIME; // to avoid click sounds at the end of the sample playback
101     ReleaseStepsLeft = (long) (ReleaseTime * ModulationSystem::GetSampleRate());
102     ReleaseCoeff = 1.0 - exp(log(EG_ENVELOPE_LIMIT) / (double) ReleaseStepsLeft);
103    
104     dmsg(4,("AttackLength=%d, ReleaseLength=%d",AttackStepsLeft,ReleaseStepsLeft));
105     }
106    
107     /**
108     * Will be called by the voice when the key / voice was released.
109     */
110     void EG_VCA::Release() {
111     // postpone release stage until sustain stage reached
112     if (Stage == stage_sustain) Stage = stage_release;
113     ReleaseSignalReceived = true;
114     }

  ViewVC Help
Powered by ViewVC