Imported Upstream version 0.10.23
[profile/ivi/gst-plugins-bad.git] / gst / legacyresample / resample.c
1 /* Resampling library
2  * Copyright (C) <2001> David A. Schleef <ds@schleef.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24
25 #include <string.h>
26 #include <math.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <limits.h>
30
31 #include "resample.h"
32 #include "buffer.h"
33 #include "debug.h"
34
35 GST_DEBUG_CATEGORY (libaudioresample_debug);
36
37 void
38 resample_init (void)
39 {
40   static int inited = 0;
41
42   if (!inited) {
43     inited = 1;
44     GST_DEBUG_CATEGORY_INIT (libaudioresample_debug, "libaudioresample", 0,
45         "audio resampling library");
46
47   }
48 }
49
50 ResampleState *
51 resample_new (void)
52 {
53   ResampleState *r;
54
55   r = malloc (sizeof (ResampleState));
56   memset (r, 0, sizeof (ResampleState));
57
58   r->filter_length = 16;
59
60   r->i_start = 0;
61   if (r->filter_length & 1) {
62     r->o_start = 0;
63   } else {
64     r->o_start = r->o_inc * 0.5;
65   }
66
67   r->queue = audioresample_buffer_queue_new ();
68   r->out_tmp = malloc (10000 * sizeof (double));
69
70   r->need_reinit = 1;
71
72   return r;
73 }
74
75 void
76 resample_free (ResampleState * r)
77 {
78   if (r->buffer) {
79     free (r->buffer);
80   }
81   if (r->ft) {
82     functable_free (r->ft);
83   }
84   if (r->queue) {
85     audioresample_buffer_queue_free (r->queue);
86   }
87   if (r->out_tmp) {
88     free (r->out_tmp);
89   }
90
91   free (r);
92 }
93
94 static void
95 resample_buffer_free (AudioresampleBuffer * buffer, void *priv)
96 {
97   if (buffer->priv2) {
98     ((void (*)(void *)) buffer->priv2) (buffer->priv);
99   }
100 }
101
102 /*
103  * free_func: a function that frees the given closure.  If NULL, caller is
104  *            responsible for freeing.
105  */
106 void
107 resample_add_input_data (ResampleState * r, void *data, int size,
108     void (*free_func) (void *), void *closure)
109 {
110   AudioresampleBuffer *buffer;
111
112   RESAMPLE_DEBUG ("data %p size %d", data, size);
113
114   buffer = audioresample_buffer_new_with_data (data, size);
115   buffer->free = resample_buffer_free;
116   buffer->priv2 = (void *) free_func;
117   buffer->priv = closure;
118
119   audioresample_buffer_queue_push (r->queue, buffer);
120 }
121
122 void
123 resample_input_flush (ResampleState * r)
124 {
125   RESAMPLE_DEBUG ("flush");
126
127   audioresample_buffer_queue_flush (r->queue);
128   r->buffer_filled = 0;
129   r->need_reinit = 1;
130 }
131
132 void
133 resample_input_pushthrough (ResampleState * r)
134 {
135   AudioresampleBuffer *buffer;
136   int filter_bytes;
137   int buffer_filled;
138
139   if (r->sample_size == 0)
140     return;
141
142   filter_bytes = r->filter_length * r->sample_size;
143   buffer_filled = r->buffer_filled;
144
145   RESAMPLE_DEBUG ("pushthrough filter_bytes %d, filled %d",
146       filter_bytes, buffer_filled);
147
148   /* if we have no pending samples, we don't need to do anything. */
149   if (buffer_filled <= 0)
150     return;
151
152   /* send filter_length/2 number of samples so we can get to the
153    * last queued samples */
154   buffer = audioresample_buffer_new_and_alloc (filter_bytes / 2);
155   memset (buffer->data, 0, buffer->length);
156
157   RESAMPLE_DEBUG ("pushthrough %u", buffer->length);
158
159   audioresample_buffer_queue_push (r->queue, buffer);
160 }
161
162 void
163 resample_input_eos (ResampleState * r)
164 {
165   RESAMPLE_DEBUG ("EOS");
166   resample_input_pushthrough (r);
167   r->eos = 1;
168 }
169
170 int
171 resample_get_output_size_for_input (ResampleState * r, int size)
172 {
173   int outsize;
174   double outd;
175   int avail;
176   int filter_bytes;
177   int buffer_filled;
178
179   if (r->sample_size == 0)
180     return 0;
181
182   filter_bytes = r->filter_length * r->sample_size;
183   buffer_filled = filter_bytes / 2 - r->buffer_filled / 2;
184
185   avail =
186       audioresample_buffer_queue_get_depth (r->queue) + size - buffer_filled;
187
188   RESAMPLE_DEBUG ("avail %d, o_rate %f, i_rate %f, filter_bytes %d, filled %d",
189       avail, r->o_rate, r->i_rate, filter_bytes, buffer_filled);
190   if (avail <= 0)
191     return 0;
192
193   outd = (double) avail *r->o_rate / r->i_rate;
194
195   outsize = (int) floor (outd);
196
197   /* round off for sample size */
198   outsize -= outsize % r->sample_size;
199
200   return outsize;
201 }
202
203 int
204 resample_get_input_size_for_output (ResampleState * r, int size)
205 {
206   int outsize;
207   double outd;
208   int avail;
209
210   if (r->sample_size == 0)
211     return 0;
212
213   avail = size;
214
215   RESAMPLE_DEBUG ("size %d, o_rate %f, i_rate %f", avail, r->o_rate, r->i_rate);
216   outd = (double) avail *r->i_rate / r->o_rate;
217
218   outsize = (int) ceil (outd);
219
220   /* round off for sample size */
221   outsize -= outsize % r->sample_size;
222
223   return outsize;
224 }
225
226 int
227 resample_get_output_size (ResampleState * r)
228 {
229   return resample_get_output_size_for_input (r, 0);
230 }
231
232 int
233 resample_get_output_data (ResampleState * r, void *data, int size)
234 {
235   r->o_buf = data;
236   r->o_size = size;
237
238   if (size == 0)
239     return 0;
240
241   switch (r->method) {
242     case 0:
243       resample_scale_ref (r);
244       break;
245     case 1:
246       resample_scale_functable (r);
247       break;
248     default:
249       break;
250   }
251
252   return size - r->o_size;
253 }
254
255 void
256 resample_set_filter_length (ResampleState * r, int length)
257 {
258   r->filter_length = length;
259   r->need_reinit = 1;
260 }
261
262 void
263 resample_set_input_rate (ResampleState * r, double rate)
264 {
265   r->i_rate = rate;
266   r->need_reinit = 1;
267 }
268
269 void
270 resample_set_output_rate (ResampleState * r, double rate)
271 {
272   r->o_rate = rate;
273   r->need_reinit = 1;
274 }
275
276 void
277 resample_set_n_channels (ResampleState * r, int n_channels)
278 {
279   r->n_channels = n_channels;
280   r->sample_size = r->n_channels * resample_format_size (r->format);
281   r->need_reinit = 1;
282 }
283
284 void
285 resample_set_format (ResampleState * r, ResampleFormat format)
286 {
287   r->format = format;
288   r->sample_size = r->n_channels * resample_format_size (r->format);
289   r->need_reinit = 1;
290 }
291
292 void
293 resample_set_method (ResampleState * r, int method)
294 {
295   r->method = method;
296   r->need_reinit = 1;
297 }
298
299 int
300 resample_format_size (ResampleFormat format)
301 {
302   switch (format) {
303     case RESAMPLE_FORMAT_S16:
304       return 2;
305     case RESAMPLE_FORMAT_S32:
306     case RESAMPLE_FORMAT_F32:
307       return 4;
308     case RESAMPLE_FORMAT_F64:
309       return 8;
310   }
311   return 0;
312 }