diff options
Diffstat (limited to 'gst-libs/gst/resample/dtos.c')
-rw-r--r-- | gst-libs/gst/resample/dtos.c | 201 |
1 files changed, 201 insertions, 0 deletions
diff --git a/gst-libs/gst/resample/dtos.c b/gst-libs/gst/resample/dtos.c new file mode 100644 index 00000000..7762595f --- /dev/null +++ b/gst-libs/gst/resample/dtos.c @@ -0,0 +1,201 @@ +/* Resampling library + * Copyright (C) <2001> David A. Schleef <ds@schleef.org> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include <string.h> +#include <math.h> +#include <stdio.h> +#include <stdlib.h> + +//#include <ml.h> +#include <resample.h> + + + +#define short_to_double_table +//#define short_to_double_altivec +#define short_to_double_unroll + +#ifdef short_to_double_table +static float ints_high[256]; +static float ints_low[256]; + +void conv_double_short_table(double *dest, short *src, int n) +{ + static int init = 0; + int i; + unsigned int idx; + if(!init){ + for(i=0;i<256;i++){ + ints_high[i]=256.0*((i<128)?i:i-256); + ints_low[i]=i; + } + init = 1; + } + + if(n&1){ + idx = (unsigned short)*src++; + *dest++ = ints_high[(idx>>8)] + ints_low[(idx&0xff)]; + n-=1; + } + for(i=0;i<n;i+=2){ + idx = (unsigned short)*src++; + *dest++ = ints_high[(idx>>8)] + ints_low[(idx&0xff)]; + idx = (unsigned short)*src++; + *dest++ = ints_high[(idx>>8)] + ints_low[(idx&0xff)]; + } +} + +#endif + +#ifdef short_to_double_unroll +void conv_double_short_unroll(double *dest, short *src, int n) +{ + if(n&1){ + *dest++ = *src++; + n--; + } + if(n&2){ + *dest++ = *src++; + *dest++ = *src++; + n-=2; + } + while(n>0){ + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + n-=4; + } +} +#endif + +void conv_double_short_ref(double *dest, short *src, int n) +{ + int i; + for(i=0;i<n;i++){ + dest[i]=src[i]; + } +} + +#ifdef HAVE_CPU_PPC +#if 0 +static union { int i[4]; float f[4]; } av_tmp __attribute__ ((__aligned__ (16))); + +void conv_double_short_altivec(double *dest, short *src, int n) +{ + int i; + + for(i=0;i<n;i+=4){ + av_tmp.i[0] = src[0]; + av_tmp.i[1] = src[1]; + av_tmp.i[2] = src[2]; + av_tmp.i[3] = src[3]; + + asm( + " lvx 0,0,%0\n" + " vcfsx 1,0,0\n" + " stvx 1,0,%0\n" + : : "r" (&av_tmp) + ); + + dest[0]=av_tmp.f[0]; + dest[1]=av_tmp.f[1]; + dest[2]=av_tmp.f[2]; + dest[3]=av_tmp.f[3]; + src += 4; + dest += 4; + } +} +#endif +#endif + + + +/* double to short */ + +void conv_short_double_ref(short *dest, double *src, int n) +{ + int i; + double x; + + for(i=0;i<n;i++){ + x = *src++; + if(x<-32768.0)x=-32768.0; + if(x>32767.0)x=32767.0; + *dest++ = rint(x); + } +} + +#ifdef HAVE_CPU_PPC +void conv_short_double_ppcasm(short *dest, double *src, int n) +{ + int tmp[2]; + double min = -32768.0; + double max = 32767.0; + double ftmp0, ftmp1; + + asm __volatile__( + "\taddic. %3,%3,-8\n" + "\taddic. %6,%6,-2\n" + "loop:\n" + "\tlfdu %0,8(%3)\n" + "\tfsub %1,%0,%4\n" + "\tfsel %0,%1,%0,%4\n" + "\tfsub %1,%0,%5\n" + "\tfsel %0,%1,%5,%0\n" + "\tfctiw %1,%0\n" + "\taddic. 5,5,-1\n" + "\tstfd %1,0(%2)\n" + "\tlhz 9,6(%2)\n" + "\tsthu 9,2(%6)\n" + "\tbne loop\n" + : "=&f" (ftmp0), "=&f" (ftmp1) + : "b" (tmp), "r" (src), "f" (min), "f" (max), "r" (dest) + : "r9", "r5" ); + +} +#endif + + +void conv_double_short_dstr(double *dest, short *src, int n, int dstr) +{ + int i; + void *d = dest; + for(i=0;i<n;i++){ + (*(double *)d)=*src++; + d += dstr; + } +} + +void conv_short_double_sstr(short *dest, double *src, int n, int sstr) +{ + int i; + double x; + void *s = src; + + for(i=0;i<n;i++){ + x = *(double *)s; + if(x<-32768.0)x=-32768.0; + if(x>32767.0)x=32767.0; + *dest++ = rint(x); + s += sstr; + } +} + |