root/lv2filter.c

Revision 6138b266a4a6d8c7ca668cbd2de4aa4f2ee4da59, 6.7 KB (checked in by Nedko Arnaudov <nedko@…>, 14 months ago)

Stereo plugin

  • Property mode set to 100644
Line 
1/* -*- Mode: C ; c-basic-offset: 2 -*- */
2/*****************************************************************************
3 *
4 *   Copyright (C) 2006,2007,2008,2009 Nedko Arnaudov <nedko@arnaudov.name>
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; version 2 of the License
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 St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 *****************************************************************************/
20
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>
28
29#include "lv2filter.h"
30#include "filter.h"
31#define LOG_LEVEL LOG_LEVEL_ERROR
32#include "log.h"
33
34#define BANDS_COUNT 4
35
36#define LV2_PORT_MONO_AUDIO_IN       0
37#define LV2_PORT_MONO_AUDIO_OUT      1
38#define LV2_MONO_AUDIO_PORT_COUNT    2
39#define LV2_PORTS_COUNT_MONO         (LV2_MONO_AUDIO_PORT_COUNT + GLOBAL_PARAMETERS_COUNT + BANDS_COUNT * BAND_PARAMETERS_COUNT)
40
41#define LV2_PORT_LEFT_AUDIO_IN       0
42#define LV2_PORT_RIGHT_AUDIO_IN      1
43#define LV2_PORT_LEFT_AUDIO_OUT      2
44#define LV2_PORT_RIGHT_AUDIO_OUT     3
45#define LV2_STEREO_AUDIO_PORT_COUNT  4
46#define LV2_PORTS_COUNT_STEREO       (LV2_STEREO_AUDIO_PORT_COUNT + GLOBAL_PARAMETERS_COUNT + BANDS_COUNT * BAND_PARAMETERS_COUNT)
47
48struct lv2filter
49{
50  bool stereo;
51  filter_handle filter;
52  filter_handle filter_right;
53  char * bundle_path;
54  const float * audio_in;
55  const float * audio_in_right;
56  float * audio_out;
57  float * audio_out_right;
58  const LV2_Feature * const * host_features;
59};
60
61LV2_Handle
62lv2filter_instantiate(
63  const LV2_Descriptor * descriptor,
64  double sample_rate,
65  const char * bundle_path,
66  const LV2_Feature * const * host_features)
67{
68  struct lv2filter * lv2filter_ptr;
69  const LV2_Feature * const * feature_ptr_ptr;
70
71  LOG_DEBUG("lv2filter_create_plugin_instance() called.");
72  LOG_DEBUG("uri = \"%s\"", descriptor->URI);
73  LOG_DEBUG("sample_rate = %f", sample_rate);
74  LOG_DEBUG("bundle_path = \"%s\"", bundle_path);
75
76  feature_ptr_ptr = host_features;
77  while (*feature_ptr_ptr)
78  {
79    LOG_DEBUG("Host feature <%s> detected", (*feature_ptr_ptr)->URI);
80
81    feature_ptr_ptr++;
82  }
83
84  lv2filter_ptr = malloc(sizeof(struct lv2filter));
85  if (lv2filter_ptr == NULL)
86  {
87    goto fail;
88  }
89
90  if (strcmp(descriptor->URI, LV2FILTER_STEREO_URI) == 0)
91  {
92    lv2filter_ptr->stereo = true;
93  }
94  else if (strcmp(descriptor->URI, LV2FILTER_MONO_URI) == 0)
95  {
96    lv2filter_ptr->stereo = false;
97  }
98  else
99  {
100    assert(false);
101    goto fail_free_instance;
102  }
103
104  lv2filter_ptr->host_features = host_features;
105
106  lv2filter_ptr->bundle_path = strdup(bundle_path);
107  if (lv2filter_ptr->bundle_path == NULL)
108  {
109    goto fail_free_instance;
110  }
111
112  if (!filter_create(sample_rate, BANDS_COUNT, &lv2filter_ptr->filter))
113  {
114    goto fail_free_bundle_path;
115  }
116
117  if (lv2filter_ptr->stereo)
118  {
119    if (!filter_create(sample_rate, BANDS_COUNT, &lv2filter_ptr->filter_right))
120    {
121      goto fail_destroy_filter;
122    }
123  }
124
125  return (LV2_Handle)lv2filter_ptr;
126
127fail_destroy_filter:
128  filter_destroy(lv2filter_ptr->filter);
129
130fail_free_bundle_path:
131  free(lv2filter_ptr->bundle_path);
132
133fail_free_instance:
134  free(lv2filter_ptr);
135
136fail:
137  return NULL;
138}
139
140#define lv2filter_ptr ((struct lv2filter *)instance)
141
142/* The run() callback. This is the function that gets called by the host
143   when it wants to run the plugin. The parameter is the number of sample
144   frames to process. */
145void
146lv2filter_run(
147  LV2_Handle instance,
148  uint32_t samples_count)
149{
150  LOG_DEBUG("lv2filter_run");
151  filter_run(
152    lv2filter_ptr->filter,
153    lv2filter_ptr->audio_in,
154    lv2filter_ptr->audio_out,
155    samples_count);
156
157  if (lv2filter_ptr->stereo)
158  {
159    filter_run(
160      lv2filter_ptr->filter_right,
161      lv2filter_ptr->audio_in_right,
162      lv2filter_ptr->audio_out_right,
163      samples_count);
164  }
165}
166
167void
168lv2filter_cleanup(
169  LV2_Handle instance)
170{
171  filter_destroy(lv2filter_ptr->filter);
172
173  if (lv2filter_ptr->stereo)
174  {
175    filter_destroy(lv2filter_ptr->filter_right);
176  }
177
178  free(lv2filter_ptr->bundle_path);
179  free(lv2filter_ptr);
180}
181
182void
183lv2filter_connect_port(
184  LV2_Handle instance,
185  uint32_t port,
186  void * data_location)
187{
188  LOG_DEBUG("lv2filter_connect_port %u %p", (unsigned int)port, data_location);
189
190  if (lv2filter_ptr->stereo)
191  {
192    if (port >= LV2_PORTS_COUNT_STEREO)
193    {
194      assert(0);
195      return;
196    }
197
198    if (port == LV2_PORT_LEFT_AUDIO_IN)
199    {
200      lv2filter_ptr->audio_in = data_location;
201    }
202    else if (port == LV2_PORT_LEFT_AUDIO_OUT)
203    {
204      lv2filter_ptr->audio_out = data_location;
205    }
206    else if (port == LV2_PORT_RIGHT_AUDIO_IN)
207    {
208      lv2filter_ptr->audio_in_right = data_location;
209    }
210    else if (port == LV2_PORT_RIGHT_AUDIO_OUT)
211    {
212      lv2filter_ptr->audio_out_right = data_location;
213    }
214    else
215    {
216      assert(port >= LV2_STEREO_AUDIO_PORT_COUNT);
217      port -= LV2_STEREO_AUDIO_PORT_COUNT;
218      if (port < GLOBAL_PARAMETERS_COUNT)
219      {
220        filter_connect_global_parameter(lv2filter_ptr->filter, port, data_location);
221        filter_connect_global_parameter(lv2filter_ptr->filter_right, port, data_location);
222      }
223      else
224      {
225        assert(port >= GLOBAL_PARAMETERS_COUNT);
226        port -= GLOBAL_PARAMETERS_COUNT;
227
228        filter_connect_band_parameter(lv2filter_ptr->filter, port / BANDS_COUNT, port % BANDS_COUNT, data_location);
229        filter_connect_band_parameter(lv2filter_ptr->filter_right, port / BANDS_COUNT, port % BANDS_COUNT, data_location);
230      }
231    }
232  }
233  else
234  {
235    if (port >= LV2_PORTS_COUNT_MONO)
236    {
237      assert(0);
238      return;
239    }
240
241    if (port == LV2_PORT_MONO_AUDIO_IN)
242    {
243      lv2filter_ptr->audio_in = data_location;
244    }
245    else if (port == LV2_PORT_MONO_AUDIO_OUT)
246    {
247      lv2filter_ptr->audio_out = data_location;
248    }
249    else
250    {
251      port -= LV2_MONO_AUDIO_PORT_COUNT;
252      if (port < GLOBAL_PARAMETERS_COUNT)
253      {
254        filter_connect_global_parameter(lv2filter_ptr->filter, port, data_location);
255      }
256      else
257      {
258        port -= GLOBAL_PARAMETERS_COUNT;
259
260        filter_connect_band_parameter(lv2filter_ptr->filter, port / BANDS_COUNT, port % BANDS_COUNT, data_location);
261      }
262    }
263  }
264}
265
266const void *
267lv2filter_extension_data(
268  const char * URI)
269{
270  return NULL;
271}
Note: See TracBrowser for help on using the browser.