~ubuntu-branches/ubuntu/breezy/kdemultimedia/breezy

« back to all changes in this revision

Viewing changes to arts/modules/synth/synth_pitch_shift_impl.cc

  • Committer: Bazaar Package Importer
  • Author(s): Jonathan Riddell
  • Date: 2005-03-24 04:48:58 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 sarge)
  • Revision ID: james.westby@ubuntu.com-20050324044858-8ff88o9jxej6ii3d
Tags: 4:3.4.0-0ubuntu3
Add kubuntu_02_hide_arts_menu_entries.diff to hide artsbuilder and artscontrol k-menu entries

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 
 
3
    Copyright (C) 2000 Jeff Tranter
 
4
                       tranter@pobox.com
 
5
 
 
6
              (C) 1999 Stefan Westerfeld
 
7
                       stefan@space.twc.de
 
8
 
 
9
    This program is free software; you can redistribute it and/or modify
 
10
    it under the terms of the GNU General Public License as published by
 
11
    the Free Software Foundation; either version 2 of the License, or
 
12
    (at your option) any later version.
 
13
 
 
14
    This program is distributed in the hope that it will be useful,
 
15
    but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
    GNU General Public License for more details.
 
18
 
 
19
    You should have received a copy of the GNU General Public License
 
20
    along with this program; if not, write to the Free Software
 
21
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
22
 
 
23
    */
 
24
 
 
25
#include <math.h>
 
26
#include "artsmodulessynth.h"
 
27
#include "stdsynthmodule.h"
 
28
 
 
29
using namespace Arts;
 
30
 
 
31
class Synth_PITCH_SHIFT_impl : virtual public Synth_PITCH_SHIFT_skel,
 
32
                                                           virtual public StdSynthModule
 
33
{
 
34
protected:
 
35
        float _speed, _frequency;
 
36
 
 
37
        enum { MAXDELAY = 44100 };
 
38
        float *dbuffer;
 
39
        float lfopos, b1pos, b2pos, b1inc, b2inc;
 
40
        bool b1reset, b2reset, initialized;
 
41
        int dbpos;
 
42
 
 
43
public:
 
44
        Synth_PITCH_SHIFT_impl() : _speed(1.0), _frequency(5.0)
 
45
        {
 
46
        }
 
47
 
 
48
        float speed() { return _speed; }
 
49
        void speed(float newSpeed) { _speed = newSpeed; }
 
50
 
 
51
        float frequency() { return _frequency; }
 
52
        void frequency(float newFrequency) { _frequency = newFrequency; }
 
53
 
 
54
 
 
55
        void streamInit()
 
56
        {
 
57
                dbuffer = new float[MAXDELAY];
 
58
                for (dbpos=0; dbpos<MAXDELAY; dbpos++)
 
59
                        dbuffer[dbpos] = 0;
 
60
 
 
61
                dbpos = 0;
 
62
                initialized = false;
 
63
                lfopos = 0;
 
64
        }
 
65
        void streamEnd()
 
66
        {
 
67
                delete[] dbuffer;
 
68
        }
 
69
 
 
70
        void calculateBlock(unsigned long samples)
 
71
        {
 
72
                float *outend = outvalue + samples;
 
73
                float fsr = (float)samplingRate;
 
74
                float pi2 = 2*M_PI;
 
75
                float lfo, b1value, b2value;
 
76
                float lfoposinc = _frequency / fsr;
 
77
 
 
78
                if (!initialized)
 
79
                {
 
80
                        if (_speed <= 1.0) {
 
81
                                b1pos = b2pos = 0.0;
 
82
                                b1inc = b2inc = 1.0 - _speed;
 
83
                        } else {
 
84
                                /* not yet sure what would be a nice initialization here? */
 
85
                                b1pos = b2pos = 0.0;
 
86
                                b1inc = b2inc = 0.0;
 
87
                        }
 
88
                        initialized = true;
 
89
                }
 
90
 
 
91
                while (outvalue < outend)
 
92
                {
 
93
                        /*
 
94
                         * fill delay buffer with the input signal
 
95
                         */
 
96
                        dbuffer[dbpos] = *invalue++;
 
97
 
 
98
                        lfopos += lfoposinc;
 
99
                        lfopos -= floor(lfopos);
 
100
 
 
101
                        if (lfopos < 0.25) {
 
102
                                b1reset = b2reset = false;
 
103
                        }
 
104
 
 
105
                        /*
 
106
                         * _speed < 1.0 (downpitching)
 
107
                         *
 
108
                         *  start with current sample and increase delay slowly
 
109
                         *
 
110
                         * _speed > 1.0 (uppitching)
 
111
                         *
 
112
                         *  start with a sample from long ago and slowly decrease delay
 
113
                         */
 
114
                        if (!b1reset && lfopos > 0.25) {
 
115
                                if (_speed <= 1.0) {
 
116
                                        b1pos = 0;
 
117
                                        b1inc = 1 - _speed;
 
118
                                } else {
 
119
                                        b1inc = 1 - _speed;
 
120
                                        b1pos = 10 + ((-b1inc) * (1 / lfoposinc));
 
121
                                        /* 10+ are not strictly necessary */
 
122
                                }
 
123
                                b1reset = true;
 
124
                        }
 
125
 
 
126
                        if (!b2reset && lfopos > 0.75) {
 
127
                                if (_speed <= 1.0) {
 
128
                                        b2pos = 0;
 
129
                                        b2inc = 1 - _speed;
 
130
                                } else{
 
131
                                        b2inc = 1 - _speed;
 
132
                                        b2pos = 10 + ((-b2inc) * (1/lfoposinc));
 
133
                                        /* 10+ are not strictly necessary */
 
134
                                }
 
135
                                b2reset = true;
 
136
                        }
 
137
 
 
138
                        b1pos += b1inc;
 
139
                        b2pos += b2inc;
 
140
 
 
141
                        int position, position1;
 
142
                        double error,int_pos;
 
143
 
 
144
                        /*
 
145
                         * Interpolate value from buffer position 1
 
146
                         */
 
147
                        error = modf(b1pos, &int_pos);
 
148
        
 
149
                        position = dbpos - (int)int_pos;
 
150
                        if (position < 0)
 
151
                                position += MAXDELAY;
 
152
                        position1 = position - 1;
 
153
                        if (position1 < 0)
 
154
                                position1 += MAXDELAY;
 
155
 
 
156
                        b1value = dbuffer[position] * (1 - error) + dbuffer[position1] * error;
 
157
 
 
158
                        /*
 
159
                         * Interpolate value from buffer position 2
 
160
                         */
 
161
                        error = modf(b2pos,&int_pos);
 
162
        
 
163
                        position = dbpos - (int)int_pos;
 
164
                        if (position < 0)
 
165
                                position += MAXDELAY;
 
166
                        position1 = position-1;
 
167
                        if ( position1 < 0)
 
168
                                position1 += MAXDELAY;
 
169
 
 
170
                        b2value = dbuffer[position]*(1-error) + dbuffer[position1]*error;
 
171
 
 
172
                        /*
 
173
                         * Calculate output signal from these two buffers
 
174
                         */
 
175
 
 
176
                        lfo = (sin(pi2 * lfopos) + 1) / 2;
 
177
 
 
178
                        /*             position    sin   lfo variable
 
179
                         *------------------------------------------------------------------
 
180
                         * lfo value:    0.25       1         1        => buffer 2 is used
 
181
                         *               0.75      -1         0        => buffer 1 is used
 
182
                         */
 
183
                        
 
184
                        *outvalue++ = b1value * (1.0 - lfo) + b2value * lfo;
 
185
                        
 
186
                        /*
 
187
                         * increment delay buffer position
 
188
                         */
 
189
                        dbpos++;
 
190
                        if (dbpos == MAXDELAY)
 
191
                                dbpos = 0;
 
192
                }
 
193
        }
 
194
};
 
195
 
 
196
REGISTER_IMPLEMENTATION(Synth_PITCH_SHIFT_impl);