1 /*
2 * Author: Harry van Haaren 2013
3 * harryhaaren@gmail.com
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 * MA 02110-1301, USA.
19 */
20
21 #include "della.hxx"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <math.h>
27
28 #include "dsp_delay.hxx"
29
30 #include "lv2/lv2plug.in/ns/ext/atom/atom.h"
31 #include "lv2/lv2plug.in/ns/ext/atom/util.h"
32 #include "lv2/lv2plug.in/ns/ext/urid/urid.h"
33 #include "lv2/lv2plug.in/ns/ext/time/time.h"
34
35
36
instantiate(const LV2_Descriptor * descriptor,double samplerate,const char * bundle_path,const LV2_Feature * const * features)37 LV2_Handle Della::instantiate(const LV2_Descriptor* descriptor,
38 double samplerate,
39 const char* bundle_path,
40 const LV2_Feature* const* features)
41 {
42 Della* d = new Della( samplerate );
43 d->map = 0;
44
45 // get URID_map and unmap
46 for (int i = 0; features[i]; i++) {
47 if (!strcmp(features[i]->URI, LV2_URID__map)) {
48 d->map = (LV2_URID_Map*)features[i]->data;
49 }
50 }
51
52 // we don't have the map extension: print warning
53 if( !d->map ) {
54 printf("Della: Error: host doesn't provide Lv2 URID map, cannot sync BPM!\n");
55 delete d;
56 return 0;
57 }
58
59 // Get URID's for Lv2 TIME / ATOM extensions
60 d->time_Position = d->map->map(d->map->handle, LV2_TIME__Position);
61 d->time_barBeat = d->map->map(d->map->handle, LV2_TIME__barBeat);
62 d->time_beatsPerMinute= d->map->map(d->map->handle, LV2_TIME__beatsPerMinute);
63 d->time_speed = d->map->map(d->map->handle, LV2_TIME__speed);
64
65 d->atom_Blank = d->map->map(d->map->handle, LV2_ATOM__Blank);
66 d->atom_Float = d->map->map(d->map->handle, LV2_ATOM__Float);
67
68 return (LV2_Handle) d;
69 }
70
Della(int rate)71 Della::Della(int rate)
72 {
73 delay = new Delay( rate );
74 }
75
activate(LV2_Handle instance)76 void Della::activate(LV2_Handle instance)
77 {
78 }
79
deactivate(LV2_Handle instance)80 void Della::deactivate(LV2_Handle instance)
81 {
82 }
83
connect_port(LV2_Handle instance,uint32_t port,void * data)84 void Della::connect_port(LV2_Handle instance, uint32_t port, void *data)
85 {
86 Della* self = (Della*) instance;
87
88 switch (port) {
89 case DELLA_INPUT:
90 self->audioInput = (float*)data;
91 break;
92 case DELLA_OUTPUT:
93 self->audioOutput = (float*)data;
94 break;
95
96 case DELLA_TIME:
97 self->controlDelay = (float*)data;
98 break;
99 case DELLA_VOLUME:
100 self->controlVolume = (float*)data;
101 break;
102 case DELLA_FEEDBACK:
103 self->controlFeedback = (float*)data;
104 break;
105 case DELLA_ACTIVE:
106 self->controlActive = (float*)data;
107 break;
108
109 case DELLA_ATOM_IN:
110 self->atom_port = (LV2_Atom_Sequence*)data;
111 break;
112 }
113 }
114
run(LV2_Handle instance,uint32_t n_samples)115 void Della::run(LV2_Handle instance, uint32_t n_samples)
116 {
117 Della* self = (Della*) instance;
118
119 /// audio inputs
120 float* in = self->audioInput;
121 float* out = self->audioOutput;
122
123 /// control inputs
124 float active = *self->controlActive;
125 float delay = *self->controlDelay;
126 float volume = *self->controlVolume;
127 float feedback = *self->controlFeedback;
128
129 /// handle Atom messages
130 LV2_ATOM_SEQUENCE_FOREACH(self->atom_port, ev) {
131 if ( ev->body.type == self->atom_Blank ) {
132 const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body;
133 //printf("time_Position message\n" );
134 LV2_Atom* bpm = 0;
135 lv2_atom_object_get(obj,
136 self->time_beatsPerMinute, &bpm,
137 NULL);
138
139 if ( bpm ) { //&& bpm->type == self->atom_Float) {
140 // Tempo changed, update BPM
141 float bpmValue = ((LV2_Atom_Float*)bpm)->body;
142 //self->dspMasherL->bpm( bpmValue );
143 //printf("set bpm of %f\n", bpmValue );
144 self->delay->setBPM( bpmValue );
145 }
146
147 } else {
148 //printf("atom message: %s\n", self->unmap->unmap( self->unmap->handle, ev->body.type ) );
149 }
150 }
151
152 if ( active > 0.5 )
153 self->delay->active( true );
154 else
155 self->delay->active( false );
156
157 self->delay->setValue( delay );
158 self->delay->setVolume( volume );
159 self->delay->setFeedback( feedback );
160
161 self->delay->process( n_samples, in, out );
162 }
163
cleanup(LV2_Handle instance)164 void Della::cleanup(LV2_Handle instance)
165 {
166 delete ((Della*)instance)->delay;
167
168 delete ((Della*) instance);
169 }
170
extension_data(const char * uri)171 const void* Della::extension_data(const char* uri)
172 {
173 return NULL;
174 }
175