1 /*
2 * Copyright (C) 2013 Hermann Meyer
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17 * --------------------------------------------------------------------------
18 */
19
20 #include <unistd.h>
21 #include <semaphore.h>
22 #include <pthread.h>
23 #include <sys/stat.h>
24
25 #include <sstream>
26 #include <cstdio>
27 #include <cstdlib>
28 #include <cmath>
29 #include <climits>
30
31 #include <sndfile.hh>
32
33 #include <lv2.h>
34
35 #define SCPLUGIN_URI "https://github.com/brummer10/screcord"
36
37 typedef enum
38 {
39 FORM,
40 REC,
41 CLIP,
42 EFFECTS_OUTPUT,
43 EFFECTS_INPUT,
44 EFFECTS_OUTPUT1,
45 EFFECTS_INPUT1,
46 } PortIndex;
47
48 ////////////////////////////// LOCAL INCLUDES //////////////////////////
49
50 #include "screcord1.cc"
51
52 ////////////////////////////// PLUG-IN CLASS ///////////////////////////
53
54 class SCrecord
55 {
56 private:
57 // pointer to buffer
58 float* output;
59 float* input;
60 float* output1;
61 float* input1;
62 // pointer to dsp class
63 screcord::SCapture* record;
64 // private functions
65 inline void run_dsp_(uint32_t n_samples);
66 inline void run_dsp_st(uint32_t n_samples);
67 inline void connect_(uint32_t port,void* data);
68 inline void init_dsp_(uint32_t rate);
69 inline void init_dsp_st(uint32_t rate);
70 inline void connect_all__ports(uint32_t port, void* data);
71 inline void activate_f();
72 inline void clean_up();
73 inline void deactivate_f();
74
75 public:
76 // LV2 Descriptor
77 static const LV2_Descriptor descriptor;
78 static const LV2_Descriptor descriptor1;
79 // static wrapper to private functions
80 static void deactivate(LV2_Handle instance);
81 static void cleanup(LV2_Handle instance);
82 static void run(LV2_Handle instance, uint32_t n_samples);
83 static void run_st(LV2_Handle instance, uint32_t n_samples);
84 static void activate(LV2_Handle instance);
85 static void connect_port(LV2_Handle instance, uint32_t port, void* data);
86 static LV2_Handle instantiate(const LV2_Descriptor* descriptor,
87 double rate, const char* bundle_path,
88 const LV2_Feature* const* features);
89 static LV2_Handle instantiate_st(const LV2_Descriptor* descriptor,
90 double rate, const char* bundle_path,
91 const LV2_Feature* const* features);
92 SCrecord();
93 ~SCrecord();
94 };
95
96 // constructor
SCrecord()97 SCrecord::SCrecord() :
98 output(NULL),
99 input(NULL),
100 output1(NULL),
101 input1(NULL) { };
102
103 // destructor
~SCrecord()104 SCrecord::~SCrecord()
105 {
106 record->activate_plugin(false, record);
107 record->delete_instance(record);
108 };
109
110 ///////////////////////// PRIVATE CLASS FUNCTIONS /////////////////////
111
init_dsp_(uint32_t rate)112 void SCrecord::init_dsp_(uint32_t rate)
113 {
114 record = new screcord::SCapture(1);
115 record->set_samplerate(rate, record); // init the DSP class
116 }
117
init_dsp_st(uint32_t rate)118 void SCrecord::init_dsp_st(uint32_t rate)
119 {
120 record = new screcord::SCapture(2);
121 record->set_samplerate(rate, record); // init the DSP class
122 }
123
124 // connect the Ports used by the plug-in class
connect_(uint32_t port,void * data)125 void SCrecord::connect_(uint32_t port,void* data)
126 {
127 switch ((PortIndex)port)
128 {
129 case EFFECTS_OUTPUT:
130 output = static_cast<float*>(data);
131 break;
132 case EFFECTS_INPUT:
133 input = static_cast<float*>(data);
134 break;
135 case EFFECTS_OUTPUT1:
136 output1 = static_cast<float*>(data);
137 break;
138 case EFFECTS_INPUT1:
139 input1 = static_cast<float*>(data);
140 break;
141 default:
142 break;
143 }
144 }
145
activate_f()146 void SCrecord::activate_f()
147 {
148 // allocate the internal DSP mem
149 record->activate_plugin(true, record);
150 }
151
clean_up()152 void SCrecord::clean_up()
153 {
154 // delete the internal DSP mem
155 record->activate_plugin(false, record);
156 }
157
deactivate_f()158 void SCrecord::deactivate_f()
159 {
160 // delete the internal DSP mem
161 record->activate_plugin(false, record);
162 }
163
run_dsp_(uint32_t n_samples)164 void SCrecord::run_dsp_(uint32_t n_samples)
165 {
166 record->mono_audio(static_cast<int>(n_samples), input, output, record);
167 }
168
run_dsp_st(uint32_t n_samples)169 void SCrecord::run_dsp_st(uint32_t n_samples)
170 {
171 record->stereo_audio(static_cast<int>(n_samples), input, input1, output, output1, record);
172 }
173
connect_all__ports(uint32_t port,void * data)174 void SCrecord::connect_all__ports(uint32_t port, void* data)
175 {
176 // connect the Ports used by the plug-in class
177 connect_(port,data);
178 // connect the Ports used by the DSP class
179 record->connect_ports(port, data, record);
180 }
181
182 ////////////////////// STATIC CLASS FUNCTIONS ////////////////////////
183
184 LV2_Handle
instantiate(const LV2_Descriptor * descriptor,double rate,const char * bundle_path,const LV2_Feature * const * features)185 SCrecord::instantiate(const LV2_Descriptor* descriptor,
186 double rate, const char* bundle_path,
187 const LV2_Feature* const* features)
188 {
189 // init the plug-in class
190 SCrecord *self = new SCrecord();
191 if (!self)
192 {
193 return NULL;
194 }
195
196 self->init_dsp_((uint32_t)rate);
197
198 return (LV2_Handle)self;
199 }
200
201 LV2_Handle
instantiate_st(const LV2_Descriptor * descriptor,double rate,const char * bundle_path,const LV2_Feature * const * features)202 SCrecord::instantiate_st(const LV2_Descriptor* descriptor,
203 double rate, const char* bundle_path,
204 const LV2_Feature* const* features)
205 {
206 // init the plug-in class
207 SCrecord *self = new SCrecord();
208 if (!self)
209 {
210 return NULL;
211 }
212
213 self->init_dsp_st((uint32_t)rate);
214
215 return (LV2_Handle)self;
216 }
217
connect_port(LV2_Handle instance,uint32_t port,void * data)218 void SCrecord::connect_port(LV2_Handle instance,
219 uint32_t port, void* data)
220 {
221 // connect all ports
222 static_cast<SCrecord*>(instance)->connect_all__ports(port, data);
223 }
224
activate(LV2_Handle instance)225 void SCrecord::activate(LV2_Handle instance)
226 {
227 // allocate needed mem
228 static_cast<SCrecord*>(instance)->activate_f();
229 }
230
run(LV2_Handle instance,uint32_t n_samples)231 void SCrecord::run(LV2_Handle instance, uint32_t n_samples)
232 {
233 // run dsp
234 static_cast<SCrecord*>(instance)->run_dsp_(n_samples);
235 }
236
run_st(LV2_Handle instance,uint32_t n_samples)237 void SCrecord::run_st(LV2_Handle instance, uint32_t n_samples)
238 {
239 // run dsp
240 static_cast<SCrecord*>(instance)->run_dsp_st(n_samples);
241 }
242
deactivate(LV2_Handle instance)243 void SCrecord::deactivate(LV2_Handle instance)
244 {
245 // free allocated mem
246 static_cast<SCrecord*>(instance)->deactivate_f();
247 }
248
cleanup(LV2_Handle instance)249 void SCrecord::cleanup(LV2_Handle instance)
250 {
251 // well, clean up after us
252 SCrecord* self = static_cast<SCrecord*>(instance);
253 self->clean_up();
254 delete self;
255 }
256
257 const LV2_Descriptor SCrecord::descriptor =
258 {
259 SCPLUGIN_URI "#mono_record",
260 SCrecord::instantiate,
261 SCrecord::connect_port,
262 SCrecord::activate,
263 SCrecord::run,
264 SCrecord::deactivate,
265 SCrecord::cleanup,
266 NULL
267 };
268
269 const LV2_Descriptor SCrecord::descriptor1 =
270 {
271 SCPLUGIN_URI "#stereo_record",
272 SCrecord::instantiate_st,
273 SCrecord::connect_port,
274 SCrecord::activate,
275 SCrecord::run_st,
276 SCrecord::deactivate,
277 SCrecord::cleanup,
278 NULL
279 };
280
281 ////////////////////////// LV2 SYMBOL EXPORT ///////////////////////////
282
283 extern "C"
284 LV2_SYMBOL_EXPORT
285 const LV2_Descriptor*
lv2_descriptor(uint32_t index)286 lv2_descriptor(uint32_t index)
287 {
288 switch (index)
289 {
290 case 0:
291 return &SCrecord::descriptor;
292 case 1:
293 return &SCrecord::descriptor1;
294 default:
295 return NULL;
296 }
297 }
298
299 ///////////////////////////// FIN //////////////////////////////////////
300