BEAST/BSE - Better Audio System and Sound Engine  0.8.2
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
gsldatautils.hh
Go to the documentation of this file.
00001  // Licensed GNU LGPL v2.1 or later: http://www.gnu.org/licenses/lgpl.html
00002 #ifndef __GSL_DATA_UTILS_H__
00003 #define __GSL_DATA_UTILS_H__
00004 
00005 #include <bse/bsemath.hh>
00006 #include <bse/gsldatahandle.hh>
00007 
00008 G_BEGIN_DECLS
00009 
00010 /* --- structures --- */
00011 #define GSL_DATA_HANDLE_PEEK_BUFFER     (2048)
00012 typedef struct
00013 {
00014   gint    dir;   /* initialize direction to -1 or +1 (or 0 for random access) */
00015   GslLong start; /* initialize to 0 */
00016   GslLong end;   /* initialize to 0 */
00017   gfloat  data[GSL_DATA_HANDLE_PEEK_BUFFER];
00018 } GslDataPeekBuffer;
00019 typedef struct
00020 {
00021   GslLong head_skip;    /* FIXME: remove this */
00022   GslLong tail_cut;
00023   GslLong min_loop;
00024   GslLong max_loop;
00025 } GslLoopSpec;  /* rename this to GslData... */
00026 
00027 
00028 /* --- data utils --- */
00029 gboolean        gsl_data_detect_signal          (GslDataHandle          *handle,
00030                                                  GslLong                *sigstart,
00031                                                  GslLong                *sigend);
00032 GslLong         gsl_data_find_sample            (GslDataHandle          *dhandle,
00033                                                  gfloat                  min_value,
00034                                                  gfloat                  max_value,
00035                                                  GslLong                 start_offset,
00036                                                  gint                    direction);
00037 gboolean        gsl_data_find_tailmatch         (GslDataHandle          *dhandle,
00038                                                  const GslLoopSpec      *lspec,
00039                                                  GslLong                *loop_start_p,
00040                                                  GslLong                *loop_end_p);
00041 GslLong         gsl_data_find_block             (GslDataHandle          *handle,
00042                                                  guint                   n_values,
00043                                                  const gfloat           *values,
00044                                                  gfloat                  epsilon);
00045 gfloat*         gsl_data_make_fade_ramp         (GslDataHandle          *handle,
00046                                                  GslLong                 min_pos, /* *= 0.0 + delta */
00047                                                  GslLong                 max_pos, /* *= 1.0 - delta */
00048                                                  GslLong                *length_p);
00049 double          gsl_data_find_min_max           (GslDataHandle          *handle,
00050                                                  double                 *dmin,
00051                                                  double                 *dmax);
00052 
00053 
00054 /* --- data handle utils --- */
00055 static inline gfloat gsl_data_handle_peek_value (GslDataHandle          *dhandle,
00056                                                  GslLong                 position,
00057                                                  GslDataPeekBuffer      *peekbuf);
00058 gint /* errno */     gsl_data_handle_dump       (GslDataHandle          *dhandle,
00059                                                  gint                    fd,
00060                                                  GslWaveFormatType       format,
00061                                                  guint                   byte_order);
00062 gint /* errno */     gsl_data_handle_dump_wav   (GslDataHandle          *dhandle,
00063                                                  gint                    fd,
00064                                                  guint                   n_bits,
00065                                                  guint                   n_channels,
00066                                                  guint                   sample_freq);
00067 void                 gsl_data_handle_dump_wstore(GslDataHandle          *dhandle,
00068                                                  SfiWStore              *wstore,
00069                                                  GslWaveFormatType       format,
00070                                                  guint                   byte_order);
00071 gint /* errno */     bse_wave_file_dump_header  (gint                    fd,
00072                                                  guint                   n_data_bytes,
00073                                                  guint                   n_bits,
00074                                                  guint                   n_channels,
00075                                                  guint                   sample_freq);
00076 gint /* errno */     bse_wave_file_patch_length (gint                    fd,
00077                                                  guint                   n_data_bytes);
00078 gint /* errno */     bse_wave_file_dump_data    (gint                    fd,
00079                                                  guint                   n_bits,
00080                                                  guint                   n_values,
00081                                                  const gfloat           *values);
00082 gint /* errno */     bse_wave_file_from_fbuffer (const char             *file_name,
00083                                                  guint                   n_bits,
00084                                                  guint                   n_channels,
00085                                                  guint                   sample_freq,
00086                                                  guint                   n_values,
00087                                                  const gfloat           *values);
00088 gint /* errno */     bse_wave_file_from_dbuffer (const char             *file_name,
00089                                                  guint                   n_bits,
00090                                                  guint                   n_channels,
00091                                                  guint                   sample_freq,
00092                                                  guint                   n_values,
00093                                                  const gdouble          *values);
00094 
00095 /* --- conversion utils --- */
00096 static inline guint   gsl_conv_from_float       (GslWaveFormatType format,
00097                                                  guint             byte_order,
00098                                                  const gfloat     *src,
00099                                                  gpointer          dest,
00100                                                  guint             n_values);
00101 static inline guint   gsl_conv_from_float_clip  (GslWaveFormatType format,
00102                                                  guint             byte_order,
00103                                                  const gfloat     *src,
00104                                                  gpointer          dest,
00105                                                  guint             n_values);
00106 static inline void    gsl_conv_to_float         (GslWaveFormatType format,
00107                                                  guint             byte_order,
00108                                                  gconstpointer     src,
00109                                                  gfloat           *dest,
00110                                                  guint             n_values);
00111 static inline guint   gsl_conv_from_double      (GslWaveFormatType format,
00112                                                  guint             byte_order,
00113                                                  const gdouble    *src,
00114                                                  gpointer          dest,
00115                                                  guint             n_values);
00116 static inline guint   gsl_conv_from_double_clip (GslWaveFormatType format,
00117                                                  guint             byte_order,
00118                                                  const gdouble    *src,
00119                                                  gpointer          dest,
00120                                                  guint             n_values);
00121 static inline void    gsl_conv_to_double        (GslWaveFormatType format,
00122                                                  guint             byte_order,
00123                                                  gconstpointer     src,
00124                                                  gdouble          *dest,
00125                                                  guint             n_values);
00126 static inline gint16  gsl_alaw_to_pcm           (gint8             alawv);
00127 static inline gint16  gsl_ulaw_to_pcm           (gint8             ulawv);
00128 
00129 
00130 /* --- clipping --- */
00131 typedef struct
00132 {
00133   guint  produce_info : 1;
00134   gfloat threshold;     /* 0..+1 */
00135   guint  head_samples;
00136   guint  tail_samples;
00137   guint  fade_samples;
00138   guint  pad_samples;
00139   guint  tail_silence;
00140 } GslDataClipConfig;
00141 typedef struct
00142 {
00143   GslDataHandle *dhandle;
00144   guint          clipped_to_0length : 1;        /* no data above threshold */
00145   guint          head_detected : 1;             /* found head_samples silence */
00146   guint          tail_detected : 1;             /* found tail_samples silence */
00147   guint          clipped_head : 1;
00148   guint          clipped_tail : 1;
00149   BseErrorType   error;
00150 } GslDataClipResult;
00151 
00152 BseErrorType    gsl_data_clip_sample    (GslDataHandle     *dhandle,
00153                                          GslDataClipConfig *cconfig,
00154                                          GslDataClipResult *result);
00155 
00156 
00157 /* --- misc implementations --- */
00158 gfloat  gsl_data_peek_value_f   (GslDataHandle     *dhandle,
00159                                  GslLong            pos,
00160                                  GslDataPeekBuffer *peekbuf);
00161 
00162 static inline gfloat
00163 gsl_data_handle_peek_value (GslDataHandle     *dhandle,
00164                             GslLong            position,
00165                             GslDataPeekBuffer *peekbuf)
00166 {
00167   return (position >= peekbuf->start && position < peekbuf->end ?
00168           peekbuf->data[position - peekbuf->start] :
00169           gsl_data_peek_value_f (dhandle, position, peekbuf));
00170 }
00171 
00172 #define GSL_CONV_FORMAT(format, endian_flag)    (((endian_flag) << 16) | ((format) & 0xffff))
00173 
00174 static inline guint     /* returns number of bytes used in dest */
00175 gsl_conv_from_float (GslWaveFormatType format,
00176                      guint             byte_order,
00177                      const gfloat     *src,
00178                      gpointer          dest,
00179                      guint             n_values)
00180 {
00181   gint8 *i8 = (gint8*) dest;
00182   guint8 *u8 = (guint8*) dest;
00183   gint16 *i16 = (gint16*) dest;
00184   guint16 *u16 = (guint16*) dest;
00185   gint32 *i32 = (gint32*) dest;
00186   guint32 *u32dest = (guint32*) dest;
00187   const gfloat *bound = src + n_values;
00188   const guint32 *u32src = (guint32*) src, *u32bound = (const guint32*) bound;
00189 
00190   if (!n_values)
00191     return 0;
00192 
00193   switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
00194     {
00195       BseFpuState fpu;
00196       gfloat v;
00197       gint16 vi16;
00198       guint16 vu16;
00199       guint32 vu32;
00200     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00201     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00202       do
00203         *u8++ = bse_dtoi (*src++ * 128. + 128);
00204       while (src < bound);
00205       return n_values;
00206     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00207     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00208       bse_fpu_setround (&fpu);
00209       do
00210         {
00211           v = *src++;
00212           v *= 128.;
00213           *i8++ = bse_dtoi (v);
00214         }
00215       while (src < bound);
00216       bse_fpu_restore (fpu);
00217       return n_values;
00218     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00219       do
00220         *u16++ = bse_dtoi (*src++ * 2048. + 2048);
00221       while (src < bound);
00222       return n_values << 1;
00223     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00224       do
00225         {
00226           vu16 = bse_dtoi (*src++ * 2048. + 2048);
00227           *u16++ = GUINT16_SWAP_LE_BE (vu16);
00228         }
00229       while (src < bound);
00230       return n_values << 1;
00231     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00232       bse_fpu_setround (&fpu);
00233       do
00234         {
00235           v = *src++;
00236           v *= 2048.;
00237           *i16++ = bse_dtoi (v);
00238         }
00239       while (src < bound);
00240       bse_fpu_restore (fpu);
00241       return n_values << 1;
00242     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00243       bse_fpu_setround (&fpu);
00244       do
00245         {
00246           v = *src++;
00247           v *= 2048.;
00248           vi16 = bse_dtoi (v);
00249           *i16++ = GUINT16_SWAP_LE_BE (vi16);
00250         }
00251       while (src < bound);
00252       bse_fpu_restore (fpu);
00253       return n_values << 1;
00254     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00255       do
00256         *u16++ = bse_dtoi (*src++ * 32768. + 32768);
00257       while (src < bound);
00258       return n_values << 1;
00259     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00260       do
00261         {
00262           vu16 = bse_dtoi (*src++ * 32768. + 32768);
00263           *u16++ = GUINT16_SWAP_LE_BE (vu16);
00264         }
00265       while (src < bound);
00266       return n_values << 1;
00267     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00268       bse_fpu_setround (&fpu);
00269       do
00270         {
00271           v = *src++;
00272           v *= 32768.;
00273           *i16++ = bse_dtoi (v);
00274         }
00275       while (src < bound);
00276       bse_fpu_restore (fpu);
00277       return n_values << 1;
00278     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00279       bse_fpu_setround (&fpu);
00280       do
00281         {
00282           v = *src++;
00283           v *= 32768.;
00284           vi16 = bse_dtoi (v);
00285           *i16++ = GUINT16_SWAP_LE_BE (vi16);
00286         }
00287       while (src < bound);
00288       bse_fpu_restore (fpu);
00289       return n_values << 1;
00290     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER == G_BYTE_ORDER):
00291     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER != G_BYTE_ORDER):
00292       bse_fpu_setround (&fpu);
00293       if (byte_order == G_LITTLE_ENDIAN)
00294         do
00295           {
00296             v = *src++;
00297             v *= 8388608.;
00298             gint32 vi32 = bse_dtoi (v);
00299             *u8++ = vi32 >> 0;
00300             *u8++ = vi32 >> 8;
00301             *((gint8*) u8) = vi32 >> 16;
00302             u8++;
00303           }
00304         while (src < bound);
00305       else /* G_BIG_ENDIAN */
00306         do
00307           {
00308             v = *src++;
00309             v *= 8388608.;
00310             gint32 vi32 = bse_dtoi (v);
00311             *((gint8*) u8) = vi32 >> 16;
00312             u8++;
00313             *u8++ = vi32 >> 8;
00314             *u8++ = vi32 >> 0;
00315           }
00316         while (src < bound);
00317       bse_fpu_restore (fpu);
00318       return n_values * 3;
00319     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER == G_BYTE_ORDER):
00320       bse_fpu_setround (&fpu);
00321       do
00322         {
00323           v = *src++;
00324           v *= 8388608.;
00325           *i32++ = bse_dtoi (v);
00326         }
00327       while (src < bound);
00328       bse_fpu_restore (fpu);
00329       return n_values * 4;
00330     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER != G_BYTE_ORDER):
00331       bse_fpu_setround (&fpu);
00332       do
00333         {
00334           v = *src++;
00335           v *= 8388608.;
00336           gint32 vi32 = bse_dtoi (v);
00337           *i32++ = GUINT32_SWAP_LE_BE (vi32);
00338         }
00339       while (src < bound);
00340       bse_fpu_restore (fpu);
00341       return n_values * 4;
00342     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER == G_BYTE_ORDER):
00343       bse_fpu_setround (&fpu);
00344       do
00345         {
00346           v = *src++;
00347           v *= 2147483648.;
00348           *i32++ = bse_dtoi (v);
00349         }
00350       while (src < bound);
00351       bse_fpu_restore (fpu);
00352       return n_values * 4;
00353     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER != G_BYTE_ORDER):
00354       bse_fpu_setround (&fpu);
00355       do
00356         {
00357           v = *src++;
00358           v *= 2147483648.;
00359           gint32 vi32 = bse_dtoi (v);
00360           *i32++ = GUINT32_SWAP_LE_BE (vi32);
00361         }
00362       while (src < bound);
00363       bse_fpu_restore (fpu);
00364       return n_values * 4;
00365     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
00366       return n_values * 4;
00367     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
00368       do
00369         {
00370           vu32 = *u32src++;
00371           *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
00372         }
00373       while (u32src < u32bound);
00374       return n_values * 4;
00375     default:
00376       g_assert_not_reached ();
00377       return 0;
00378     }
00379 }
00380 
00381 static inline guint     /* returns number of bytes used in dest */
00382 gsl_conv_from_float_clip (GslWaveFormatType format,
00383                           guint             byte_order,
00384                           const gfloat     *src,
00385                           gpointer          dest,
00386                           guint             n_values)
00387 {
00388   gint8 *i8 = (gint8*) dest;
00389   guint8 *u8 = (guint8*) dest;
00390   gint16 *i16 = (gint16*) dest;
00391   guint16 *u16 = (guint16*) dest;
00392   gint32 *i32 = (gint32*) dest;
00393   guint32 *u32dest = (guint32*) dest;
00394   const gfloat *bound = src + n_values;
00395   const guint32 *u32src = (const guint32*) src, *u32bound = (const guint32*) bound;
00396 
00397   if (!n_values)
00398     return 0;
00399 
00400   switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
00401     {
00402       BseFpuState fpu;
00403       gfloat v;
00404       guint32 vu32;
00405       gint32 vi32;
00406     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00407     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00408       do
00409         {
00410           vi32 = bse_dtoi (*src++ * 128. + 128);
00411           *u8++ = CLAMP (vi32, 0, 255);
00412         }
00413       while (src < bound);
00414       return n_values;
00415     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00416     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00417       bse_fpu_setround (&fpu);
00418       do
00419         {
00420           v = *src++;
00421           v *= 128.;
00422           vi32 = bse_dtoi (v);
00423           *i8++ = CLAMP (vi32, -128, 127);
00424         }
00425       while (src < bound);
00426       bse_fpu_restore (fpu);
00427       return n_values;
00428     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00429       do
00430         {
00431           vi32 = bse_dtoi (*src++ * 2048. + 2048);
00432           *u16++ = CLAMP (vi32, 0, 4095);
00433         }
00434       while (src < bound);
00435       return n_values << 1;
00436     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00437       do
00438         {
00439           vi32 = bse_dtoi (*src++ * 2048. + 2048);
00440           vi32 = CLAMP (vi32, 0, 4095);
00441           *u16++ = GUINT16_SWAP_LE_BE (vi32);
00442         }
00443       while (src < bound);
00444       return n_values << 1;
00445     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00446       bse_fpu_setround (&fpu);
00447       do
00448         {
00449           v = *src++;
00450           v *= 2048.;
00451           vi32 = bse_dtoi (v);
00452           *i16++ = CLAMP (vi32, -2048, 2047);
00453         }
00454       while (src < bound);
00455       bse_fpu_restore (fpu);
00456       return n_values << 1;
00457     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00458       bse_fpu_setround (&fpu);
00459       do
00460         {
00461           v = *src++;
00462           v *= 2048.;
00463           vi32 = bse_dtoi (v);
00464           vi32 = CLAMP (vi32, -2048, 2047);
00465           *i16++ = GUINT16_SWAP_LE_BE (vi32);
00466         }
00467       while (src < bound);
00468       bse_fpu_restore (fpu);
00469       return n_values << 1;
00470     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00471       do
00472         {
00473           vi32 = bse_dtoi (*src++ * 32768. + 32768);
00474           *u16++ = CLAMP (vi32, 0, 65535);
00475         }
00476       while (src < bound);
00477       return n_values << 1;
00478     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00479       do
00480         {
00481           vi32 = bse_dtoi (*src++ * 32768. + 32768);
00482           vi32 = CLAMP (vi32, 0, 65535);
00483           *u16++ = GUINT16_SWAP_LE_BE (vi32);
00484         }
00485       while (src < bound);
00486       return n_values << 1;
00487     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00488       bse_fpu_setround (&fpu);
00489       do
00490         {
00491           v = *src++;
00492           v *= 32768.;
00493           vi32 = bse_dtoi (v);
00494           vi32 = CLAMP (vi32, -32768, 32767);
00495           *i16++ = vi32;
00496         }
00497       while (src < bound);
00498       bse_fpu_restore (fpu);
00499       return n_values << 1;
00500     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00501       bse_fpu_setround (&fpu);
00502       do
00503         {
00504           v = *src++;
00505           v *= 32768.;
00506           vi32 = bse_dtoi (v);
00507           vi32 = CLAMP (vi32, -32768, 32767);
00508           *i16++ = GUINT16_SWAP_LE_BE (vi32);
00509         }
00510       while (src < bound);
00511       bse_fpu_restore (fpu);
00512       return n_values << 1;
00513     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER == G_BYTE_ORDER):
00514     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER != G_BYTE_ORDER):
00515       bse_fpu_setround (&fpu);
00516       if (byte_order == G_LITTLE_ENDIAN)
00517         do
00518           {
00519             v = *src++;
00520             v *= 8388608.;
00521             gint32 vi32 = bse_dtoi (v);
00522             vi32 = CLAMP (vi32, -8388608, 8388607);
00523             *u8++ = vi32 >> 0;
00524             *u8++ = vi32 >> 8;
00525             *((gint8*) u8) = vi32 >> 16;
00526             u8++;
00527           }
00528         while (src < bound);
00529       else /* G_BIG_ENDIAN */
00530         do
00531           {
00532             v = *src++;
00533             v *= 8388608.;
00534             gint32 vi32 = bse_dtoi (v);
00535             vi32 = CLAMP (vi32, -8388608, 8388607);
00536             *((gint8*) u8) = vi32 >> 16;
00537             u8++;
00538             *u8++ = vi32 >> 8;
00539             *u8++ = vi32 >> 0;
00540           }
00541         while (src < bound);
00542       bse_fpu_restore (fpu);
00543       return n_values * 3;
00544     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER == G_BYTE_ORDER):
00545       bse_fpu_setround (&fpu);
00546       do
00547         {
00548           v = *src++;
00549           v *= 8388608.;
00550           vi32 = bse_dtoi (v);
00551           vi32 = CLAMP (vi32, -8388608, 8388607);
00552           *i32++ = vi32;
00553         }
00554       while (src < bound);
00555       bse_fpu_restore (fpu);
00556       return n_values * 4;
00557     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER != G_BYTE_ORDER):
00558       bse_fpu_setround (&fpu);
00559       do
00560         {
00561           v = *src++;
00562           v *= 8388608.;
00563           vi32 = bse_dtoi (v);
00564           vi32 = CLAMP (vi32, -8388608, 8388607);
00565           *i32++ = GUINT32_SWAP_LE_BE (vi32);
00566         }
00567       while (src < bound);
00568       bse_fpu_restore (fpu);
00569       return n_values * 4;
00570     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER == G_BYTE_ORDER):
00571       bse_fpu_setround (&fpu);
00572       do
00573         {
00574           v = *src++;
00575           v *= 2147483648.;
00576           vi32 = bse_dtoi (v);
00577           // vi32 = CLAMP (vi32, -2147483648, 2147483647);
00578           *i32++ = vi32;
00579         }
00580       while (src < bound);
00581       bse_fpu_restore (fpu);
00582       return n_values * 4;
00583     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER != G_BYTE_ORDER):
00584       bse_fpu_setround (&fpu);
00585       do
00586         {
00587           v = *src++;
00588           v *= 2147483648.;
00589           vi32 = bse_dtoi (v);
00590           // vi32 = CLAMP (vi32, -2147483648, 2147483647);
00591           *i32++ = GUINT32_SWAP_LE_BE (vi32);
00592         }
00593       while (src < bound);
00594       bse_fpu_restore (fpu);
00595       return n_values * 4;
00596     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
00597       return n_values << 2;
00598     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
00599       do
00600         {
00601           vu32 = *u32src++;
00602           *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
00603         }
00604       while (u32src < u32bound);
00605       return n_values << 2;
00606     default:
00607       g_assert_not_reached ();
00608       return 0;
00609     }
00610 }
00611 
00612 #define GSL_ALAW_MAX    (0x7e00)
00613 static inline gint16
00614 gsl_alaw_to_pcm (gint8 alawv)
00615 {
00616   static const short alaw2pcm_table[128] = {
00617     0x1580, 0x1480, 0x1780, 0x1680, 0x1180, 0x1080, 0x1380, 0x1280,
00618     0x1d80, 0x1c80, 0x1f80, 0x1e80, 0x1980, 0x1880, 0x1b80, 0x1a80,
00619     0x0ac0, 0x0a40, 0x0bc0, 0x0b40, 0x08c0, 0x0840, 0x09c0, 0x0940,
00620     0x0ec0, 0x0e40, 0x0fc0, 0x0f40, 0x0cc0, 0x0c40, 0x0dc0, 0x0d40,
00621     0x5600, 0x5200, 0x5e00, 0x5a00, 0x4600, 0x4200, 0x4e00, 0x4a00,
00622     0x7600, 0x7200, 0x7e00, 0x7a00, 0x6600, 0x6200, 0x6e00, 0x6a00,
00623     0x2b00, 0x2900, 0x2f00, 0x2d00, 0x2300, 0x2100, 0x2700, 0x2500,
00624     0x3b00, 0x3900, 0x3f00, 0x3d00, 0x3300, 0x3100, 0x3700, 0x3500,
00625     0x0158, 0x0148, 0x0178, 0x0168, 0x0118, 0x0108, 0x0138, 0x0128,
00626     0x01d8, 0x01c8, 0x01f8, 0x01e8, 0x0198, 0x0188, 0x01b8, 0x01a8,
00627     0x0058, 0x0048, 0x0078, 0x0068, 0x0018, 0x0008, 0x0038, 0x0028,
00628     0x00d8, 0x00c8, 0x00f8, 0x00e8, 0x0098, 0x0088, 0x00b8, 0x00a8,
00629     0x0560, 0x0520, 0x05e0, 0x05a0, 0x0460, 0x0420, 0x04e0, 0x04a0,
00630     0x0760, 0x0720, 0x07e0, 0x07a0, 0x0660, 0x0620, 0x06e0, 0x06a0,
00631     0x02b0, 0x0290, 0x02f0, 0x02d0, 0x0230, 0x0210, 0x0270, 0x0250,
00632     0x03b0, 0x0390, 0x03f0, 0x03d0, 0x0330, 0x0310, 0x0370, 0x0350,
00633   };
00634   return alawv < 0 ? alaw2pcm_table[128 + alawv] : -alaw2pcm_table[alawv];
00635 }
00636 
00637 #define GSL_ULAW_MAX    (0x7d7c)
00638 static inline gint16
00639 gsl_ulaw_to_pcm (gint8 ulawv)
00640 {
00641   static const short ulaw2pcm_table[128] = {
00642     0x7d7c, 0x797c, 0x757c, 0x717c, 0x6d7c, 0x697c, 0x657c, 0x617c,
00643     0x5d7c, 0x597c, 0x557c, 0x517c, 0x4d7c, 0x497c, 0x457c, 0x417c,
00644     0x3e7c, 0x3c7c, 0x3a7c, 0x387c, 0x367c, 0x347c, 0x327c, 0x307c,
00645     0x2e7c, 0x2c7c, 0x2a7c, 0x287c, 0x267c, 0x247c, 0x227c, 0x207c,
00646     0x1efc, 0x1dfc, 0x1cfc, 0x1bfc, 0x1afc, 0x19fc, 0x18fc, 0x17fc,
00647     0x16fc, 0x15fc, 0x14fc, 0x13fc, 0x12fc, 0x11fc, 0x10fc, 0x0ffc,
00648     0x0f3c, 0x0ebc, 0x0e3c, 0x0dbc, 0x0d3c, 0x0cbc, 0x0c3c, 0x0bbc,
00649     0x0b3c, 0x0abc, 0x0a3c, 0x09bc, 0x093c, 0x08bc, 0x083c, 0x07bc,
00650     0x075c, 0x071c, 0x06dc, 0x069c, 0x065c, 0x061c, 0x05dc, 0x059c,
00651     0x055c, 0x051c, 0x04dc, 0x049c, 0x045c, 0x041c, 0x03dc, 0x039c,
00652     0x036c, 0x034c, 0x032c, 0x030c, 0x02ec, 0x02cc, 0x02ac, 0x028c,
00653     0x026c, 0x024c, 0x022c, 0x020c, 0x01ec, 0x01cc, 0x01ac, 0x018c,
00654     0x0174, 0x0164, 0x0154, 0x0144, 0x0134, 0x0124, 0x0114, 0x0104,
00655     0x00f4, 0x00e4, 0x00d4, 0x00c4, 0x00b4, 0x00a4, 0x0094, 0x0084,
00656     0x0078, 0x0070, 0x0068, 0x0060, 0x0058, 0x0050, 0x0048, 0x0040,
00657     0x0038, 0x0030, 0x0028, 0x0020, 0x0018, 0x0010, 0x0008, 0x0000,
00658   };
00659   return ulawv < 0 ? ulaw2pcm_table[128 + ulawv] : -ulaw2pcm_table[ulawv];
00660 }
00661 
00662 static inline void
00663 gsl_conv_to_float (GslWaveFormatType format,
00664                    guint             byte_order,
00665                    gconstpointer     src,
00666                    gfloat           *dest,
00667                    guint             n_values)
00668 {
00669   const guint8 *u8 = (guint8*) src;
00670   const gint8 *i8 = (gint8*) src;
00671   const guint16 *u16 = (guint16*) src;
00672   const gint16 *i16 = (gint16*) src;
00673   const gint32 *i32 = (gint32*) src;
00674   const guint32 *u32src = (guint32*) src;
00675   gfloat *bound = dest + n_values;
00676   guint32 *u32dest = (guint32*) dest, *u32bound = (guint32*) bound;
00677 
00678   if (!n_values)
00679     return;
00680 
00681   switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
00682     {
00683       gint16 vi16;
00684       guint16 vu16;
00685       guint32 vu32;
00686     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00687     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00688       do
00689         *dest++ = (*u8++ - 128) * (1. / 128.);
00690       while (dest < bound);
00691       break;
00692     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00693     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00694       do
00695         *dest++ = *i8++ * (1. / 128.);
00696       while (dest < bound);
00697       break;
00698     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ALAW, G_BYTE_ORDER == G_BYTE_ORDER):
00699     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ALAW, G_BYTE_ORDER != G_BYTE_ORDER):
00700       do
00701         *dest++ = gsl_alaw_to_pcm (*i8++) * (1.0 / GSL_ALAW_MAX);
00702       while (dest < bound);
00703       break;
00704     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ULAW, G_BYTE_ORDER == G_BYTE_ORDER):
00705     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ULAW, G_BYTE_ORDER != G_BYTE_ORDER):
00706       do
00707         *dest++ = gsl_ulaw_to_pcm (*i8++) * (1.0 / GSL_ULAW_MAX);
00708       while (dest < bound);
00709       break;
00710     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00711       do
00712         *dest++ = ((*u16++ & 0x0fff) - 2048) * (1. / 2048.);
00713       while (dest < bound);
00714       break;
00715     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00716       do
00717         {
00718           vu16 = *u16++;
00719           *dest++ = ((GUINT16_SWAP_LE_BE (vu16) & 0x0fff) - 2048) * (1. / 2048.);
00720         }
00721       while (dest < bound);
00722       break;
00723     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00724       do
00725         {
00726           vi16 = *i16++;
00727           *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
00728         }
00729       while (dest < bound);
00730       break;
00731     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00732       do
00733         {
00734           vi16 = *i16++;
00735           vi16 = GUINT16_SWAP_LE_BE (vi16);
00736           *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
00737         }
00738       while (dest < bound);
00739       break;
00740     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00741       do
00742         *dest++ = (*u16++ - 32768) * (1. / 32768.);
00743       while (dest < bound);
00744       break;
00745     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00746       do
00747         {
00748           vu16 = *u16++;
00749           *dest++ = (GUINT16_SWAP_LE_BE (vu16) - 32768) * (1. / 32768.);
00750         }
00751       while (dest < bound);
00752       break;
00753     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00754       do
00755         *dest++ = *i16++ * (1. / 32768.);
00756       while (dest < bound);
00757       break;
00758     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00759       do
00760         {
00761           vi16 = *i16++;
00762           *dest++ = GUINT16_SWAP_LE_BE (vi16) * (1. / 32768.);
00763         }
00764       while (dest < bound);
00765       break;
00766     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER == G_BYTE_ORDER):
00767     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER != G_BYTE_ORDER):
00768       if (byte_order == G_LITTLE_ENDIAN)
00769         do
00770           {
00771             gint32 v32 = *u8++;
00772             v32 |= *u8++ << 8;
00773             v32 |= *((gint8*) u8) << 16;
00774             u8++;
00775             *dest++ = v32 * (1. / 8388608.);
00776           }
00777         while (dest < bound);
00778       else /* G_BIG_ENDIAN */
00779         do
00780           {
00781             gint32 v32 = *((gint8*) u8) << 16;
00782             u8++;
00783             v32 |= *u8++ << 8;
00784             v32 |= *u8++;
00785             *dest++ = v32 * (1. / 8388608.);
00786           }
00787         while (dest < bound);
00788       break;
00789     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER == G_BYTE_ORDER):
00790       do
00791         *dest++ = *i32++ * (1. / 8388608.);
00792       while (dest < bound);
00793       break;
00794     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER != G_BYTE_ORDER):
00795       do
00796         {
00797           gint32 vi32 = *i32++;
00798           *dest++ = GUINT32_SWAP_LE_BE (vi32) * (1. / 8388608.);
00799         }
00800       while (dest < bound);
00801       break;
00802     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER == G_BYTE_ORDER):
00803       do
00804         *dest++ = *i32++ * (1. / 2147483648.);
00805       while (dest < bound);
00806       break;
00807     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER != G_BYTE_ORDER):
00808       do
00809         {
00810           gint32 vi32 = *i32++;
00811           *dest++ = GUINT32_SWAP_LE_BE (vi32) * (1. / 2147483648.);
00812         }
00813       while (dest < bound);
00814       break;
00815     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
00816       break;
00817     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
00818       do
00819         {
00820           vu32 = *u32src++;
00821           *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
00822         }
00823       while (u32dest < u32bound);
00824       break;
00825     default:
00826       g_assert_not_reached ();
00827     }
00828 }
00829 
00830 /* same as above with s/float/double */
00831 static inline guint     /* returns number of bytes used in dest */
00832 gsl_conv_from_double (GslWaveFormatType format,
00833                       guint             byte_order,
00834                       const gdouble    *src,
00835                       gpointer          dest,
00836                       guint             n_values)
00837 {
00838   gint8 *i8 = (gint8*) dest;
00839   guint8 *u8 = (guint8*) dest;
00840   gint16 *i16 = (gint16*) dest;
00841   guint16 *u16 = (guint16*) dest;
00842   guint32 *u32dest = (guint32*) dest;
00843   gint32 *i32 = (gint32*) dest;
00844   const gdouble *bound = src + n_values;
00845   const guint32 *u32src = (const guint32*) src, *u32bound = (const guint32*) bound;
00846 
00847   if (!n_values)
00848     return 0;
00849 
00850   switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
00851     {
00852       BseFpuState fpu;
00853       gdouble v;
00854       gint16 vi16;
00855       guint16 vu16;
00856       guint32 vu32;
00857     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00858     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00859       do
00860         *u8++ = bse_dtoi (*src++ * 128. + 128);
00861       while (src < bound);
00862       return n_values;
00863     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
00864     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
00865       bse_fpu_setround (&fpu);
00866       do
00867         {
00868           v = *src++;
00869           v *= 128.;
00870           *i8++ = bse_dtoi (v);
00871         }
00872       while (src < bound);
00873       bse_fpu_restore (fpu);
00874       return n_values;
00875     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00876       do
00877         *u16++ = bse_dtoi (*src++ * 2048. + 2048);
00878       while (src < bound);
00879       return n_values << 1;
00880     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00881       do
00882         {
00883           vu16 = bse_dtoi (*src++ * 2048. + 2048);
00884           *u16++ = GUINT16_SWAP_LE_BE (vu16);
00885         }
00886       while (src < bound);
00887       return n_values << 1;
00888     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
00889       bse_fpu_setround (&fpu);
00890       do
00891         {
00892           v = *src++;
00893           v *= 2048.;
00894           *i16++ = bse_dtoi (v);
00895         }
00896       while (src < bound);
00897       bse_fpu_restore (fpu);
00898       return n_values << 1;
00899     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
00900       bse_fpu_setround (&fpu);
00901       do
00902         {
00903           v = *src++;
00904           v *= 2048.;
00905           vi16 = bse_dtoi (v);
00906           *i16++ = GUINT16_SWAP_LE_BE (vi16);
00907         }
00908       while (src < bound);
00909       bse_fpu_restore (fpu);
00910       return n_values << 1;
00911     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00912       do
00913         *u16++ = bse_dtoi (*src++ * 32768. + 32768);
00914       while (src < bound);
00915       return n_values << 1;
00916     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00917       do
00918         {
00919           vu16 = bse_dtoi (*src++ * 32768. + 32768);
00920           *u16++ = GUINT16_SWAP_LE_BE (vu16);
00921         }
00922       while (src < bound);
00923       return n_values << 1;
00924     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
00925       bse_fpu_setround (&fpu);
00926       do
00927         {
00928           v = *src++;
00929           v *= 32768.;
00930           *i16++ = bse_dtoi (v);
00931         }
00932       while (src < bound);
00933       bse_fpu_restore (fpu);
00934       return n_values << 1;
00935     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
00936       bse_fpu_setround (&fpu);
00937       do
00938         {
00939           v = *src++;
00940           v *= 32768.;
00941           vi16 = bse_dtoi (v);
00942           *i16++ = GUINT16_SWAP_LE_BE (vi16);
00943         }
00944       while (src < bound);
00945       bse_fpu_restore (fpu);
00946       return n_values << 1;
00947     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER == G_BYTE_ORDER):
00948     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER != G_BYTE_ORDER):
00949       bse_fpu_setround (&fpu);
00950       if (byte_order == G_LITTLE_ENDIAN)
00951         do
00952           {
00953             v = *src++;
00954             v *= 8388608.;
00955             gint32 vi32 = bse_dtoi (v);
00956             *u8++ = vi32 >> 0;
00957             *u8++ = vi32 >> 8;
00958             *((gint8*) u8) = vi32 >> 16;
00959             u8++;
00960           }
00961         while (src < bound);
00962       else /* G_BIG_ENDIAN */
00963         do
00964           {
00965             v = *src++;
00966             v *= 8388608.;
00967             gint32 vi32 = bse_dtoi (v);
00968             *((gint8*) u8) = vi32 >> 16;
00969             u8++;
00970             *u8++ = vi32 >> 8;
00971             *u8++ = vi32 >> 0;
00972           }
00973         while (src < bound);
00974       bse_fpu_restore (fpu);
00975       return n_values * 3;
00976     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER == G_BYTE_ORDER):
00977       bse_fpu_setround (&fpu);
00978       do
00979         {
00980           v = *src++;
00981           v *= 8388608.;
00982           *i32++ = bse_dtoi (v);
00983         }
00984       while (src < bound);
00985       bse_fpu_restore (fpu);
00986       return n_values * 4;
00987     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER != G_BYTE_ORDER):
00988       bse_fpu_setround (&fpu);
00989       do
00990         {
00991           v = *src++;
00992           v *= 8388608.;
00993           gint32 vi32 = bse_dtoi (v);
00994           *i32++ = GUINT32_SWAP_LE_BE (vi32);
00995         }
00996       while (src < bound);
00997       bse_fpu_restore (fpu);
00998       return n_values * 4;
00999     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER == G_BYTE_ORDER):
01000       bse_fpu_setround (&fpu);
01001       do
01002         {
01003           v = *src++;
01004           v *= 2147483648.;
01005           *i32++ = bse_dtoi (v);
01006         }
01007       while (src < bound);
01008       bse_fpu_restore (fpu);
01009       return n_values * 4;
01010     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER != G_BYTE_ORDER):
01011       bse_fpu_setround (&fpu);
01012       do
01013         {
01014           v = *src++;
01015           v *= 2147483648.;
01016           gint32 vi32 = bse_dtoi (v);
01017           *i32++ = GUINT32_SWAP_LE_BE (vi32);
01018         }
01019       while (src < bound);
01020       bse_fpu_restore (fpu);
01021       return n_values * 4;
01022     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
01023       return n_values << 2;
01024     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
01025       do
01026         {
01027           vu32 = *u32src++;
01028           *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
01029         }
01030       while (u32src < u32bound);
01031       return n_values << 2;
01032     default:
01033       g_assert_not_reached ();
01034       return 0;
01035     }
01036 }
01037 
01038 static inline guint     /* returns number of bytes used in dest */
01039 gsl_conv_from_double_clip (GslWaveFormatType format,
01040                            guint             byte_order,
01041                            const gdouble    *src,
01042                            gpointer          dest,
01043                            guint             n_values)
01044 {
01045   gint8 *i8 = (gint8*) dest;
01046   guint8 *u8 = (guint8*) dest;
01047   gint16 *i16 = (gint16*) dest;
01048   guint16 *u16 = (guint16*) dest;
01049   guint32 *u32dest = (guint32*) dest;
01050   gint32 *i32 = (gint32*) dest;
01051   const gdouble *bound = src + n_values;
01052   const guint32 *u32src = (const guint32*) src, *u32bound = (const guint32*) bound;
01053 
01054   if (!n_values)
01055     return 0;
01056 
01057   switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
01058     {
01059       BseFpuState fpu;
01060       gdouble v;
01061       guint32 vu32;
01062       gint32 vi32;
01063     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
01064     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
01065       do
01066         {
01067           vi32 = bse_dtoi (*src++ * 128. + 128);
01068           *u8++ = CLAMP (vi32, 0, 255);
01069         }
01070       while (src < bound);
01071       return n_values;
01072     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
01073     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
01074       bse_fpu_setround (&fpu);
01075       do
01076         {
01077           v = *src++;
01078           v *= 128.;
01079           vi32 = bse_dtoi (v);
01080           *i8++ = CLAMP (vi32, -128, 127);
01081         }
01082       while (src < bound);
01083       bse_fpu_restore (fpu);
01084       return n_values;
01085     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
01086       do
01087         {
01088           vi32 = bse_dtoi (*src++ * 2048. + 2048);
01089           *u16++ = CLAMP (vi32, 0, 4095);
01090         }
01091       while (src < bound);
01092       return n_values << 1;
01093     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
01094       do
01095         {
01096           vi32 = bse_dtoi (*src++ * 2048. + 2048);
01097           vi32 = CLAMP (vi32, 0, 4095);
01098           *u16++ = GUINT16_SWAP_LE_BE (vi32);
01099         }
01100       while (src < bound);
01101       return n_values << 1;
01102     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
01103       bse_fpu_setround (&fpu);
01104       do
01105         {
01106           v = *src++;
01107           v *= 2048.;
01108           vi32 = bse_dtoi (v);
01109           *i16++ = CLAMP (vi32, -2048, 2047);
01110         }
01111       while (src < bound);
01112       bse_fpu_restore (fpu);
01113       return n_values << 1;
01114     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
01115       bse_fpu_setround (&fpu);
01116       do
01117         {
01118           v = *src++;
01119           v *= 2048.;
01120           vi32 = bse_dtoi (v);
01121           vi32 = CLAMP (vi32, -2048, 2047);
01122           *i16++ = GUINT16_SWAP_LE_BE (vi32);
01123         }
01124       while (src < bound);
01125       bse_fpu_restore (fpu);
01126       return n_values << 1;
01127     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
01128       do
01129         {
01130           vi32 = bse_dtoi (*src++ * 32768. + 32768);
01131           *u16++ = CLAMP (vi32, 0, 65535);
01132         }
01133       while (src < bound);
01134       return n_values << 1;
01135     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
01136       do
01137         {
01138           vi32 = bse_dtoi (*src++ * 32768. + 32768);
01139           vi32 = CLAMP (vi32, 0, 65535);
01140           *u16++ = GUINT16_SWAP_LE_BE (vi32);
01141         }
01142       while (src < bound);
01143       return n_values << 1;
01144     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
01145       bse_fpu_setround (&fpu);
01146       do
01147         {
01148           v = *src++;
01149           v *= 32768.;
01150           vi32 = bse_dtoi (v);
01151           vi32 = CLAMP (vi32, -32768, 32767);
01152           *i16++ = vi32;
01153         }
01154       while (src < bound);
01155       bse_fpu_restore (fpu);
01156       return n_values << 1;
01157     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
01158       bse_fpu_setround (&fpu);
01159       do
01160         {
01161           v = *src++;
01162           v *= 32768.;
01163           vi32 = bse_dtoi (v);
01164           vi32 = CLAMP (vi32, -32768, 32767);
01165           *i16++ = GUINT16_SWAP_LE_BE (vi32);
01166         }
01167       while (src < bound);
01168       bse_fpu_restore (fpu);
01169       return n_values << 1;
01170     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER == G_BYTE_ORDER):
01171     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER != G_BYTE_ORDER):
01172       bse_fpu_setround (&fpu);
01173       if (byte_order == G_LITTLE_ENDIAN)
01174         do
01175           {
01176             v = *src++;
01177             v *= 8388608.;
01178             gint32 vi32 = bse_dtoi (v);
01179             vi32 = CLAMP (vi32, -8388608, 8388607);
01180             *u8++ = vi32 >> 0;
01181             *u8++ = vi32 >> 8;
01182             *((gint8*) u8) = vi32 >> 16;
01183             u8++;
01184           }
01185         while (src < bound);
01186       else /* G_BIG_ENDIAN */
01187         do
01188           {
01189             v = *src++;
01190             v *= 8388608.;
01191             gint32 vi32 = bse_dtoi (v);
01192             vi32 = CLAMP (vi32, -8388608, 8388607);
01193             *((gint8*) u8) = vi32 >> 16;
01194             u8++;
01195             *u8++ = vi32 >> 8;
01196             *u8++ = vi32 >> 0;
01197           }
01198         while (src < bound);
01199       bse_fpu_restore (fpu);
01200       return n_values * 3;
01201     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER == G_BYTE_ORDER):
01202       bse_fpu_setround (&fpu);
01203       do
01204         {
01205           v = *src++;
01206           v *= 8388608.;
01207           vi32 = bse_dtoi (v);
01208           vi32 = CLAMP (vi32, -8388608, 8388607);
01209           *i32++ = vi32;
01210         }
01211       while (src < bound);
01212       bse_fpu_restore (fpu);
01213       return n_values * 4;
01214     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER != G_BYTE_ORDER):
01215       bse_fpu_setround (&fpu);
01216       do
01217         {
01218           v = *src++;
01219           v *= 8388608.;
01220           vi32 = bse_dtoi (v);
01221           vi32 = CLAMP (vi32, -8388608, 8388607);
01222           *i32++ = GUINT32_SWAP_LE_BE (vi32);
01223         }
01224       while (src < bound);
01225       bse_fpu_restore (fpu);
01226       return n_values * 4;
01227     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER == G_BYTE_ORDER):
01228       bse_fpu_setround (&fpu);
01229       do
01230         {
01231           v = *src++;
01232           v *= 2147483648.;
01233           vi32 = bse_dtoi (v);
01234           // vi32 = CLAMP (vi32, -2147483648, 2147483647);
01235           *i32++ = vi32;
01236         }
01237       while (src < bound);
01238       bse_fpu_restore (fpu);
01239       return n_values * 4;
01240     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER != G_BYTE_ORDER):
01241       bse_fpu_setround (&fpu);
01242       do
01243         {
01244           v = *src++;
01245           v *= 2147483648.;
01246           vi32 = bse_dtoi (v);
01247           // vi32 = CLAMP (vi32, -2147483648, 2147483647);
01248           *i32++ = GUINT32_SWAP_LE_BE (vi32);
01249         }
01250       while (src < bound);
01251       bse_fpu_restore (fpu);
01252       return n_values * 4;
01253     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
01254       return n_values << 2;
01255     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
01256       do
01257         {
01258           vu32 = *u32src++;
01259           *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
01260         }
01261       while (u32src < u32bound);
01262       return n_values << 2;
01263     default:
01264       g_assert_not_reached ();
01265       return 0;
01266     }
01267 }
01268 
01269 static inline void
01270 gsl_conv_to_double (GslWaveFormatType format,
01271                     guint             byte_order,
01272                     gconstpointer     src,
01273                     gdouble          *dest,
01274                     guint             n_values)
01275 {
01276   const guint8 *u8 = (guint8*) src;
01277   const gint8 *i8 = (gint8*) src;
01278   const guint16 *u16 = (guint16*) src;
01279   const gint16 *i16 = (gint16*) src;
01280   const guint32 *u32src = (guint32*) src;
01281   const gint32 *i32 = (gint32*) src;
01282   gdouble *bound = dest + n_values;
01283   guint32 *u32dest = (guint32*) dest, *u32bound = (guint32*) bound;
01284 
01285   if (!n_values)
01286     return;
01287 
01288   switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER))
01289     {
01290       gint16 vi16;
01291       guint16 vu16;
01292       guint32 vu32;
01293     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
01294     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
01295       do
01296         *dest++ = (*u8++ - 128) * (1. / 128.);
01297       while (dest < bound);
01298       break;
01299     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER):
01300     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER):
01301       do
01302         *dest++ = *i8++ * (1. / 128.);
01303       while (dest < bound);
01304       break;
01305     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ALAW, G_BYTE_ORDER == G_BYTE_ORDER):
01306     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ALAW, G_BYTE_ORDER != G_BYTE_ORDER):
01307       do
01308         *dest++ = gsl_alaw_to_pcm (*i8++) * (1.0 / GSL_ALAW_MAX);
01309       while (dest < bound);
01310       break;
01311     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ULAW, G_BYTE_ORDER == G_BYTE_ORDER):
01312     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_ULAW, G_BYTE_ORDER != G_BYTE_ORDER):
01313       do
01314         *dest++ = gsl_ulaw_to_pcm (*i8++) * (1.0 / GSL_ULAW_MAX);
01315       while (dest < bound);
01316       break;
01317     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
01318       do
01319         *dest++ = ((*u16++ & 0x0fff) - 2048) * (1. / 2048.);
01320       while (dest < bound);
01321       break;
01322     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
01323       do
01324         {
01325           vu16 = *u16++;
01326           *dest++ = ((GUINT16_SWAP_LE_BE (vu16) & 0x0fff) - 2048) * (1. / 2048.);
01327         }
01328       while (dest < bound);
01329       break;
01330     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER):
01331       do
01332         {
01333           vi16 = *i16++;
01334           *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
01335         }
01336       while (dest < bound);
01337       break;
01338     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER):
01339       do
01340         {
01341           vi16 = *i16++;
01342           vi16 = GUINT16_SWAP_LE_BE (vi16);
01343           *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.);
01344         }
01345       while (dest < bound);
01346       break;
01347     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
01348       do
01349         *dest++ = (*u16++ - 32768) * (1. / 32768.);
01350       while (dest < bound);
01351       break;
01352     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
01353       do
01354         {
01355           vu16 = *u16++;
01356           *dest++ = (GUINT16_SWAP_LE_BE (vu16) - 32768) * (1. / 32768.);
01357         }
01358       while (dest < bound);
01359       break;
01360     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER):
01361       do
01362         *dest++ = *i16++ * (1. / 32768.);
01363       while (dest < bound);
01364       break;
01365     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER):
01366       do
01367         {
01368           vi16 = *i16++;
01369           *dest++ = GUINT16_SWAP_LE_BE (vi16) * (1. / 32768.);
01370         }
01371       while (dest < bound);
01372       break;
01373     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER == G_BYTE_ORDER):
01374     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24, G_BYTE_ORDER != G_BYTE_ORDER):
01375       if (byte_order == G_LITTLE_ENDIAN)
01376         do
01377           {
01378             gint32 v32 = *u8++;
01379             v32 |= *u8++ << 8;
01380             v32 |= *((gint8*) u8) << 16;
01381             u8++;
01382             *dest++ = v32 * (1. / 8388608.);
01383           }
01384         while (dest < bound);
01385       else /* G_BIG_ENDIAN */
01386         do
01387           {
01388             gint32 v32 = *((gint8*) u8) << 16;
01389             u8++;
01390             v32 |= *u8++ << 8;
01391             v32 |= *u8++;
01392             *dest++ = v32 * (1. / 8388608.);
01393           }
01394         while (dest < bound);
01395       break;
01396     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER == G_BYTE_ORDER):
01397       do
01398         *dest++ = *i32++ * (1. / 8388608.);
01399       while (dest < bound);
01400       break;
01401     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_24_PAD4, G_BYTE_ORDER != G_BYTE_ORDER):
01402       do
01403         {
01404           gint32 vi32 = *i32++;
01405           *dest++ = GUINT32_SWAP_LE_BE (vi32) * (1. / 8388608.);
01406         }
01407       while (dest < bound);
01408       break;
01409     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER == G_BYTE_ORDER):
01410       do
01411         *dest++ = *i32++ * (1. / 2147483648.);
01412       while (dest < bound);
01413       break;
01414     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_32, G_BYTE_ORDER != G_BYTE_ORDER):
01415       do
01416         {
01417           gint32 vi32 = *i32++;
01418           *dest++ = GUINT32_SWAP_LE_BE (vi32) * (1. / 2147483648.);
01419         }
01420       while (dest < bound);
01421       break;
01422     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER):
01423       break;
01424     case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER):
01425       do
01426         {
01427           vu32 = *u32src++;
01428           *u32dest++ = GUINT32_SWAP_LE_BE (vu32);
01429         }
01430       while (u32dest < u32bound);
01431       break;
01432     default:
01433       g_assert_not_reached ();
01434     }
01435 }
01436 
01437 G_END_DECLS
01438 
01439 #endif /* __GSL_DATA_UTILS_H__ */
01440 
01441 /* vim:set ts=8 sts=2 sw=2: */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines