]> git.mxchange.org Git - flightgear.git/blob - Lib/src/slEnvelope.cxx
Merge FG_Lib as subdirectory
[flightgear.git] / Lib / src / slEnvelope.cxx
1
2 #include "sl.h"
3
4 float slEnvelope::getValue ( float _time )
5 {
6   float delta ;
7   int   step = getStepDelta ( &_time, &delta ) ;
8
9   return delta * (_time - time[step]) + value[step] ;
10 }
11
12
13
14 int slEnvelope::getStepDelta ( float *_time, float *delta )
15 {
16   float tt ;
17
18   if ( replay_mode == SL_SAMPLE_LOOP )
19   {
20     tt = floor ( *_time / time [ nsteps-1 ] ) ; 
21     *_time -= tt * time [ nsteps-1 ] ;
22   }
23
24   tt = *_time ;
25
26   if ( tt <= time[    0   ] ) { *delta = 0.0f ; return 0 ; }
27   if ( tt >= time[nsteps-1] ) { *delta = 0.0f ; return nsteps-1 ; }
28
29   for ( int i = 1 ; i <= nsteps-1 ; i++ )
30     if ( tt <= time[i] )
31     {
32       float t1 = time[i-1] ; float v1 = value[i-1] ;
33       float t2 = time[ i ] ; float v2 = value[ i ] ;
34
35       if ( t1 == t2 )
36       {
37         *delta = 0.0f ;
38         return i ;
39       }
40
41       *delta = (v2-v1) / (t2-t1) ;
42       return i-1 ;
43     }
44
45   *delta = 0.0f ;
46   return nsteps - 1 ;
47 }
48
49
50 void slEnvelope::applyToPitch  ( Uchar *dst, slSamplePlayer *src,
51                                  int nframes, int start, int next_env )
52 {
53   float  delta ;
54   float  _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
55   int     step = getStepDelta ( &_time, &delta ) ;
56   float _value = delta * (_time - time[step]) + value[step] ;
57
58   delta /= (float) slScheduler::getCurrent() -> getRate () ;
59
60   unsigned char tmp [ 512 ] ;
61   float  pos = 0 ;
62   float npos = 0 ;
63   unsigned char last = 0x80 ;
64
65   while ( nframes-- )
66   {
67     npos += _value ;
68     _value += delta ;
69
70     int offset = (int) ( npos - pos ) ;
71
72     if ( offset > 512 )
73       offset = 512 ;
74
75     if ( offset < 1 )
76       *(dst++) = last ;
77     else
78     {
79       pos += offset ;
80
81       src -> read ( offset, tmp, next_env ) ;
82
83       *(dst++) = last = tmp [ offset-1 ] ; 
84     }
85   }
86 }
87
88
89 void slEnvelope::applyToInvPitch  ( Uchar *dst, slSamplePlayer *src,
90                                     int nframes, int start, int next_env )
91 {
92   float  delta ;
93   float  _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
94   int     step = getStepDelta ( &_time, &delta ) ;
95   float _value = delta * (_time - time[step]) + value[step] ;
96
97   delta /= (float) slScheduler::getCurrent() -> getRate () ;
98
99   unsigned char tmp [ 512 ] ;
100   float  pos = 0 ;
101   float npos = 0 ;
102   unsigned char last = 0x80 ;
103
104   while ( nframes-- )
105   {
106     npos += 1.0 / _value ;
107     _value += delta ;
108
109     int offset = (int) ( npos - pos ) ;
110
111     if ( offset > 512 )
112       offset = 512 ;
113
114     if ( offset < 1 )
115       *(dst++) = last ;
116     else
117     {
118       pos += offset ;
119
120       src -> read ( offset, tmp, next_env ) ;
121
122       *(dst++) = last = tmp [ offset-1 ] ; 
123     }
124   }
125 }
126
127 void slEnvelope::applyToVolume ( Uchar *dst, Uchar *src,
128                                  int nframes, int start )
129 {
130   float  delta ;
131   float  _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
132   int     step = getStepDelta ( &_time, &delta ) ;
133   float _value = delta * (_time - time[step]) + value[step] ;
134
135   delta /= (float) slScheduler::getCurrent() -> getRate () ;
136
137   while ( nframes-- )
138   {
139     register int res = (int)( (float)((int)*(src++)-0x80) * _value ) + 0x80 ;
140
141     _value += delta ;
142
143     *(dst++) = ( res > 255 ) ? 255 : ( res < 0 ) ? 0 : res ;
144   }
145 }
146
147 void slEnvelope::applyToInvVolume ( Uchar *dst, Uchar *src,
148                                     int nframes, int start )
149 {
150   float  delta ;
151   float  _time = slScheduler::getCurrent() -> getElapsedTime ( start ) ;
152   int     step = getStepDelta ( &_time, &delta ) ;
153   float _value = delta * (_time - time[step]) + value[step] ;
154
155   delta /= (float) slScheduler::getCurrent() -> getRate () ;
156
157   delta = - delta ;
158   _value = 1.0 - _value ;
159
160   while ( nframes-- )
161   {
162     register int res = (int)( (float)((int)*(src++)-0x80) * _value ) + 0x80 ;
163
164     _value += delta ;
165
166     *(dst++) = ( res > 255 ) ? 255 : ( res < 0 ) ? 0 : res ;
167   }
168 }
169
170