1 /* B.Oops
2  * Glitch effect sequencer LV2 plugin
3  *
4  * Copyright (C) 2020 by Sven Jähnichen
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19  */
20 
21 #ifndef FXOOPSHPP_
22 #define FXOOPSHPP_
23 
24 #include "Fx.hpp"
25 #include "Sample.hpp"
26 
27 #define FX_OOPSAMP 0
28 #define FX_OOPSAMPRAND 1
29 #define FX_OOPSPITCH 2
30 #define FX_OOPSPITCHRAND 3
31 #define FX_OOPSOFFSET 4
32 #define FX_OOPSOFFSETRAND 5
33 
34 class FxOops : public Fx
35 {
36 public:
37 	FxOops () = delete;
38 
FxOops(RingBuffer<Stereo> ** buffer,float * params,Pad * pads,double * framesPerStep,double rate,const char * pluginpath)39 	FxOops (RingBuffer<Stereo>** buffer, float* params, Pad* pads, double* framesPerStep, double rate, const char* pluginpath) :
40 		Fx (buffer, params, pads),
41 		samplerate (rate),
42 		framesPerStepPtr (framesPerStep),
43 		framesPerStep (24000),
44 		amp (0.0f), pitch (0.0f), offset (0.0)
45 	{
46 		if (!framesPerStep) throw std::invalid_argument ("Fx initialized with framesPerStep nullptr");
47 
48 		if (pluginpath)
49 		{
50 			char samplepath[1024] = {0};
51 			strncpy (samplepath, pluginpath, 988);
52 			strcat (samplepath, "inc/Oops.wav");
53 			try {oops = Sample (samplepath);}
54 			catch (std::bad_alloc &ba)
55 			{
56 				fprintf (stderr, "BOops.lv2: Can't allocate enoug memory to open inc/Oops.wav.\n");
57 			}
58 			catch (std::invalid_argument &ia)
59 			{
60 				fprintf (stderr, "%s\n", ia.what());
61 			}
62 		}
63 	}
64 
init(const double position)65 	virtual void init (const double position) override
66 	{
67 		Fx::init (position);
68 		const double r1 = bidist (rnd);
69 		amp = LIMIT (2.0 * (params[SLOTS_OPTPARAMS + FX_OOPSAMP] + r1 * params[SLOTS_OPTPARAMS + FX_OOPSAMPRAND]), 0.0, 2.0);
70 		const double r2 = bidist (rnd);
71 		pitch = pow (2.0, LIMIT (2.0 * (params[SLOTS_OPTPARAMS + FX_OOPSPITCH] + r2 * params[SLOTS_OPTPARAMS + FX_OOPSPITCHRAND]) - 1.0, -1.0, 1.0));
72 		framesPerStep = *framesPerStepPtr;
73 		offset = (params ? LIMIT (params[SLOTS_OPTPARAMS + FX_OOPSOFFSET] + r1 * params[SLOTS_OPTPARAMS + FX_OOPSOFFSETRAND], 0.0, 1.0) : 0.0);
74 	}
75 
process(const double position,const double size)76 	virtual Stereo process (const double position, const double size) override
77 	{
78 		const Stereo s0 = (**buffer).front();
79 		Stereo s1 = Stereo (0, 0);
80 		if (position > offset)
81 		{
82 			sf_count_t frame = (position - offset) * framesPerStep * pitch;
83 			s1 = Stereo (oops.get (frame, 0, samplerate), oops.get (frame, 0, samplerate));
84 		}
85 
86 		return s0 + s1 * amp;
87 	}
88 
89 protected:
90 	double samplerate;
91 	double* framesPerStepPtr;
92 	double framesPerStep;
93 	Sample oops;
94 	float amp;
95 	float pitch;
96 	double offset;
97 
98 };
99 
100 #endif /* FXOOPSHPP_ */
101