Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/openal-0.0.8/src/audioconvert/ac_freq.c @ 17

Last change on this file since 17 was 17, checked in by landauf, 16 years ago

added openal

File size: 5.8 KB
Line 
1/* -*- mode: C; tab-width:8; c-basic-offset:8 -*-
2 * vi:set ts=8:
3 *
4 * ac_freq.c
5 *
6 * audioconvert functions related to changing the sampling
7 * rate of a buffer.
8 *
9 */
10#include "al_siteconfig.h"
11
12#include <AL/al.h>
13#include <stdio.h>
14
15#include "audioconvert/audioconvert.h"
16
17/* Convert rate up by multiple of 2 */
18void acFreqMUL2(acAudioCVT *cvt, ALushort format) {
19        int i;
20        ALubyte *src, *dst;
21        src = (ALubyte *) cvt->buf + cvt->len_cvt;
22        dst = (ALubyte *) cvt->buf + cvt->len_cvt * 2;
23       
24        switch(format & 0xFF) {
25        case 8:
26                if (format == AUDIO_U8) {
27                        ALubyte *src8 = (ALubyte*) src;
28                        ALubyte *dst8 = (ALubyte*) dst;
29                        src8 -= 1;
30                        dst8 -= 2;
31                        /* For the first sample to be processed (last sample
32                           in the buffer) there's no 'next' sample in the
33                           buffer to interpolate against.  So we use a value
34                           extrapolated (then dampened) from the previous
35                           sample in the buffer; this dampens (but doesn't
36                           eliminate :() the 'click' of the first sample. */
37                        if (cvt->len_cvt >= 2) {
38                                int ex; /* extrapolated sample, damped */
39                                ex = src8[0] + (src8[0]-(int)src8[-1])/8;
40                                if ( ex > 255 )
41                                        ex = 255;
42                                else if ( ex < 0 )
43                                        ex = 0;
44                                dst8[0] = src8[0];
45                                dst8[1] = ex;
46                                for ( i=cvt->len_cvt-1; i; --i ) {
47                                        src8 -= 1;
48                                        dst8 -= 2;
49                                        dst8[0] = src8[0];
50                                        dst8[1] = (src8[0]+(int)src8[1])/2;
51                                }
52                        } else if (cvt->len_cvt == 1) {
53                                dst8[0] = src8[0];
54                                dst8[1] = src8[0];
55                        }
56                } else if (format == AUDIO_S8) {
57                        ALbyte *src8 = (ALbyte*) src;
58                        ALbyte *dst8 = (ALbyte*) dst;
59                        src8 -= 1;
60                        dst8 -= 2;
61                        if (cvt->len_cvt >= 2) {
62                                int ex; /* extrapolated sample, damped */
63                                ex = src8[0] + (src8[0]-(int)src8[-1])/8;
64                                if ( ex > 127 )
65                                        ex = 127;
66                                else if ( ex < -128 )
67                                        ex = -128;
68                                dst8[0] = src8[0];
69                                dst8[1] = ex;
70                                for ( i=cvt->len_cvt-1; i; --i ) {
71                                        src8 -= 1;
72                                        dst8 -= 2;
73                                        dst8[0] = src8[0];
74                                        dst8[1] = (src8[0]+(int)src8[1])/2;
75                                }
76                        } else {
77                                dst8[0] = src8[0];
78                                dst8[1] = src8[0];
79                        }
80                }
81                break;
82        case 16:
83                if (format == AUDIO_S16) {
84                        ALshort *src16 = (ALshort*) src;
85                        ALshort *dst16 = (ALshort*) dst;
86                        src16 -= 1;
87                        dst16 -= 2;
88                        if (cvt->len_cvt >= 4) {
89                                int ex; /* extrapolated sample, damped */
90                                ex = src16[0] + (src16[0]-(int)src16[-1])/8;
91                                if ( ex > 32767 )
92                                        ex = 32767;
93                                else if ( ex < -32768 )
94                                        ex = -32768;
95                                dst16[0] = src16[0];
96                                dst16[1] = ex;
97                                for ( i=cvt->len_cvt/2-1; i; --i ) {
98                                        src16 -= 1;
99                                        dst16 -= 2;
100                                        dst16[0] = src16[0];
101                                        dst16[1] = (src16[0]+(int)src16[1])/2;
102                                }
103                        } else if (cvt->len_cvt == 2) {
104                                dst16[0] = src16[0];
105                                dst16[1] = src16[0];
106                        }
107                } else if (format == AUDIO_U16) {
108                        ALushort *src16 = (ALushort*) src;
109                        ALushort *dst16 = (ALushort*) dst;
110                        src16 -= 1;
111                        dst16 -= 2;
112                        if (cvt->len_cvt >= 4) {
113                                int ex; /* extrapolated sample, damped */
114                                ex = src16[0] + (src16[0]-(int)src16[-1])/8;
115                                if ( ex > 65535 )
116                                        ex = 65535;
117                                else if ( ex < 0 )
118                                        ex = 0;
119                                dst16[0] = src16[0];
120                                dst16[1] = ex;
121                                for ( i=cvt->len_cvt/2-1; i; --i ) {
122                                        src16 -= 1;
123                                        dst16 -= 2;
124                                        dst16[0] = src16[0];
125                                        dst16[1] = (src16[0]+(int)src16[1])/2;
126                                }
127                        } else if (cvt->len_cvt == 2) {
128                                dst16[0] = src16[0];
129                                dst16[1] = src16[0];
130                        }
131                } else {
132                        /* this is a 16-bit format that doesn't correspond
133                           to a native type, so sample interpolation isn't
134                           completely trivial; we'll just do sample
135                           duplication.  Not too hard to fix though, for
136                           future work. */
137                        ALushort *src16 = (ALushort*) src;
138                        ALushort *dst16 = (ALushort*) dst;
139                        for ( i=cvt->len_cvt/2; i; --i ) {
140                                src16 -= 1;
141                                dst16 -= 2;
142                                dst16[0] = src16[0];
143                                dst16[1] = src16[0];
144                        }
145                }
146        break;
147        }
148        cvt->len_cvt *= 2;
149       
150        if (cvt->filters[++cvt->filter_index] ) {
151                cvt->filters[cvt->filter_index](cvt, format);
152        }
153}
154
155/* Convert rate down by multiple of 2 */
156void acFreqDIV2(acAudioCVT *cvt, ALushort format) {
157        int i;
158        ALubyte *src, *dst;
159
160        src = cvt->buf;
161        dst = cvt->buf;
162        switch(format & 0xFF) {
163                case 8:
164                        for ( i=cvt->len_cvt/2; i; --i ) {
165                                dst[0] = src[0];
166                                src += 2;
167                                dst += 1;
168                        }
169                        break;
170                case 16:
171                        for ( i=cvt->len_cvt/4; i; --i ) {
172                                dst[0] = src[0];
173                                dst[1] = src[1];
174                                src += 4;
175                                dst += 2;
176                        }
177                        break;
178        }
179
180        cvt->len_cvt /= 2;
181
182        if (cvt->filters[++cvt->filter_index] ) {
183                cvt->filters[cvt->filter_index](cvt, format);
184        }
185}
186
187/* Very slow rate conversion routine */
188void acFreqSLOW(acAudioCVT *cvt, ALushort format) {
189        double ipos;
190        int i, clen;
191
192        clen = (int) ((double)cvt->len_cvt / cvt->rate_incr);
193        if(cvt->rate_incr > 1.0) {
194                switch(format & 0xFF) {
195                        case 8: {
196                                ALubyte *output;
197
198                                output = cvt->buf;
199                                ipos = 0.0;
200                                for ( i=clen; i; --i ) {
201                                        *output = *((ALubyte *) cvt->buf + (int)ipos);
202                                        ipos += cvt->rate_incr;
203                                        output += 1;
204                                }
205                        }
206                        break;
207
208                        case 16: {
209                                ALushort *output;
210
211                                clen &= ~1;
212                                output = (ALushort *) cvt->buf;
213                                ipos = 0.0;
214                                for ( i=clen/2; i; --i ) {
215                                        *output=((ALushort *)cvt->buf)[(int)ipos];
216                                        ipos += cvt->rate_incr;
217                                        output += 1;
218                                }
219                        }
220                        break;
221
222                        default: {
223                                /* unexpected */
224                        }
225                        break;
226                }
227        } else {
228                switch (format & 0xFF) {
229                        case 8: {
230                                ALubyte *output;
231
232                                output = (ALubyte *) cvt->buf + clen;
233                                ipos = (double)cvt->len_cvt;
234                                for ( i=clen; i; --i ) {
235                                        ipos -= cvt->rate_incr;
236                                        output -= 1;
237                                        *output = *((ALubyte *) cvt->buf + (int)ipos);
238                                }
239                        }
240                        break;
241
242                        case 16: {
243                                ALushort *output;
244
245                                clen &= ~1;
246                                output = (ALushort *) cvt->buf;
247                                output += clen / sizeof *output;
248
249                                ipos = (double)cvt->len_cvt/2;
250                                for ( i=clen/2; i; --i ) {
251                                        ipos -= cvt->rate_incr;
252                                        output -= 1;
253                                        *output=((ALushort *)cvt->buf)[(int)ipos];
254                                }
255                        }
256                        break;
257
258                        default: {
259                                /* unexpected */
260                        }
261                        break;
262                }
263        }
264        cvt->len_cvt = clen;
265
266        if (cvt->filters[++cvt->filter_index] ) {
267                cvt->filters[cvt->filter_index](cvt, format);
268        }
269}
Note: See TracBrowser for help on using the repository browser.