comparison examples/airharp/Waveguide.cpp @ 300:dbeed520b014 prerelease

Renamed projects to examples
author Giulio Moro <giuliomoro@yahoo.it>
date Fri, 27 May 2016 13:58:20 +0100
parents projects/airharp/Waveguide.cpp@40badaff5729
children
comparison
equal deleted inserted replaced
297:a3d83ebdf49b 300:dbeed520b014
1 /*
2 *
3 * Simple 1-Dimensional Waveguide
4 *
5 */
6
7 #include "Waveguide.h"
8 #include "../include/Utilities.h"
9 #include <rtdk.h>
10 #include <cmath>
11 #include <stdio.h>
12 #include <cstdlib>
13
14 #define DECAY 0.995//0.999
15 #define DAMPING 0.01//0.05
16
17 // TODO: make damping and decay parametrisable
18
19 Waveguide::Waveguide() {
20
21 // initialize variables
22 a1_lp = 0;
23 a2_lp = 0;
24 b0_lp = 0;
25 b1_lp = 0;
26 b2_lp = 0;
27 _dt = 1.0/44100.0;
28 setFrequency(440);
29 updateFilterCoeffs(8000);
30 _filterReadPtr=0;
31 for(int i=0;i<FILTER_BUFFER_SIZE;i++) {
32 _filterBuffer_x[i] = 0;
33 _filterBuffer_y[i] = 0;
34 }
35 for(int i=0;i<WG_BUFFER_SIZE;i++) {
36 _buffer[i] = 0;
37 }
38 _lastX = 0;
39 _lastY = 0;
40 _readPtr = 0;
41
42 }
43
44 void Waveguide::setup() {
45
46 }
47
48 float Waveguide::update(float in) {
49
50 // 1. advance delay buffer read pointer
51
52 if(++_readPtr>=WG_BUFFER_SIZE)
53 _readPtr=0;
54
55 // 2. write input into buffer
56
57 _buffer[_readPtr] = in;
58
59 // 3. read delayed sample from buffer
60
61 float out = _buffer[(_readPtr-_periodInSamples+WG_BUFFER_SIZE)%WG_BUFFER_SIZE];
62
63 // 4. apply damping (low-pass) filter to output
64
65 if(++_filterReadPtr>=FILTER_BUFFER_SIZE)
66 _filterReadPtr=0;
67
68 out = b0_lp*out +
69 b1_lp*_filterBuffer_x[(_filterReadPtr-1+FILTER_BUFFER_SIZE)%FILTER_BUFFER_SIZE] +
70 b2_lp*_filterBuffer_x[(_filterReadPtr-2+FILTER_BUFFER_SIZE)%FILTER_BUFFER_SIZE] -
71 a1_lp*_filterBuffer_y[(_filterReadPtr-1+FILTER_BUFFER_SIZE)%FILTER_BUFFER_SIZE] -
72 a2_lp*_filterBuffer_y[(_filterReadPtr-2+FILTER_BUFFER_SIZE)%FILTER_BUFFER_SIZE];
73
74 // 5. Simple high-pass filter to block DC-offset
75 // y[n] = x[n] - x[n-1] + a * y[n-1]
76 float gain = 0.9999;
77 float temp = out;
78 out = out - _lastX + gain * _lastY;
79 _lastY = out;
80 _lastX = temp;
81
82 // 6. Apply intensity damping
83 out *= DECAY;
84
85 _filterBuffer_x[_filterReadPtr] = in;
86 _filterBuffer_y[_filterReadPtr] = out;
87
88 return out;
89
90 }
91
92 void Waveguide::setFrequency(float frequency) {
93
94 // NB: currently no interpolation, so may not be ideal for dynamically changing waveguide frequency
95 _periodInMilliseconds = 1000.0/frequency;
96 _periodInSamples = (int)(_periodInMilliseconds * 44.1);
97
98 }
99
100 void Waveguide::updateFilterCoeffs(float frequency) {
101
102 // FIXME: Butterworth filter doesn't work very well,
103 // using simple FIR in the meantime
104
105 a1_lp = 0;
106 a2_lp = 0;
107 b0_lp = 1.0 - DAMPING;
108 b1_lp = DAMPING;
109 b2_lp = 0;
110
111 /*
112 // 'w' for sake of resembling lower-case 'omega'
113 float w = 2.0 * M_PI * frequency;
114 float t = _dt;
115 // The Q for a 2nd-order Butterworth is sqrt(2)/2
116 float q = 0.707;//sqrt(2.0)/2.0;
117
118 // low-pass filter coefficients
119 float a0_lp = w*w*t*t + 2*(w/q)*t + 4.0;
120 float k = 1.0/a0_lp;
121 a1_lp = (2.0*w*w*t*t - 8.0) * k;
122 a2_lp = (4.0 - (w/q)*2.0*t + w*w*t*t) * k;
123 b0_lp = (w*w*t*t) * k;
124 b1_lp = (2.0*w*w*t*t) * k;
125 b2_lp = (w*w*t*t) * k;
126 */
127
128 }