source: roaraudio/libroardsp/resampler_poly3.c @ 5961:06e7fd9e4c25

Last change on this file since 5961:06e7fd9e4c25 was 5961:06e7fd9e4c25, checked in by phi, 10 years ago

Updates of copyright and license headers

File size: 7.2 KB
Line 
1//resampler_poly3.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2010-2014
5 *      Copyright (C) Hans-Kristian 'maister' Arntzen - 2010
6 *
7 *  This file is part of libroar a part of RoarAudio,
8 *  a cross-platform sound system for both, home and professional use.
9 *  See README for details.
10 *
11 *  This file is free software; you can redistribute it and/or modify
12 *  it under the terms of the GNU General Public License version 3
13 *  as published by the Free Software Foundation.
14 *
15 *  libroar is distributed in the hope that it will be useful,
16 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 *  GNU General Public License for more details.
19 *
20 *  You should have received a copy of the GNU General Public License
21 *  along with this software; see the file COPYING.  If not, write to
22 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
23 *  Boston, MA 02110-1301, USA.
24 *
25 *  NOTE for everyone want's to change something and send patches:
26 *  read README and HACKING! There a addition information on
27 *  the license of this document you need to read before you send
28 *  any patches.
29 *
30 *  NOTE for uses of non-GPL (LGPL,...) software using libesd, libartsc
31 *  or libpulse*:
32 *  The libs libroaresd, libroararts and libroarpulse link this lib
33 *  and are therefore GPL. Because of this it may be illigal to use
34 *  them with any software that uses libesd, libartsc or libpulse*.
35 */
36
37#include "libroardsp.h"
38
39int roar_conv_poly3_8 (int8_t * out, int8_t * in, size_t olen, size_t ilen, int channels) {
40 float ratio = (float)olen / (float)ilen;
41 int8_t *ip;
42 int c, x;
43 float pos_in;
44 float poly[3];
45 float y[3];
46 float x_val;
47 int_least16_t temp;
48
49 /* Can't create poly out of less than 3 samples in each channel. */
50 if ( ilen < 3 * channels )
51  return -1;
52
53 ip = roar_mm_malloc(ilen * sizeof(int8_t));
54 if ( ip == NULL )
55  return -1;
56
57 memcpy(ip, in, ilen * sizeof(int8_t));
58
59 olen /= channels;
60
61 for (x = 0; x < olen; x++) {
62  for (c = 0; c < channels; c++) {
63   pos_in = (float)x / ratio;
64
65   if ( (int)pos_in == 0 ) {
66    y[0] = ip[0 * channels + c];
67    y[1] = ip[1 * channels + c];
68    y[2] = ip[2 * channels + c];
69    x_val = pos_in;
70    roar_math_mkpoly_3x3(poly, y);
71   } else if ( (int)pos_in + 1 >= ilen/channels ) {
72    /* If we're at the end of the block, we will need to interpolate against a value that is not yet known.
73     * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */
74    y[0] = ip[((int)pos_in - 1) * channels + c];
75    y[1] = ip[((int)pos_in    ) * channels + c];
76
77    // we create a 2x2 poly here and set the 3rd coefficient to zero to build a 3x3 poly
78    roar_math_mkpoly_2x2(poly, y);
79    poly[2] = 0;
80    x_val = pos_in - (int)pos_in + 1.0;
81   } else {
82    y[0] = ip[((int)pos_in - 1) * channels + c];
83    y[1] = ip[((int)pos_in    ) * channels + c];
84    y[2] = ip[((int)pos_in + 1) * channels + c];
85    x_val = pos_in - (int)pos_in + 1.0;
86    roar_math_mkpoly_3x3(poly, y);
87   }
88
89
90   temp = (float)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5);
91   /* temp could be out of bounds, so need to check this */
92   if ( temp > 0x7E ) {
93    out[x * channels + c] =  0x7E;
94   } else if (temp < -0x7F) {
95    out[x * channels + c] = -0x7F;
96   } else {
97    out[x * channels + c] = (int8_t)temp;
98   }
99  }
100 }
101
102 roar_mm_free(ip);
103 return 0;
104}
105
106int roar_conv_poly3_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen, int channels) {
107 float ratio = (float)olen / (float)ilen;
108 int16_t *ip;
109 int c, x;
110 float pos_in;
111 float poly[3];
112 float y[3];
113 float x_val;
114 int_least32_t temp;
115
116 /* Can't create poly out of less than 3 samples in each channel. */
117 if ( ilen < 3 * channels )
118  return -1;
119
120 ip = roar_mm_malloc(ilen * sizeof(int16_t));
121 if ( ip == NULL )
122  return -1;
123
124 memcpy(ip, in, ilen * sizeof(int16_t));
125
126 olen /= channels;
127
128 for (x = 0; x < olen; x++) {
129  for (c = 0; c < channels; c++) {
130   pos_in = (float)x / ratio;
131
132   if ( (int)pos_in == 0 ) {
133    y[0] = ip[0 * channels + c];
134    y[1] = ip[1 * channels + c];
135    y[2] = ip[2 * channels + c];
136    x_val = pos_in;
137    roar_math_mkpoly_3x3(poly, y);
138   } else if ( (int)pos_in + 1 >= ilen/channels ) {
139    /* If we're at the end of the block, we will need to interpolate against a value that is not yet known.
140     * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */
141    y[0] = ip[((int)pos_in - 1) * channels + c];
142    y[1] = ip[((int)pos_in    ) * channels + c];
143
144    // we create a 2x2 poly here and set the 3rd coefficient to zero to build a 3x3 poly
145    roar_math_mkpoly_2x2(poly, y);
146    poly[2] = 0;
147    x_val = pos_in - (int)pos_in + 1.0;
148   } else {
149    y[0] = ip[((int)pos_in - 1) * channels + c];
150    y[1] = ip[((int)pos_in    ) * channels + c];
151    y[2] = ip[((int)pos_in + 1) * channels + c];
152    x_val = pos_in - (int)pos_in + 1.0;
153    roar_math_mkpoly_3x3(poly, y);
154   }
155
156
157   temp = (float)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5);
158   /* temp could be out of bounds, so need to check this */
159   if (temp > 0x7FFE ) {
160    out[x * channels + c] =  0x7FFE;
161   } else if (temp < -0x7FFF) {
162    out[x * channels + c] = -0x7FFF;
163   } else {
164    out[x * channels + c] = (int16_t)temp;
165   }
166  }
167 }
168
169 roar_mm_free(ip);
170 return 0;
171}
172
173int roar_conv_poly3_32 (int32_t * out, int32_t * in, size_t olen, size_t ilen, int channels) {
174 float ratio = (float)olen / (float)ilen;
175 int32_t *ip;
176 int c, x;
177 float pos_in;
178 float poly[3];
179 float y[3];
180 float x_val;
181 int_least64_t temp;
182
183 /* Can't create poly out of less than 3 samples in each channel. */
184 if ( ilen < 3 * channels )
185  return -1;
186
187 ip = roar_mm_malloc(ilen * sizeof(int32_t));
188 if ( ip == NULL )
189  return -1;
190
191 memcpy(ip, in, ilen * sizeof(int32_t));
192
193 olen /= channels;
194
195 for (x = 0; x < olen; x++) {
196  for (c = 0; c < channels; c++) {
197   pos_in = (float)x / ratio;
198
199   if ( (int)pos_in == 0 ) {
200    y[0] = ip[0 * channels + c];
201    y[1] = ip[1 * channels + c];
202    y[2] = ip[2 * channels + c];
203    x_val = pos_in;
204    roar_math_mkpoly_3x3(poly, y);
205   } else if ( (int)pos_in + 1 >= ilen/channels ) {
206    /* If we're at the end of the block, we will need to interpolate against a value that is not yet known.
207     * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */
208    y[0] = ip[((int)pos_in - 1) * channels + c];
209    y[1] = ip[((int)pos_in    ) * channels + c];
210
211    // we create a 2x2 poly here and set the 3rd coefficient to zero to build a 3x3 poly
212    roar_math_mkpoly_2x2(poly, y);
213    poly[2] = 0;
214    x_val = pos_in - (int)pos_in + 1.0;
215   } else {
216    y[0] = ip[((int)pos_in - 1) * channels + c];
217    y[1] = ip[((int)pos_in    ) * channels + c];
218    y[2] = ip[((int)pos_in + 1) * channels + c];
219    x_val = pos_in - (int)pos_in + 1.0;
220    roar_math_mkpoly_3x3(poly, y);
221   }
222
223
224   temp = (float)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5);
225   /* temp could be out of bounds, so need to check this */
226   if ( temp > 0x7FFFFFFE ) {
227    out[x * channels + c] =  0x7FFFFFFE;
228   } else if (temp < -0x7FFFFFFF) {
229    out[x * channels + c] = -0x7FFFFFFF;
230   } else {
231    out[x * channels + c] = (int32_t)temp;
232   }
233  }
234 }
235
236 roar_mm_free(ip);
237 return 0;
238}
239
Note: See TracBrowser for help on using the repository browser.