Add some foaf and doap info to zynadd.ttl
[zyn.git] / zynadd.c
blob1ed6c48c2329ef836c12ae24472d788a5f594307
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * Copyright (C) 2006,2007 Nedko Arnaudov <nedko@arnaudov.name>
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; version 2 of the License
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.
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 St, Fifth Floor, Boston, MA 02110-1301 USA.
19 *****************************************************************************/
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <assert.h>
25 #include <math.h>
26 #include <stdbool.h>
27 #include <lv2.h>
29 #include "common.h"
30 #include "lv2-miditype.h"
31 #include "lv2-midifunctions.h"
32 #include "zynadd.h"
33 #include "addsynth.h"
34 #include "lv2dynparam/lv2dynparam.h"
35 #include "lv2dynparam/lv2_rtmempool.h"
36 #include "lv2dynparam/plugin.h"
37 #include "list.h"
38 #include "zynadd_internal.h"
39 //#define LOG_LEVEL LOG_LEVEL_DEBUG
40 #include "log.h"
43 * The number of voices of additive synth for a single note
45 #define NUM_VOICES 8
47 #define LV2_PORT_MIDI_IN 0
48 #define LV2_PORT_OUTPUT_LEFT 1
49 #define LV2_PORT_OUTPUT_RIGHT 2
50 #define LV2_PORTS_COUNT 3
52 LV2_Handle
53 zynadd_instantiate(
54 const LV2_Descriptor * descriptor,
55 double sample_rate,
56 const char * bundle_path,
57 const LV2_Feature * const * host_features)
59 struct zynadd * zynadd_ptr;
60 struct lv2_rtsafe_memory_pool_provider * rtmempool_ptr;
61 const LV2_Feature * const * feature_ptr_ptr;
63 LOG_DEBUG("zynadd_create_plugin_instance() called.");
64 LOG_DEBUG("sample_rate = %f", sample_rate);
65 LOG_DEBUG("bundle_path = \"%s\"", bundle_path);
67 rtmempool_ptr = NULL;
69 feature_ptr_ptr = host_features;
70 while (*feature_ptr_ptr)
72 LOG_DEBUG("Host feature <%s> detected", (*feature_ptr_ptr)->URI);
74 if (strcmp((*feature_ptr_ptr)->URI, LV2_RTSAFE_MEMORY_POOL_URI) == 0)
76 rtmempool_ptr = (*feature_ptr_ptr)->data;
79 feature_ptr_ptr++;
82 if (rtmempool_ptr == NULL)
84 LOG_ERROR(LV2_RTSAFE_MEMORY_POOL_URI " extension is required");
85 goto fail;
88 zynadd_ptr = malloc(sizeof(struct zynadd));
89 if (zynadd_ptr == NULL)
91 goto fail;
94 zynadd_ptr->host_features = host_features;
96 zynadd_ptr->bundle_path = strdup(bundle_path);
97 if (zynadd_ptr->bundle_path == NULL)
99 goto fail_free_instance;
102 zynadd_ptr->ports = malloc(LV2_PORTS_COUNT * sizeof(void *));
103 if (zynadd_ptr->ports == NULL)
105 goto fail_free_bundle_path;
108 zynadd_ptr->sample_rate = sample_rate;
110 if (!zyn_addsynth_create(sample_rate, NUM_VOICES, &zynadd_ptr->synth))
112 goto fail_free_ports;
115 zynadd_ptr->synth_output_offset = SOUND_BUFFER_SIZE;
117 if (!zynadd_dynparam_init(zynadd_ptr))
119 LOG_ERROR("zynadd_dynparam_init() failed.");
120 goto fail_destroy_synth;
123 return (LV2_Handle)zynadd_ptr;
125 fail_destroy_synth:
126 zyn_addsynth_destroy(zynadd_ptr->synth);
128 fail_free_ports:
129 free(zynadd_ptr->ports);
131 fail_free_bundle_path:
132 free(zynadd_ptr->bundle_path);
134 fail_free_instance:
135 free(zynadd_ptr);
137 fail:
138 /* printf("zynadd_instantiate() failed.\n"); */
139 return NULL;
142 #define zynadd_ptr ((struct zynadd *)instance)
144 /* The run() callback. This is the function that gets called by the host
145 when it wants to run the plugin. The parameter is the number of sample
146 frames to process. */
147 void
148 zynadd_run(
149 LV2_Handle instance,
150 uint32_t samples_count)
152 LV2_MIDIState midi;
153 double event_time;
154 uint32_t event_size;
155 unsigned char* event;
156 uint32_t now;
157 uint32_t fill;
158 uint32_t synth_output_offset_future;
159 /* char fake_event[2]; */
161 /* printf("%u\n", sample_count); fflush(stdout); */
163 midi.midi = (LV2_MIDI *)zynadd_ptr->ports[LV2_PORT_MIDI_IN];
164 midi.frame_count = samples_count;
165 midi.position = 0;
167 now = 0;
168 event_time = -1.0;
169 event = NULL;
170 event_size = 0;
172 while (now < samples_count)
174 fill = samples_count - now;
175 synth_output_offset_future = zynadd_ptr->synth_output_offset;
177 if (synth_output_offset_future == SOUND_BUFFER_SIZE)
179 synth_output_offset_future = 0;
182 if (fill > SOUND_BUFFER_SIZE - synth_output_offset_future)
184 fill = SOUND_BUFFER_SIZE - synth_output_offset_future;
187 while (event_time < now + fill)
189 if (event_time < 0) /* we need to extract next event */
191 lv2midi_get_event(&midi, &event_time, &event_size, &event);
192 /* if (event[0] == 0x90) */
193 /* { */
194 /* event_time = 0; */
195 /* fake_event[0] = 0x90; */
196 /* fake_event[1] = 69; */
197 /* } */
198 lv2midi_step(&midi);
201 if (event_time >= 0 && event_time < now + fill)
203 /* printf("%02X\n", (unsigned int)event[0]); */
204 if (event_size == 3)
206 switch (event[0] & 0xF0)
208 case 0x90: /* note on */
209 zyn_addsynth_note_on(zynadd_ptr->synth, event[1], event[2]);
210 break;
211 case 0x80: /* note off */
212 zyn_addsynth_note_off(zynadd_ptr->synth, event[1]);
213 break;
217 event_time = -1.0;
221 if (zynadd_ptr->synth_output_offset == SOUND_BUFFER_SIZE)
223 zyn_addsynth_get_audio_output(zynadd_ptr->synth, zynadd_ptr->synth_output_left, zynadd_ptr->synth_output_right);
224 zynadd_ptr->synth_output_offset = 0;
227 assert(zynadd_ptr->synth_output_offset == synth_output_offset_future);
229 memcpy((float *)(zynadd_ptr->ports[LV2_PORT_OUTPUT_LEFT]) + now, zynadd_ptr->synth_output_left, fill * sizeof(float));
230 memcpy((float *)(zynadd_ptr->ports[LV2_PORT_OUTPUT_RIGHT]) + now, zynadd_ptr->synth_output_right, fill * sizeof(float));
232 zynadd_ptr->synth_output_offset += fill;
233 assert(zynadd_ptr->synth_output_offset <= SOUND_BUFFER_SIZE);
234 now += fill;
235 assert(now <= samples_count);
239 void
240 zynadd_cleanup(
241 LV2_Handle instance)
243 /* printf("zynadd_cleanup\n"); */
244 zynadd_dynparam_uninit(zynadd_ptr);
245 zyn_addsynth_destroy(zynadd_ptr->synth);
246 free(zynadd_ptr->ports);
247 free(zynadd_ptr->bundle_path);
248 free(zynadd_ptr);
251 void
252 zynadd_connect_port(
253 LV2_Handle instance,
254 uint32_t port,
255 void * data_location)
257 if (port >= LV2_PORTS_COUNT)
259 assert(0);
260 return;
263 zynadd_ptr->ports[port] = data_location;
266 const void *
267 zynadd_extension_data(
268 const char * URI)
270 if (strcmp(URI, LV2DYNPARAM_URI) == 0)
272 return get_lv2dynparam_plugin_extension_data();
275 return NULL;