1 /*
2  * Copyright (C) 2012 Hermann Meyer, Andreas Degert, Pete Shorthose, Steve Poskitt
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 ////////////////////////////// LOCAL INCLUDES //////////////////////////
21 
22 #include "gx_common.h"      // faust support and denormal protection (SSE)
23 #include "gxtape_st.h"        // define struct PortIndex
24 #include "gx_pluginlv2.h"   // define struct PluginLV2
25 #include "gxtape_st.cc"    // dsp class generated by faust -> dsp2cc
26 #ifndef __SSE__
27 #include "noiser.cc"
28 #endif
29 
30 ////////////////////////////// PLUG-IN CLASS ///////////////////////////
31 
32 
33 class Gxtape_st
34 {
35 private:
36   // internal stuff
37   float*                       output0;
38   float*                       input0;
39   float*                       output1;
40   float*                       input1;
41   float*                       meterlevel;
42   PluginLV2*                   tape;
43 #ifndef __SSE__
44   PluginLV2*                   wn;
45 #endif
46 public:
47 
48   inline void run_dsp_stereo(uint32_t n_samples);
49   inline void connect_stereo(uint32_t port,void* data);
50   inline void init_dsp_stereo(uint32_t rate);
51   inline void connect_all_stereo_ports(uint32_t port, void* data);
52   inline void activate_f();
53   inline void clean_up();
54   Gxtape_st();
55   ~Gxtape_st();
56 };
57 
58 // constructor
Gxtape_st()59 Gxtape_st::Gxtape_st() :
60   output0(NULL),
61   input0(NULL),
62   output1(NULL),
63   input1(NULL),
64   tape(gxtape_st::plugin()) {};
65 
66 // destructor
~Gxtape_st()67 Gxtape_st::~Gxtape_st()
68 {
69   // just to be sure the plug have given free the allocated mem
70 
71  // it didn't hurd if the mem is already given free by clean_up()
72   tape->activate_plugin(false, tape);
73   // delete DSP class
74   tape->delete_instance(tape);
75 };
76 
77 ////////////////////////////// PLUG-IN CLASS  FUNCTIONS ////////////////
78 
init_dsp_stereo(uint32_t rate)79 void Gxtape_st::init_dsp_stereo(uint32_t rate)
80 {
81   AVOIDDENORMALS(); // init the SSE denormal protection
82 #ifndef __SSE__
83   wn = noiser::plugin();
84   wn->set_samplerate(rate, wn);
85 #endif
86   tape->set_samplerate(rate, tape); // init the DSP class
87 }
88 
89 // connect the Ports used by the plug-in class
connect_stereo(uint32_t port,void * data)90 void Gxtape_st::connect_stereo(uint32_t port,void* data)
91 {
92   switch ((PortIndex)port)
93     {
94     case EFFECTS_OUTPUT_L:
95       output0 = static_cast<float*>(data);
96       break;
97     case EFFECTS_OUTPUT_R:
98       output1 = static_cast<float*>(data);
99       break;
100     case EFFECTS_INPUT_L:
101       input0 = static_cast<float*>(data);
102       break;
103     case EFFECTS_INPUT_R:
104       input1 = static_cast<float*>(data);
105       break;
106 /*    case METERLEVEL:
107       meterlevel = static_cast<float*>(data);
108       break;
109  */   default:
110       break;
111     }
112 }
113 
activate_f()114 void Gxtape_st::activate_f()
115 {
116   // allocate the internal DSP mem
117   tape->activate_plugin(true, tape);
118 }
119 
clean_up()120 void Gxtape_st::clean_up()
121 {
122 #ifndef __SSE__
123   wn->delete_instance(wn);;
124 #endif
125   // delete the internal DSP mem
126   tape->activate_plugin(false, tape);
127 }
128 
run_dsp_stereo(uint32_t n_samples)129 void Gxtape_st::run_dsp_stereo(uint32_t n_samples)
130 {
131   if (n_samples< 1) return;
132 #ifndef __SSE__
133   wn->stereo_audio(static_cast<int>(n_samples), input0,
134                          input1, output0,output1,  wn);;
135 #endif
136   tape->stereo_audio(static_cast<int>(n_samples), input0,
137                         input1, output0,output1, tape);
138 
139 }
140 
connect_all_stereo_ports(uint32_t port,void * data)141 void Gxtape_st::connect_all_stereo_ports(uint32_t port, void* data)
142 {
143   // connect the Ports used by the plug-in class
144   connect_stereo(port,data);
145   // connect the Ports used by the DSP class
146   tape->connect_ports(port,  data, tape);
147 }
148 
149 ///////////////////////////// LV2 defines //////////////////////////////
150 
151 static LV2_Handle
instantiate(const LV2_Descriptor * descriptor,double rate,const char * bundle_path,const LV2_Feature * const * features)152 instantiate(const LV2_Descriptor*     descriptor,
153             double                    rate,
154             const char*               bundle_path,
155             const LV2_Feature* const* features)
156 {
157   // init the plug-in class
158   Gxtape_st *self = new Gxtape_st();
159   if (!self)
160     {
161       return NULL;
162     }
163 
164   self->init_dsp_stereo((uint32_t)rate);
165 
166   return (LV2_Handle)self;
167 }
168 
169 static void
connect_port(LV2_Handle instance,uint32_t port,void * data)170 connect_port(LV2_Handle instance,
171              uint32_t   port,
172              void*      data)
173 {
174   // connect all ports
175   static_cast<Gxtape_st*>(instance)->connect_all_stereo_ports(port, data);
176 }
177 
178 static void
activate(LV2_Handle instance)179 activate(LV2_Handle instance)
180 {
181   // allocate needed mem
182   static_cast<Gxtape_st*>(instance)->activate_f();
183 }
184 
185 static void
run(LV2_Handle instance,uint32_t n_samples)186 run(LV2_Handle instance, uint32_t n_samples)
187 {
188   // run dsp
189   static_cast<Gxtape_st*>(instance)->run_dsp_stereo(n_samples);
190 }
191 
192 static void
cleanup(LV2_Handle instance)193 cleanup(LV2_Handle instance)
194 {
195   // well, clean up after us
196   Gxtape_st* self = static_cast<Gxtape_st*>(instance);
197   self->clean_up();
198   delete self;
199 }
200 
201 ///////////////////////////// LV2 DESCRIPTOR ///////////////////////////
202 static const LV2_Descriptor descriptor =
203 {
204   GXPLUGIN_URI "#tape",
205   instantiate,
206   connect_port,
207   activate,
208   run,
209   NULL,
210   cleanup,
211   NULL
212 };
213 
214 LV2_SYMBOL_EXPORT
215 const LV2_Descriptor*
lv2_descriptor(uint32_t index)216 lv2_descriptor(uint32_t index)
217 {
218   switch (index)
219     {
220     case 0:
221       return &descriptor;
222     default:
223       return NULL;
224     }
225 }
226 
227 ///////////////////////////// FIN //////////////////////////////////////
228