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