Mercurial > hg > apm2s
comparison AccessiblePeakMeter.h @ 0:4606bd505630 tip
first import
author | Fiore Martin <f.martin@qmul.ac.uk> |
---|---|
date | Sat, 13 Jun 2015 15:08:10 +0100 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4606bd505630 |
---|---|
1 // | |
2 // AccessiblePeakMeter.h | |
3 // | |
4 // Author: Fiore Martin | |
5 // Started from IPlugMultiTargets example in WDL-OL, by Oli Larkin - https://github.com/olilarkin/wdl-ol | |
6 // | |
7 // Licensed under the Cockos WDL License, see README.txt | |
8 // | |
9 | |
10 #ifndef __ACCESSIBLEPEAKMETER__ | |
11 #define __ACCESSIBLEPEAKMETER__ | |
12 | |
13 #include "IPlug_include_in_plug_hdr.h" | |
14 #include "stk/include/SineWave.h" | |
15 #include "stk/include/Envelope.h" | |
16 #include "stk/include/ADSR.h" | |
17 #include "stk/include/RtAudio.h" | |
18 #include "stk/include/RtWvOut.h" | |
19 | |
20 #include <thread> | |
21 #include <mutex> | |
22 | |
23 | |
24 const int DAC_BUFFER_SIZE = 64; | |
25 const int SONIFICATION_TYPE_CLIPPING = 1; | |
26 const int SONIFICATION_TYPE_CONTINUOUS = 0; | |
27 const double BEEP_TIME = 0.2; | |
28 const int MAX_CHANNELS = 2; | |
29 | |
30 /* | |
31 This is a slightly hacked version of the AccessiblePeakMeter. The sonification is sent to | |
32 the defualt audio card rather than to the plugin output. The input audio signal is still | |
33 routed to the plugin out put with nomodification besides the amplitude, modified according | |
34 to the dry parameter. | |
35 | |
36 When Reset() is called for the first time on the plugin, a new thread is spawned. | |
37 The VST plugin then continuously shares information about the input audio with the thread. | |
38 The thread continously polls this information and plays the sonification on the default audio interface. | |
39 | |
40 DacRoutine() : is the function execute by the new thread | |
41 DacSynced : is the struct with all shared variables between the new thread and the VST plugin | |
42 Sonification: is the structure with all the sonification stuff. In this version it is only | |
43 accessed by the new thread. | |
44 | |
45 DacThread struct does RAAI on the resource "thread" | |
46 | |
47 */ | |
48 | |
49 | |
50 | |
51 /* DacRouting is the function executed by the thread that plays the sonification to the dac */ | |
52 void DacRoutine(); | |
53 | |
54 /* the sonification struct contains all the variables for sonification. | |
55 It is accessed exclusively by the sonification thread */ | |
56 struct Sonification { | |
57 stk::SineWave ugen[MAX_CHANNELS]; | |
58 | |
59 /* resets all the ugens. Type and ugen freq are not affected by reset | |
60 as well as sample rate, when srate is less than 0 */ | |
61 void reset(double srate = -1.0){ | |
62 for (int i = 0; i < MAX_CHANNELS; i++){ | |
63 ugen[i].reset(); | |
64 | |
65 /* continous sonification */ | |
66 continous.isOn[i] = true; | |
67 stk::Envelope & coe = continous.envelope[i]; | |
68 coe.setValue(1.0); // setValue also sets the target | |
69 coe.setTime(0.2); | |
70 | |
71 /* clipping sonification */ | |
72 clipping.maxDiff[i] = 0.0; | |
73 stk::ADSR & cle = clipping.envelope[i]; | |
74 cle.setValue(0.0); | |
75 cle.setReleaseTime(BEEP_TIME); | |
76 cle.setAttackTime(0.01); | |
77 cle.setSustainLevel(1); | |
78 | |
79 /* | |
80 the sample is fixed to 44100 when the handle to the soundcard is created | |
81 the sonification is independent from changes in the daw sample rate anyway | |
82 if (srate > 0.0){ | |
83 ugen[i].setSampleRate(srate); | |
84 coe.setSampleRate(srate); | |
85 cle.setSampleRate(srate); | |
86 } | |
87 */ | |
88 } | |
89 } | |
90 | |
91 struct Continous { | |
92 stk::Envelope envelope[MAX_CHANNELS]; | |
93 bool isOn[MAX_CHANNELS]; | |
94 } continous; | |
95 | |
96 struct Clipping { | |
97 double maxDiff[MAX_CHANNELS]; | |
98 stk::ADSR envelope[MAX_CHANNELS]; | |
99 } clipping; | |
100 | |
101 Sonification() { | |
102 reset(); | |
103 } | |
104 } sSonification; | |
105 | |
106 /* this structure is used to pass information back and forth between | |
107 the puginthread and the sonification thread, with direct access to the sound card */ | |
108 struct DacSynced { | |
109 bool die; | |
110 double wet; | |
111 double sonifFreq[MAX_CHANNELS]; | |
112 int type; | |
113 double maxClippingDiff[MAX_CHANNELS]; | |
114 int sonificationType; | |
115 DacSynced() | |
116 : die(false), | |
117 wet(0.5), | |
118 sonificationType( SONIFICATION_TYPE_CLIPPING ) | |
119 { | |
120 for (int i = 0; i < MAX_CHANNELS; i++){ | |
121 sonifFreq[i] = 0.0; | |
122 maxClippingDiff[i] = 0.0; | |
123 } | |
124 } | |
125 } sDacSynced; | |
126 | |
127 | |
128 | |
129 /* mutex to sync the vst plugin thread with the thread | |
130 that writes directly into the soundcard (DacThread) | |
131 */ | |
132 std::mutex sDacMutex; | |
133 | |
134 | |
135 /*sPrevSonificationType keeps track of the sonification type. Useful for DacThread | |
136 to assess whether the sonification has changed from the last loop cycle */ | |
137 int sPrevSonificationType = SONIFICATION_TYPE_CLIPPING; | |
138 | |
139 struct DacThread { | |
140 std::thread t; | |
141 bool started = false; | |
142 | |
143 /* when this struct goes out of scope (user * | |
144 * exits daw) The thread is stopped and joined. */ | |
145 ~DacThread(){ | |
146 sDacMutex.lock(); | |
147 sDacSynced.die = true; | |
148 sDacMutex.unlock(); | |
149 | |
150 if (t.joinable()) | |
151 t.join(); | |
152 } | |
153 | |
154 } sDacThread; | |
155 | |
156 class AccessiblePeakMeter : public IPlug | |
157 { | |
158 public: | |
159 | |
160 AccessiblePeakMeter(IPlugInstanceInfo instanceInfo); | |
161 ~AccessiblePeakMeter(); | |
162 | |
163 void Reset(); | |
164 void OnParamChange(int paramIdx); | |
165 | |
166 void ProcessDoubleReplacing(double** inputs, double** outputs, int nFrames); | |
167 bool HostRequestingAboutBox(); | |
168 | |
169 static const double DRY_DEFAULT; | |
170 static const double WET_DEFAULT; | |
171 static const int SONIFICATION_TYPE_DEFAULT; | |
172 static const double METERDECAY_DEFAULT; | |
173 static const double THRESHOLD_DEFAULT; | |
174 static const double BEEP_TIME; | |
175 static const double DB_RANGE; | |
176 static const double SONIFICATION_RANGE; | |
177 static const int NO_BEEP; | |
178 static const int NUM_PRESETS = 2; | |
179 static const double MIN_SONIFICATION_FREQ; | |
180 static const int NUM_KNOB_FRAMES; | |
181 static const double CLIPPING_CEILING_SNAP; | |
182 | |
183 private: | |
184 /* parameters on the GUI */ | |
185 double mDry; | |
186 double mWet; | |
187 double mMeterDecayRate; | |
188 double mThreshold; | |
189 | |
190 double mSampleRate; | |
191 | |
192 double mPrevPeak[MAX_CHANNELS]; | |
193 int mMeterIdx[MAX_CHANNELS]; | |
194 | |
195 int mSonificationType; | |
196 | |
197 void addContinuousSonification(double** inputs, double** outputs, int nFrames); | |
198 void addClippingSonification(double** inputs, double** outputs, int nFrames); | |
199 }; | |
200 | |
201 #endif //__ACCESSIBLEPEAKMETER__ |