Changeset 4111:ea89fa7723d6 in roaraudio for libroardsp


Ignore:
Timestamp:
08/06/10 16:39:18 (14 years ago)
Author:
phi
Branch:
default
Phase:
public
Message:

experimental patch from maister for resampling

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libroardsp/convert.c

    r4110 r4111  
    626626} 
    627627 
     628int roar_conv_rate2      (void * out, void * in, int samples, int outsamples, int bits, int channels) { 
     629 switch (bits) { 
     630  case 16: 
     631    return roar_conv_poly3_16(out, in, outsamples, samples, channels); 
     632   break; 
     633 } 
     634 return -1; 
     635} 
     636 
    628637int roar_conv_signedness  (void * out, void * in, int samples, int from, int to, int bits) { 
    629638 
     
    10181027 ROAR_DBG("roar_conv2(*): input samples: %i", samples); 
    10191028 
     1029#if 0 
    10201030 // calculate size per frame 
    10211031 needed_buffer  = ROAR_MAX(from->channels, to->channels) * ROAR_MAX(from->bits, to->bits) / 8; 
     
    10321042 if ( needed_buffer > bufsize ) 
    10331043  return -1; 
     1044#endif 
    10341045 
    10351046 if ( from->rate != to->rate || from->channels != to->channels ) 
     
    10781089//--// 
    10791090 if ( from->rate != to->rate ) { 
    1080   if ( roar_conv_rate(out, cin, samples, from->rate, to->rate, cinfo.bits, cinfo.channels) == -1 ) 
     1091  if ( roar_conv_rate2(out, cin, samples, bufsize/(cinfo.bits/8), cinfo.bits, cinfo.channels) == -1 ) 
    10811092   return -1; 
    10821093 
    10831094  cin            = out; 
    1084   samples        = (float)samples * (float)to->rate / (float)from->rate; 
     1095  samples        = bufsize/(cinfo.bits/8); 
    10851096  cinfo.rate     = to->rate; 
    10861097 } 
     
    11881199 
    11891200//ll 
     1201/***********************************/ 
     1202// ilen and olen are in samples, not frames. 
     1203int roar_conv_poly3_16 (int16_t * out, int16_t * in, size_t olen, size_t ilen, int channels) { 
     1204 float ratio = (float)olen / (float)ilen; 
     1205 int16_t *ip; 
     1206 int c, x; 
     1207 
     1208 /* Can't create poly out of less than 3 samples in each channel. */ 
     1209 if ( ilen < 3 * channels ) 
     1210  return -1; 
     1211 
     1212 ip = roar_mm_malloc(ilen * sizeof(int16_t)); 
     1213 if ( ip == NULL ) 
     1214  return -1; 
     1215 
     1216 memcpy(ip, in, ilen * sizeof(int16_t)); 
     1217 
     1218 for ( x = 0; x < olen/channels; x++ ) { 
     1219  for ( c = 0; c < channels; c++ ) { 
     1220   float pos_out; 
     1221   float pos_in; 
     1222 
     1223   float poly[3]; 
     1224   float y[3]; 
     1225   float x_val; 
     1226 
     1227   pos_out = x; 
     1228   pos_in = pos_out / ratio; 
     1229 
     1230   if ( (int)pos_in == 0 ) { 
     1231    y[0] = ip[c]; 
     1232    y[1] = ip[channels + c]; 
     1233    y[2] = ip[2 * channels + c]; 
     1234    x_val = pos_in; 
     1235   } else if ( (int)pos_in + 1 >= ilen/channels ) { 
     1236    /* If we're at the end of the block, we will need to interpolate against a value that is not yet known. 
     1237     * We will assume this value, by linearly extrapolating the two preceding values. From causual testing, this is not audible. */ 
     1238    y[0] = ip[((int)pos_in - 1) * channels + c]; 
     1239    y[1] = ip[(int)pos_in * channels + c]; 
     1240    y[2] = y[1] * 2.0 - y[0]; 
     1241    /* We have to clip this value. */ 
     1242    if ( (int32_t)y[2] > 0x7FFE ) 
     1243     y[2] = 0x7FFE; 
     1244    else if ( (int32_t)y[2] < -0x7FFE ) 
     1245     y[2] = -0x7FFE; 
     1246 
     1247    x_val = pos_in - (int)pos_in + 1.0; 
     1248   } else { 
     1249    y[0] = ip[((int)pos_in - 1) * channels + c]; 
     1250    y[1] = ip[(int)pos_in * channels + c]; 
     1251    y[2] = ip[((int)pos_in + 1) * channels + c]; 
     1252    x_val = pos_in - (int)pos_in + 1.0; 
     1253   } 
     1254 
     1255   roar_math_mkpoly_3x3(poly, y); 
     1256 
     1257   int32_t temp = (int32_t)(poly[2]*x_val*x_val + poly[1]*x_val + poly[0] + 0.5); 
     1258   /* temp could be out of bounds, so need to check this */ 
     1259   if (temp > 0x7FFE ) 
     1260    out[x * channels + c] = 0x7FFE; 
     1261   else if (temp < -0x7FFE) 
     1262    out[x * channels + c] = -0x7FFE; 
     1263   else 
     1264    out[x * channels + c] = (int16_t)temp; 
     1265  } 
     1266 } 
     1267 roar_mm_free(ip); 
     1268 return 0; 
     1269} 
Note: See TracChangeset for help on using the changeset viewer.