1 /* logistic.cpp
2 
3    A sample-and-hold logistic map control generator
4 
5    (c) 2002 Nathaniel Virgo
6 
7    Part of the Computer Music Toolkit - a library of LADSPA plugins.
8    The Computer Music Toolkit is Copyright (C) 2000-2002
9    Richard W.E. Furse. The author may be contacted at
10    richard@muse.demon.co.uk.
11 
12    This library is free software; you can redistribute it and/or
13    modify it under the terms of the GNU General Public Licence as
14    published by the Free Software Foundation; either version 2 of the
15    Licence, or (at your option) any later version.
16 
17    This library is distributed in the hope that it will be useful, but
18    WITHOUT ANY WARRANTY; without even the implied warranty of
19    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20    General Public License for more details.
21 
22    You should have received a copy of the GNU General Public License
23    along with this library; if not, write to the Free Software
24    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25    02111-1307, USA. */
26 
27 /*****************************************************************************/
28 
29 #include <stdlib.h>
30 
31 /*****************************************************************************/
32 
33 #include "cmt.h"
34 
35 #include "pinknoise.h"
36 #include "utils.h"
37 
38 /*****************************************************************************/
39 
40 namespace logistic {
41 
42     enum {
43 	port_r           = 0,
44 	port_frequency   = 1,
45 	port_output      = 2,
46 	n_ports          = 3
47     };
48 
49     /** This plugin uses the logistic map to generate periodic or
50 	chaotic control signals. */
51     class Plugin : public CMT_PluginInstance {
52     private:
53 	LADSPA_Data sample_rate;
54 	LADSPA_Data x;
55 	unsigned counter;
56     public:
57 
Plugin(const LADSPA_Descriptor *,unsigned long s_rate)58         Plugin(const LADSPA_Descriptor *,
59 	       unsigned long s_rate) :
60 	    CMT_PluginInstance(n_ports),
61 	    sample_rate(s_rate) {
62 	}
63 
~Plugin()64 	~Plugin() {
65 	}
66 
67 	friend void activate(LADSPA_Handle instance);
68 
69 	friend void run(LADSPA_Handle instance,
70 			unsigned long sample_count);
71     };
72 
activate(LADSPA_Handle instance)73     void activate(LADSPA_Handle instance) {
74 	Plugin *pp = (Plugin *) instance;
75 	Plugin &p  = *pp;
76 
77 	p.x = 0.3; // arbitrary non-zero value.
78     }
79 
run(LADSPA_Handle instance,unsigned long sample_count)80     void run(LADSPA_Handle instance,
81 	     unsigned long sample_count) {
82 
83 	Plugin *pp = (Plugin *) instance;
84 	Plugin &p  = *pp;
85 
86 	LADSPA_Data   r         = *pp->m_ppfPorts[port_r];
87 	LADSPA_Data   frequency = *pp->m_ppfPorts[port_frequency];
88 	LADSPA_Data * out       =  pp->m_ppfPorts[port_output];
89 
90 	frequency = BOUNDED_ABOVE(frequency,p.sample_rate);
91 	r = BOUNDED_ABOVE(r,4);
92 	unsigned remain = sample_count;
93 
94 	if (frequency > 0) {
95 	    while (remain) {
96 		unsigned jump_samples = (remain<p.counter) ? remain : p.counter;
97 		for (unsigned j=0; j<jump_samples; ++j) {
98 		    *(out++) = p.x*2-1;
99 		}
100 		p.counter -= jump_samples;
101 		remain -= jump_samples;
102 		if (p.counter==0) {
103 		    p.x = r*p.x*(1.0f - p.x);
104 		    p.counter = (unsigned)(p.sample_rate/frequency);
105 		}
106 	    }
107 	}
108 	else
109 	{
110 	    for (unsigned long i=0; i<sample_count; ++i)
111 		*(out++) = p.x;
112 	}
113     }
114 
initialise()115     void initialise() {
116 	CMT_Descriptor * d = new CMT_Descriptor
117 	    (1849,
118 	     "logistic",
119 	     0,
120 	     "Logistic Map Control Generator",
121 	     CMT_MAKER("Nathaniel Virgo"),
122 	     CMT_COPYRIGHT("2002", "Nathaniel Virgo"),
123 	     NULL,
124 	     CMT_Instantiate<Plugin>,
125 	     activate,
126 	     run,
127 	     NULL,
128 	     NULL,
129 	     NULL);
130 	d->addPort
131 	    (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
132 	     "\"r\" parameter",
133 	     (LADSPA_HINT_BOUNDED_BELOW
134 	      | LADSPA_HINT_BOUNDED_ABOVE
135 	      | LADSPA_HINT_DEFAULT_MAXIMUM),
136 	     2.9, 3.9999);
137 	d->addPort
138 	    (LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
139 	     "Step frequency",
140 	     (LADSPA_HINT_BOUNDED_BELOW
141 	      | LADSPA_HINT_BOUNDED_ABOVE
142 	      | LADSPA_HINT_SAMPLE_RATE
143 	      | LADSPA_HINT_DEFAULT_MIDDLE),
144 	     0, 0.001);
145 	d->addPort
146 	    (LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
147 	     "Output");
148 	registerNewPluginDescriptor(d);
149     }
150 
151 } // end of namespace
152 
153 /*****************************************************************************/
154 
155 /* EOF */
156 
157