1 /*
2 wavedata.h - Structures to represent a set of wavetables
3
4 Copyright (C) 2003 Mike Rawes
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; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #ifndef blop_wavedata_h
22 #define blop_wavedata_h
23
24 #include <ladspa.h>
25 #include <config.h>
26 #include "math_func.h"
27 #include "interpolate.h"
28 #include "common.h"
29
30 /* Functions identifying wavedata dlls */
31 #define BLOP_DLSYM_SAWTOOTH "blop_get_sawtooth"
32 #define BLOP_DLSYM_SQUARE "blop_get_square"
33 #define BLOP_DLSYM_PARABOLA "blop_get_parabola"
34
35 /*
36 * Structure holding a single segment of sample data
37 * along with information relating to playback.
38 */
39 typedef struct
40 {
41 unsigned long sample_count; /* Sample count */
42 LADSPA_Data * samples_lf; /* Sample data played back at amplitude
43 inversely proportional to frequency */
44 LADSPA_Data * samples_hf; /* Sample data played back at amplitude
45 proportional to frequency */
46 unsigned long harmonics; /* Max harmonic content of sample data */
47
48 LADSPA_Data phase_scale_factor; /* Phase scale factor for playback */
49 LADSPA_Data min_frequency; /* Minimum playback frequency */
50 LADSPA_Data max_frequency; /* Maximum playback frequency */
51 LADSPA_Data range_scale_factor; /* Blend scale factor for cross fading */
52 } Wavetable;
53
54 /*
55 * Structure holding the wavetable data and playback state
56 */
57 typedef struct
58 {
59 void * data_handle; /* Data DLL handle */
60 unsigned long table_count; /* Number of wavetables in wavedata */
61 Wavetable ** tables; /* One or more wavetables, plus pair of
62 extra tables for frequency extremes */
63 unsigned long * lookup; /* Wavetable lookup vector */
64 unsigned long lookup_max; /* For clipping lookup indices */
65
66 LADSPA_Data sample_rate; /* Sample rate */
67 LADSPA_Data nyquist; /* Nyquist rate (sample_rate / 2) */
68
69 /* Playback state */
70 LADSPA_Data frequency; /* Current playback frequency */
71 LADSPA_Data abs_freq; /* Absolute playback frequency */
72 LADSPA_Data xfade; /* Crossfade factor for fading */
73 Wavetable * table; /* Wavetable to playback */
74 } Wavedata;
75
76 #ifdef __cplusplus
77 extern "C" {
78 #endif
79
80 int
81 wavedata_load (Wavedata * w,
82 const char * wdat_descriptor_name,
83 unsigned long sample_rate);
84
85 void
86 wavedata_unload (Wavedata * w);
87
88 /*****************************************************************************
89 * Description: Get interpolated sample from current wavetable in wavedata
90 * at given phase offset
91 *
92 * Arguments: w Wavedata containing playback state and data
93 * phase Phase offset [0.0, sample_rate]
94 *
95 * Returns: Interpolated sample
96 *
97 * Notes: Cubic (or quintic) interpolation requires four consecutive
98 * samples for operation:
99 *
100 * phase
101 * :
102 * p1 p0 : n0 n1
103 * | | x | |
104 * : :
105 * <-o->
106 * :
107 * interval
108 *
109 * Phase values less than one make p0 the first sample in
110 * the table - p1 will be the last sample, as a previous
111 * sample does not exist. To avoid checking for this case,
112 * a copy of the last sample is stored before the first
113 * sample in each table.
114 * Likewise, if the phase means p0 is the last sample, n0
115 * and n1 will be the first and second samples respectively.
116 * Copies of these samples are stored after the last sample
117 * in each table.
118 *
119 *****************************************************************************/
120 static inline LADSPA_Data
wavedata_get_sample(Wavedata * w,LADSPA_Data phase)121 wavedata_get_sample (Wavedata * w,
122 LADSPA_Data phase)
123 {
124 LADSPA_Data * samples_hf = w->table->samples_hf;
125 LADSPA_Data * samples_lf = w->table->samples_lf;
126 LADSPA_Data p1, p0, n0, n1;
127 LADSPA_Data phase_f;
128 long int index;
129
130 /* Scale phase to map to position in wavetable */
131 phase *= w->table->phase_scale_factor;
132
133 /* Get position of first contributing sample (p1) */
134 index = LRINTF ((float) phase - 0.5f);
135 phase_f = (LADSPA_Data) index;
136
137 index %= w->table->sample_count;
138
139 /* Cross-fade table pairs */
140 /* Previous two samples */
141 p1 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
142 index++;
143 p0 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
144 index++;
145 /* Next two samples */
146 n0 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
147 index++;
148 n1 = w->xfade * (samples_lf[index] - samples_hf[index]) + samples_hf[index];
149
150 /* Return interpolated sample */
151 return interpolate_cubic (phase - phase_f, p1, p0, n0, n1);
152 }
153
154 /*****************************************************************************
155 * Description: Get wavetable to use for playback frequency.
156 *
157 * Arguments: w Wavedata object (contains all table info)
158 * frequency Playback frequency
159 *
160 * Notes: The lookup vector used to determine the wavetable
161 * is indexed by harmonic number.
162 *
163 * The maximum playback frequency for a wavetable is
164 * determined by its harmonic content and the sample rate,
165 * and equals sample_rate / 2 / max_harmonic_in_table.
166 *
167 *****************************************************************************/
168 static inline void
wavedata_get_table(Wavedata * w,LADSPA_Data frequency)169 wavedata_get_table (Wavedata * w,
170 LADSPA_Data frequency)
171 {
172 unsigned long harmonic;
173
174 w->frequency = frequency;
175 w->abs_freq = (LADSPA_Data) FABSF ((float) frequency);
176
177 /* Get highest harmonic possible in frequency */
178 harmonic = LRINTF (w->nyquist / w->abs_freq - 0.5f);
179
180 /* Clip so lookup is within bounds */
181 if (harmonic > w->lookup_max)
182 harmonic = w->lookup_max;
183
184 /* Set playback table */
185 w->table = w->tables[w->lookup[harmonic]];
186
187 /* Get cross fade factor */
188 w->xfade = f_max (w->table->max_frequency - w->abs_freq, 0.0f) * w->table->range_scale_factor;
189 w->xfade = f_min (w->xfade, 1.0f);
190 }
191
192 #ifdef __cplusplus
193 } /* extern "C" { */
194 #endif
195
196 #endif /* blop_wavedata_h */
197