1 /***************************************************************************
2 * Copyright (C) 2011 by Pere Ràfols Soler *
3 * sapista2@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 *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21 /***************************************************************************
22 This file is the implementation of the BassUp plugin
23 This plugin is inside the Sapista Plugins Bundle
24 ****************************************************************************/
25
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <math.h>
29
30 #include <lv2/lv2plug.in/ns/lv2core/lv2.h>
31 #include "dsp/filter.h"
32
33 #define BASSUP_URI "http://eq10q.sourceforge.net/bassup"
34 #define PORT_OUTPUT 0
35 #define PORT_INPUT 1
36 #define PORT_AMOUNT 2
37
38 #define NUM_OF_HPF_STAGES 4
39 #define HPF_FREQ 50.0f
40 #define LPF_FREQ 200.0f
41
42 typedef struct {
43 //Plugin ports
44 float *amount;
45 float *output;
46 const float *input;
47
48 //Plugin Internal data
49 float sample_rate;
50 Filter *LPF_fil, *HPF_fil[4];
51 Buffers LPF_buf, HPF_buf[4];
52 } BassUp;
53
cleanupBassUp(LV2_Handle instance)54 static void cleanupBassUp(LV2_Handle instance)
55 {
56 BassUp *plugin = (BassUp *)instance;
57 int i;
58 for(i=0; i<NUM_OF_HPF_STAGES; i++)
59 {
60 FilterClean(plugin->HPF_fil[i]);
61 }
62 FilterClean(plugin->LPF_fil);
63 free(instance);
64 }
65
connectPortBassUp(LV2_Handle instance,uint32_t port,void * data)66 static void connectPortBassUp(LV2_Handle instance, uint32_t port, void *data)
67 {
68 BassUp *plugin = (BassUp *)instance;
69 switch (port) {
70 case PORT_AMOUNT:
71 plugin->amount = (float*)data;
72 break;
73 case PORT_INPUT:
74 plugin->input = (const float*)data;
75 break;
76 case PORT_OUTPUT:
77 plugin->output = (float*)data;
78 break;
79 }
80 }
81
instantiateBassUp(const LV2_Descriptor * descriptor,double s_rate,const char * path,const LV2_Feature * const * features)82 static LV2_Handle instantiateBassUp(const LV2_Descriptor *descriptor, double s_rate, const char *path, const LV2_Feature *const * features)
83 {
84 BassUp *plugin_data = (BassUp *)malloc(sizeof(BassUp));
85 plugin_data->sample_rate = s_rate;
86 int i;
87 for(i =0; i<NUM_OF_HPF_STAGES; i++)
88 {
89 plugin_data->HPF_fil[i] = FilterInit(s_rate);
90 flushBuffers(&plugin_data->HPF_buf[i]);
91 calcCoefs(plugin_data->HPF_fil[i], 0.0, HPF_FREQ, 0.75, F_HPF_ORDER_2, 1.0);
92 }
93 plugin_data->LPF_fil = FilterInit(s_rate);
94 flushBuffers(&plugin_data->LPF_buf);
95 calcCoefs(plugin_data->LPF_fil, 0.0, LPF_FREQ, 0.75, F_LPF_ORDER_2, 1.0);
96 return (LV2_Handle)plugin_data;
97 }
98
99 #define DENORMAL_TO_ZERO_FLOAT(x) if (fabs(x) < (1e-30)) x = 0.f; //Min float is 1.1754943e-38
runBassUp(LV2_Handle instance,uint32_t sample_count)100 static void runBassUp(LV2_Handle instance, uint32_t sample_count)
101 {
102 BassUp *plugin_data = (BassUp *)instance;
103 const float amount = *(plugin_data->amount);
104 double bassSignal;
105
106 for (uint32_t i = 0; i < sample_count; ++i)
107 {
108 //bassSignal
109 bassSignal = (double)fabs(plugin_data->input[i]);
110
111 //Apply Filters
112 int j;
113 for(j=0; j<NUM_OF_HPF_STAGES; j++)
114 {
115 computeFilter(plugin_data->HPF_fil[j], &plugin_data->HPF_buf[j], &bassSignal);
116 }
117 computeFilter(plugin_data->LPF_fil, &plugin_data->LPF_buf, &bassSignal);
118
119 //Output
120 plugin_data->output[i] = (float)bassSignal*amount + plugin_data->input[i];
121 }
122 }
123
124 static const LV2_Descriptor bassupDescriptor = {
125 BASSUP_URI,
126 instantiateBassUp,
127 connectPortBassUp,
128 NULL,
129 runBassUp,
130 NULL,
131 cleanupBassUp,
132 NULL
133 };
134
135 LV2_SYMBOL_EXPORT
lv2_descriptor(uint32_t index)136 const LV2_Descriptor *lv2_descriptor(uint32_t index)
137 {
138 switch (index) {
139 case 0:
140 return &bassupDescriptor;
141 default:
142 return NULL;
143 }
144 }
145