~ubuntu-branches/ubuntu/intrepid/aeolus/intrepid

« back to all changes in this revision

Viewing changes to division.cc

  • Committer: Bazaar Package Importer
  • Author(s): Free Ekanayaka
  • Date: 2007-05-14 22:18:54 UTC
  • Revision ID: james.westby@ubuntu.com-20070514221854-274rj6fqs5tegu7q
Tags: upstream-0.6.6+2
ImportĀ upstreamĀ versionĀ 0.6.6+2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
    Copyright (C) 2005 Fons Adriaensen <fons.adriaensen@skynet.be>
 
3
    
 
4
    This program is free software; you can redistribute it and/or modify
 
5
    it under the terms of the GNU General Public License as published by
 
6
    the Free Software Foundation; either version 2 of the License, or
 
7
    (at your option) any later version.
 
8
 
 
9
    This program is distributed in the hope that it will be useful,
 
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
    GNU General Public License for more details.
 
13
 
 
14
    You should have received a copy of the GNU General Public License
 
15
    along with this program; if not, write to the Free Software
 
16
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
17
*/
 
18
 
 
19
 
 
20
#include <math.h>
 
21
#include <string.h>
 
22
#include "division.h"
 
23
 
 
24
 
 
25
Division::Division (Asection *asect, float fsam) :
 
26
    _asect (asect),
 
27
    _nrank (0),
 
28
    _dmask (0),
 
29
    _trem (0),
 
30
    _fsam (fsam),
 
31
    _swel (1.0f),
 
32
    _gain (0.1f),
 
33
    _w (0.0f),
 
34
    _c (1.0f),
 
35
    _s (0.0f),
 
36
    _m (0.0f)
 
37
{
 
38
    for (int i = 0; i < NRANKS; i++) _ranks [i] = 0;    
 
39
}
 
40
 
 
41
 
 
42
Division::~Division (void)
 
43
{
 
44
}
 
45
 
 
46
 
 
47
void Division::process (void) 
 
48
{
 
49
    int    i;
 
50
    float  d, g, t;
 
51
    float  *p, *q; 
 
52
 
 
53
    memset (_buff, 0, NCHANN * PERIOD * sizeof (float));
 
54
    for (i = 0; i < _nrank; i++) _ranks [i]->play (1);
 
55
 
 
56
    g = _swel;
 
57
    if (_trem)
 
58
    {
 
59
        _s += _w * _c;
 
60
        _c -= _w * _s;
 
61
        t = sqrtf (_c * _c + _s * _s);
 
62
        _c /= t;
 
63
        _s /= t;
 
64
        if ((_trem == 2) && (fabsf (_s) < 0.05f))
 
65
        {
 
66
            _trem = 0;
 
67
            _c = 1;
 
68
            _s = 0;
 
69
        }
 
70
        g *= 1.0f + _m * _s;
 
71
    }
 
72
 
 
73
    t = 1.05 * _gain;
 
74
    if (g > t) g = t;
 
75
    t = 0.95 * _gain;
 
76
    if (g < t) g = t;
 
77
 
 
78
    d = (g - _gain) / PERIOD;    
 
79
    g = _gain;
 
80
    p = _buff;
 
81
    q = _asect->get_wptr ();
 
82
 
 
83
    for (i = 0; i < PERIOD; i++)
 
84
    {
 
85
        g += d;
 
86
        q [0 * PERIOD * MIXLEN] += p [0 * PERIOD] * g;
 
87
        q [1 * PERIOD * MIXLEN] += p [1 * PERIOD] * g;
 
88
        q [2 * PERIOD * MIXLEN] += p [2 * PERIOD] * g;
 
89
        q [3 * PERIOD * MIXLEN] += p [3 * PERIOD] * g;
 
90
        p++;
 
91
        q++;
 
92
    }
 
93
    _gain = g;
 
94
}
 
95
 
 
96
 
 
97
void Division::set_rank (int ind, Rankwave *W, int pan, int del)
 
98
{
 
99
    Rankwave *C;
 
100
 
 
101
    C = _ranks [ind];
 
102
    if (C) { W->_nmask = C->_cmask; delete C; }
 
103
    else W->_nmask = 0;
 
104
    W->_cmask = 0;
 
105
    _ranks [ind] = W;
 
106
    del = (int)(1e-3f * del * _fsam / PERIOD);
 
107
    if (del > 31) del = 31;
 
108
    W->set_param (_buff, del, pan);
 
109
    if (_nrank < ++ind) _nrank = ind;
 
110
}
 
111
 
 
112
 
 
113
void Division::update (int note, int mask)
 
114
{
 
115
    int             r;
 
116
    Rankwave       *W;
 
117
 
 
118
    for (r = 0; r < _nrank; r++)
 
119
    {
 
120
        W = _ranks [r];
 
121
        if (W->_cmask & 127)
 
122
        {     
 
123
            if (mask & W->_cmask) W->note_on (note + 36);
 
124
            else                  W->note_off (note + 36);
 
125
        }
 
126
    }
 
127
}
 
128
 
 
129
 
 
130
void Division::update (unsigned char *keys)
 
131
{
 
132
    int            d, r, m, n, n0, n1;
 
133
    unsigned char  *k;
 
134
    Rankwave       *W;
 
135
 
 
136
    for (r = 0; r < _nrank; r++)
 
137
    {
 
138
        W = _ranks [r];
 
139
        if ((W->_cmask ^ W->_nmask) & 127)
 
140
        {     
 
141
            m = W->_nmask & 127;               
 
142
            if (m)
 
143
            {            
 
144
                n0 = W->n0 ();
 
145
                n1 = W->n1 ();
 
146
                k = keys;
 
147
                d = n0 - 36;
 
148
                if (d > 0) k += d;
 
149
                for (n = n0; n <= n1; n++)
 
150
                {
 
151
                    if (*k++ & m) W->note_on (n);
 
152
                    else          W->note_off (n);
 
153
                }
 
154
            }
 
155
            else W->all_off ();
 
156
        }
 
157
        W->_cmask = W->_nmask;
 
158
    }
 
159
}
 
160
 
 
161
 
 
162
void Division::set_div_mask (int bits)
 
163
{
 
164
    int       r;
 
165
    Rankwave *W;
 
166
 
 
167
    bits &= 127;
 
168
    _dmask |= bits;
 
169
    for (r = 0; r < _nrank; r++)
 
170
    {
 
171
        W = _ranks [r];
 
172
        if (W->_nmask & 128) W->_nmask |= bits;
 
173
    } 
 
174
}
 
175
 
 
176
 
 
177
void Division::clr_div_mask (int bits)
 
178
{
 
179
    int       r;
 
180
    Rankwave *W;
 
181
 
 
182
    bits &= 127;
 
183
    _dmask &= ~bits;
 
184
    for (r = 0; r < _nrank; r++)
 
185
    {
 
186
        W = _ranks [r];
 
187
        if (W->_nmask & 128) W->_nmask &= ~bits;
 
188
    } 
 
189
}
 
190
 
 
191
 
 
192
void Division::set_rank_mask (int ind, int bits)
 
193
{
 
194
    Rankwave *W = _ranks [ind];
 
195
 
 
196
    if (bits == 128) bits |= _dmask;
 
197
    W->_nmask |= bits;
 
198
}
 
199
 
 
200
 
 
201
void Division::clr_rank_mask (int ind, int bits)
 
202
{
 
203
    Rankwave *W = _ranks [ind];
 
204
 
 
205
    if (bits == 128) bits |= _dmask;
 
206
    W->_nmask &= ~bits;
 
207
}