diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-05 00:01:18 +0000 |
commit | 42995d7bf396933ee60c5f89c354ea89cf13df0d (patch) | |
tree | cfdcea0ac57420e7baf570bfe435e107bb842541 /flow/gsl/gsldatautils.h | |
download | arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.tar.gz arts-42995d7bf396933ee60c5f89c354ea89cf13df0d.zip |
Copy of aRts for Trinity modifications
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/dependencies/arts@1070145 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'flow/gsl/gsldatautils.h')
-rw-r--r-- | flow/gsl/gsldatautils.h | 909 |
1 files changed, 909 insertions, 0 deletions
diff --git a/flow/gsl/gsldatautils.h b/flow/gsl/gsldatautils.h new file mode 100644 index 0000000..0dea8c9 --- /dev/null +++ b/flow/gsl/gsldatautils.h @@ -0,0 +1,909 @@ +/* GSL - Generic Sound Layer + * Copyright (C) 2001-2002 Stefan Westerfeld and Tim Janik + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser 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. + */ +#ifndef __GSL_DATA_UTILS_H__ +#define __GSL_DATA_UTILS_H__ + +#include <gsl/gslmath.h> +#include <gsl/gsldatahandle.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + + +/* --- structures --- */ +#define GSL_DATA_HANDLE_PEEK_BUFFER (8192) +typedef struct +{ + gint dir; /* initialize direction to -1 or +1 (or 0 for random access) */ + GslLong start; /* initialize to 0 */ + GslLong end; /* initialize to 0 */ + gfloat data[GSL_DATA_HANDLE_PEEK_BUFFER]; +} GslDataPeekBuffer; +typedef struct +{ + GslLong head_skip; /* FIXME: remove this */ + GslLong tail_cut; + GslLong min_loop; + GslLong max_loop; +} GslLoopSpec; /* rename this to ...Data... */ + + +/* --- data utils --- */ +gboolean gsl_data_detect_signal (GslDataHandle *handle, + GslLong *sigstart, + GslLong *sigend); +GslLong gsl_data_find_sample (GslDataHandle *dhandle, + gfloat min_value, + gfloat max_value, + GslLong start_offset, + gint direction); +gboolean gsl_data_find_tailmatch (GslDataHandle *dhandle, + const GslLoopSpec *lspec, + GslLong *loop_start_p, + GslLong *loop_end_p); +GslLong gsl_data_find_block (GslDataHandle *handle, + guint n_values, + const gfloat *values, + gfloat epsilon); + + +/* --- data handle utils --- */ +static inline gfloat gsl_data_handle_peek_value (GslDataHandle *dhandle, + GslLong position, + GslDataPeekBuffer *peekbuf); +gint /* errno */ gsl_data_handle_dump (GslDataHandle *dhandle, + gint fd, + GslWaveFormatType format, + guint byte_order); +gint /* errno */ gsl_data_handle_dump_wav (GslDataHandle *dhandle, + gint fd, + guint n_bits, + guint n_channels, + guint sample_freq); + + +/* --- conversion utils --- */ +static inline guint gsl_conv_from_float (GslWaveFormatType format, + guint byte_order, + const gfloat *src, + gpointer dest, + guint n_values); +static inline guint gsl_conv_from_float_clip (GslWaveFormatType format, + guint byte_order, + const gfloat *src, + gpointer dest, + guint n_values); +static inline void gsl_conv_to_float (GslWaveFormatType format, + guint byte_order, + gconstpointer src, + gfloat *dest, + guint n_values); +static inline guint gsl_conv_from_double (GslWaveFormatType format, + guint byte_order, + const gdouble *src, + gpointer dest, + guint n_values); +static inline guint gsl_conv_from_double_clip (GslWaveFormatType format, + guint byte_order, + const gdouble *src, + gpointer dest, + guint n_values); +static inline void gsl_conv_to_double (GslWaveFormatType format, + guint byte_order, + gconstpointer src, + gdouble *dest, + guint n_values); + + + +/* --- misc implementations --- */ +gfloat gsl_data_peek_value_f (GslDataHandle *dhandle, + GslLong pos, + GslDataPeekBuffer *peekbuf); + +static inline gfloat +gsl_data_handle_peek_value (GslDataHandle *dhandle, + GslLong position, + GslDataPeekBuffer *peekbuf) +{ + return (position >= peekbuf->start && position < peekbuf->end ? + peekbuf->data[position - peekbuf->start] : + gsl_data_peek_value_f (dhandle, position, peekbuf)); +} + +#define GSL_CONV_FORMAT(format, endian_flag) (((endian_flag) << 16) | ((format) & 0xffff)) + +static inline guint /* returns number of bytes used in dest */ +gsl_conv_from_float (GslWaveFormatType format, + guint byte_order, + const gfloat *src, + gpointer dest, + guint n_values) +{ + gint8 *i8 = (gint8*) dest; + guint8 *u8 = (guint8*) dest; + gint16 *i16 = (gint16*) dest; + guint16 *u16 = (guint16*) dest; + guint32 *u32dest = (guint32*) dest; + const gfloat *bound = src + n_values; + guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound; + + if (!n_values) + return 0; + + switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER)) + { + GslFpuState fpu; + gfloat v; + gint16 vi16; + guint16 vu16; + guint32 vu32; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + *u8++ = *src++ * 128. + 128.5; + while (src < bound); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 128.; + *i8++ = gsl_ftoi (v); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + *u16++ = *src++ * 2048. + 2048.5; + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *src++ * 2048. + 2048.5; + *u16++ = GUINT16_SWAP_LE_BE (vu16); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + *i16++ = gsl_ftoi (v); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + vi16 = gsl_ftoi (v); + *i16++ = GUINT16_SWAP_LE_BE (vi16); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + *u16++ = *src++ * 32768. + 32768.5; + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *src++ * 32768. + 32768.5; + *u16++ = GUINT16_SWAP_LE_BE (vu16); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + *i16++ = gsl_ftoi (v); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + vi16 = gsl_ftoi (v); + *i16++ = GUINT16_SWAP_LE_BE (vi16); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER): + return n_values << 2; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu32 = *u32src++; + *u32dest++ = GUINT32_SWAP_LE_BE (vu32); + } + while (u32src < u32bound); + return n_values << 2; + default: + g_assert_not_reached (); + return 0; + } +} + +static inline guint /* returns number of bytes used in dest */ +gsl_conv_from_float_clip (GslWaveFormatType format, + guint byte_order, + const gfloat *src, + gpointer dest, + guint n_values) +{ + gint8 *i8 = (gint8*) dest; + guint8 *u8 = (guint8*) dest; + gint16 *i16 = (gint16*) dest; + guint16 *u16 = (guint16*) dest; + guint32 *u32dest = (guint32*) dest; + const gfloat *bound = src + n_values; + guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound; + + if (!n_values) + return 0; + + switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER)) + { + GslFpuState fpu; + gfloat v; + guint32 vu32; + gint32 vi32; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi32 = *src++ * 128. + 128.5; + *u8++ = CLAMP (vi32, 0, 255); + } + while (src < bound); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 128.; + vi32 = gsl_ftoi (v); + *i8++ = CLAMP (vi32, -128, 127); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + { + vi32 = *src++ * 2048. + 2048.5; + *u16++ = CLAMP (vi32, 0, 4095); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi32 = *src++ * 2048. + 2048.5; + vi32 = CLAMP (vi32, 0, 4095); + *u16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + vi32 = gsl_ftoi (v); + *i16++ = CLAMP (vi32, -2048, 2047); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + vi32 = gsl_ftoi (v); + vi32 = CLAMP (vi32, -2048, 2047); + *i16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + { + vi32 = *src++ * 32768. + 32768.5; + *u16++ = CLAMP (vi32, 0, 65535); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi32 = *src++ * 32768. + 32768.5; + vi32 = CLAMP (vi32, 0, 65535); + *u16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + vi32 = gsl_ftoi (v); + vi32 = CLAMP (vi32, -32768, 32767); + *i16++ = vi32; + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + vi32 = gsl_ftoi (v); + vi32 = CLAMP (vi32, -32768, 32767); + *i16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER): + return n_values << 2; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu32 = *u32src++; + *u32dest++ = GUINT32_SWAP_LE_BE (vu32); + } + while (u32src < u32bound); + return n_values << 2; + default: + g_assert_not_reached (); + return 0; + } +} + +static inline void +gsl_conv_to_float (GslWaveFormatType format, + guint byte_order, + gconstpointer src, + gfloat *dest, + guint n_values) +{ + guint8 *u8 = (guint8*) src; + gint8 *i8 = (gint8*) src; + guint16 *u16 = (guint16*) src; + gint16 *i16 = (gint16*) src; + guint32 *u32src = (guint32*) src; + gfloat *bound = dest + n_values; + guint32 *u32dest = (guint32*) dest, *u32bound = (guint32*) bound; + + if (!n_values) + return; + + switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER)) + { + gint16 vi16; + guint16 vu16; + guint32 vu32; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + *dest++ = (*u8++ - 128) * (1. / 128.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + *dest++ = *i8++ * (1. / 128.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + *dest++ = ((*u16++ & 0x0fff) - 2048) * (1. / 2048.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *u16++; + *dest++ = ((GUINT16_SWAP_LE_BE (vu16) & 0x0fff) - 2048) * (1. / 2048.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + { + vi16 = *i16++; + *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi16 = *i16++; + vi16 = GUINT16_SWAP_LE_BE (vi16); + *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + *dest++ = (*u16++ - 32768) * (1. / 32768.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *u16++; + *dest++ = (GUINT16_SWAP_LE_BE (vu16) - 32768) * (1. / 32768.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + *dest++ = *i16++ * (1. / 32768.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi16 = *i16++; + *dest++ = GUINT16_SWAP_LE_BE (vi16) * (1. / 32768.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER): + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu32 = *u32src++; + *u32dest++ = GUINT32_SWAP_LE_BE (vu32); + } + while (u32dest < u32bound); + break; + default: + g_assert_not_reached (); + } +} + +/* same as above with s/float/double */ +static inline guint /* returns number of bytes used in dest */ +gsl_conv_from_double (GslWaveFormatType format, + guint byte_order, + const gdouble *src, + gpointer dest, + guint n_values) +{ + gint8 *i8 = (gint8*) dest; + guint8 *u8 = (guint8*) dest; + gint16 *i16 = (gint16*) dest; + guint16 *u16 = (guint16*) dest; + guint32 *u32dest = (guint32*) dest; + const gdouble *bound = src + n_values; + guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound; + + if (!n_values) + return 0; + + switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER)) + { + GslFpuState fpu; + gdouble v; + gint16 vi16; + guint16 vu16; + guint32 vu32; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + *u8++ = *src++ * 128. + 128.5; + while (src < bound); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 128.; + *i8++ = gsl_ftoi (v); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + *u16++ = *src++ * 2048. + 2048.5; + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *src++ * 2048. + 2048.5; + *u16++ = GUINT16_SWAP_LE_BE (vu16); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + *i16++ = gsl_ftoi (v); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + vi16 = gsl_ftoi (v); + *i16++ = GUINT16_SWAP_LE_BE (vi16); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + *u16++ = *src++ * 32768. + 32768.5; + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *src++ * 32768. + 32768.5; + *u16++ = GUINT16_SWAP_LE_BE (vu16); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + *i16++ = gsl_ftoi (v); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + vi16 = gsl_ftoi (v); + *i16++ = GUINT16_SWAP_LE_BE (vi16); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER): + return n_values << 2; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu32 = *u32src++; + *u32dest++ = GUINT32_SWAP_LE_BE (vu32); + } + while (u32src < u32bound); + return n_values << 2; + default: + g_assert_not_reached (); + return 0; + } +} + +static inline guint /* returns number of bytes used in dest */ +gsl_conv_from_double_clip (GslWaveFormatType format, + guint byte_order, + const gdouble *src, + gpointer dest, + guint n_values) +{ + gint8 *i8 = (gint8*) dest; + guint8 *u8 = (guint8*) dest; + gint16 *i16 = (gint16*) dest; + guint16 *u16 = (guint16*) dest; + guint32 *u32dest = (guint32*) dest; + const gdouble *bound = src + n_values; + guint32 *u32src = (guint32*) src, *u32bound = (guint32*) bound; + + if (!n_values) + return 0; + + switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER)) + { + GslFpuState fpu; + gdouble v; + guint32 vu32; + gint32 vi32; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi32 = *src++ * 128. + 128.5; + *u8++ = CLAMP (vi32, 0, 255); + } + while (src < bound); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 128.; + vi32 = gsl_ftoi (v); + *i8++ = CLAMP (vi32, -128, 127); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + { + vi32 = *src++ * 2048. + 2048.5; + *u16++ = CLAMP (vi32, 0, 4095); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi32 = *src++ * 2048. + 2048.5; + vi32 = CLAMP (vi32, 0, 4095); + *u16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + vi32 = gsl_ftoi (v); + *i16++ = CLAMP (vi32, -2048, 2047); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 2048.; + vi32 = gsl_ftoi (v); + vi32 = CLAMP (vi32, -2048, 2047); + *i16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + { + vi32 = *src++ * 32768. + 32768.5; + *u16++ = CLAMP (vi32, 0, 65535); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi32 = *src++ * 32768. + 32768.5; + vi32 = CLAMP (vi32, 0, 65535); + *u16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + vi32 = gsl_ftoi (v); + vi32 = CLAMP (vi32, -32768, 32767); + *i16++ = vi32; + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + gsl_fpu_setround (&fpu); + do + { + v = *src++; + v *= 32768.; + vi32 = gsl_ftoi (v); + vi32 = CLAMP (vi32, -32768, 32767); + *i16++ = GUINT16_SWAP_LE_BE (vi32); + } + while (src < bound); + gsl_fpu_restore (fpu); + return n_values << 1; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER): + return n_values << 2; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu32 = *u32src++; + *u32dest++ = GUINT32_SWAP_LE_BE (vu32); + } + while (u32src < u32bound); + return n_values << 2; + default: + g_assert_not_reached (); + return 0; + } +} + +static inline void +gsl_conv_to_double (GslWaveFormatType format, + guint byte_order, + gconstpointer src, + gdouble *dest, + guint n_values) +{ + guint8 *u8 = (guint8*) src; + gint8 *i8 = (gint8*) src; + guint16 *u16 = (guint16*) src; + gint16 *i16 = (gint16*) src; + guint32 *u32src = (guint32*) src; + gdouble *bound = dest + n_values; + guint32 *u32dest = (guint32*) dest, *u32bound = (guint32*) bound; + + if (!n_values) + return; + + switch (GSL_CONV_FORMAT (format, byte_order == G_BYTE_ORDER)) + { + gint16 vi16; + guint16 vu16; + guint32 vu32; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + *dest++ = (*u8++ - 128) * (1. / 128.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER == G_BYTE_ORDER): + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_8, G_BYTE_ORDER != G_BYTE_ORDER): + do + *dest++ = *i8++ * (1. / 128.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + *dest++ = ((*u16++ & 0x0fff) - 2048) * (1. / 2048.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *u16++; + *dest++ = ((GUINT16_SWAP_LE_BE (vu16) & 0x0fff) - 2048) * (1. / 2048.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER == G_BYTE_ORDER): + do + { + vi16 = *i16++; + *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_12, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi16 = *i16++; + vi16 = GUINT16_SWAP_LE_BE (vi16); + *dest++ = CLAMP (vi16, -2048, 2048) * (1. / 2048.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + *dest++ = (*u16++ - 32768) * (1. / 32768.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_UNSIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu16 = *u16++; + *dest++ = (GUINT16_SWAP_LE_BE (vu16) - 32768) * (1. / 32768.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER == G_BYTE_ORDER): + do + *dest++ = *i16++ * (1. / 32768.); + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_SIGNED_16, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vi16 = *i16++; + *dest++ = GUINT16_SWAP_LE_BE (vi16) * (1. / 32768.); + } + while (dest < bound); + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER == G_BYTE_ORDER): + break; + case GSL_CONV_FORMAT (GSL_WAVE_FORMAT_FLOAT, G_BYTE_ORDER != G_BYTE_ORDER): + do + { + vu32 = *u32src++; + *u32dest++ = GUINT32_SWAP_LE_BE (vu32); + } + while (u32dest < u32bound); + break; + default: + g_assert_not_reached (); + } +} + + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GSL_DATA_UTILS_H__ */ + +/* vim:set ts=8 sts=2 sw=2: */ |