Audacious
$Id:Doxyfile42802007-03-2104:39:00Znenolod$
|
00001 /* 00002 * audio.c 00003 * Copyright 2009 John Lindgren 00004 * 00005 * This file is part of Audacious. 00006 * 00007 * Audacious is free software: you can redistribute it and/or modify it under 00008 * the terms of the GNU General Public License as published by the Free Software 00009 * Foundation, version 2 or version 3 of the License. 00010 * 00011 * Audacious is distributed in the hope that it will be useful, but WITHOUT ANY 00012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR 00013 * A PARTICULAR PURPOSE. See the GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along with 00016 * Audacious. If not, see <http://www.gnu.org/licenses/>. 00017 * 00018 * The Audacious team does not consider modular code linking to Audacious or 00019 * using our public API to be a derived work. 00020 */ 00021 00022 #include <glib.h> 00023 00024 #include "audio.h" 00025 00026 #define FROM_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE) \ 00027 static void NAME (TYPE * in, gfloat * out, gint samples) \ 00028 { \ 00029 TYPE * end = in + samples; \ 00030 while (in < end) \ 00031 * out ++ = (TYPE) (SWAP (* in ++) - OFFSET) / (gdouble) RANGE; \ 00032 } 00033 00034 #define TO_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE) \ 00035 static void NAME (gfloat * in, TYPE * out, gint samples) \ 00036 { \ 00037 gfloat * end = in + samples; \ 00038 while (in < end) \ 00039 { \ 00040 gdouble f = * in ++; \ 00041 * out ++ = SWAP (OFFSET + (TYPE) (CLAMP (f, -1, 1) * (gdouble) RANGE)); \ 00042 } \ 00043 } 00044 00045 static inline gint8 noop8 (gint8 i) {return i;} 00046 static inline gint16 noop16 (gint16 i) {return i;} 00047 static inline gint32 noop32 (gint32 i) {return i;} 00048 00049 FROM_INT_LOOP (from_s8, gint8, noop8, 0x00, 0x7f) 00050 FROM_INT_LOOP (from_u8, gint8, noop8, 0x80, 0x7f) 00051 FROM_INT_LOOP (from_s16, gint16, noop16, 0x0000, 0x7fff) 00052 FROM_INT_LOOP (from_u16, gint16, noop16, 0x8000, 0x7fff) 00053 FROM_INT_LOOP (from_s24, gint32, noop32, 0x000000, 0x7fffff) 00054 FROM_INT_LOOP (from_u24, gint32, noop32, 0x800000, 0x7fffff) 00055 FROM_INT_LOOP (from_s32, gint32, noop32, 0x00000000, 0x7fffffff) 00056 FROM_INT_LOOP (from_u32, gint32, noop32, 0x80000000, 0x7fffffff) 00057 00058 TO_INT_LOOP (to_s8, gint8, noop8, 0x00, 0x7f) 00059 TO_INT_LOOP (to_u8, gint8, noop8, 0x80, 0x7f) 00060 TO_INT_LOOP (to_s16, gint16, noop16, 0x0000, 0x7fff) 00061 TO_INT_LOOP (to_u16, gint16, noop16, 0x8000, 0x7fff) 00062 TO_INT_LOOP (to_s24, gint32, noop32, 0x000000, 0x7fffff) 00063 TO_INT_LOOP (to_u24, gint32, noop32, 0x800000, 0x7fffff) 00064 TO_INT_LOOP (to_s32, gint32, noop32, 0x00000000, 0x7fffffff) 00065 TO_INT_LOOP (to_u32, gint32, noop32, 0x80000000, 0x7fffffff) 00066 00067 static inline gint16 swap16 (gint16 i) {return GUINT16_SWAP_LE_BE (i);} 00068 static inline gint32 swap32 (gint32 i) {return GUINT32_SWAP_LE_BE (i);} 00069 00070 FROM_INT_LOOP (from_s16_swap, gint16, swap16, 0x0000, 0x7fff) 00071 FROM_INT_LOOP (from_u16_swap, gint16, swap16, 0x8000, 0x7fff) 00072 FROM_INT_LOOP (from_s24_swap, gint32, swap32, 0x000000, 0x7fffff) 00073 FROM_INT_LOOP (from_u24_swap, gint32, swap32, 0x800000, 0x7fffff) 00074 FROM_INT_LOOP (from_s32_swap, gint32, swap32, 0x00000000, 0x7fffffff) 00075 FROM_INT_LOOP (from_u32_swap, gint32, swap32, 0x80000000, 0x7fffffff) 00076 00077 TO_INT_LOOP (to_s16_swap, gint16, swap16, 0x0000, 0x7fff) 00078 TO_INT_LOOP (to_u16_swap, gint16, swap16, 0x8000, 0x7fff) 00079 TO_INT_LOOP (to_s24_swap, gint32, swap32, 0x000000, 0x7fffff) 00080 TO_INT_LOOP (to_u24_swap, gint32, swap32, 0x800000, 0x7fffff) 00081 TO_INT_LOOP (to_s32_swap, gint32, swap32, 0x00000000, 0x7fffffff) 00082 TO_INT_LOOP (to_u32_swap, gint32, swap32, 0x80000000, 0x7fffffff) 00083 00084 typedef void (* FromFunc) (void * in, gfloat * out, gint samples); 00085 typedef void (* ToFunc) (gfloat * in, void * out, gint samples); 00086 00087 struct 00088 { 00089 gint format; 00090 FromFunc from; 00091 ToFunc to; 00092 } 00093 convert_table [] = 00094 { 00095 {FMT_S8, (FromFunc) from_s8, (ToFunc) to_s8}, 00096 {FMT_U8, (FromFunc) from_u8, (ToFunc) to_u8}, 00097 00098 #if G_BYTE_ORDER == G_LITTLE_ENDIAN 00099 {FMT_S16_LE, (FromFunc) from_s16, (ToFunc) to_s16}, 00100 {FMT_U16_LE, (FromFunc) from_u16, (ToFunc) to_u16}, 00101 {FMT_S24_LE, (FromFunc) from_s24, (ToFunc) to_s24}, 00102 {FMT_U24_LE, (FromFunc) from_u24, (ToFunc) to_u24}, 00103 {FMT_S32_LE, (FromFunc) from_s32, (ToFunc) to_s32}, 00104 {FMT_U32_LE, (FromFunc) from_u32, (ToFunc) to_u32}, 00105 00106 {FMT_S16_BE, (FromFunc) from_s16_swap, (ToFunc) to_s16_swap}, 00107 {FMT_U16_BE, (FromFunc) from_u16_swap, (ToFunc) to_u16_swap}, 00108 {FMT_S24_BE, (FromFunc) from_s24_swap, (ToFunc) to_s24_swap}, 00109 {FMT_U24_BE, (FromFunc) from_u24_swap, (ToFunc) to_u24_swap}, 00110 {FMT_S32_BE, (FromFunc) from_s32_swap, (ToFunc) to_s32_swap}, 00111 {FMT_U32_BE, (FromFunc) from_u32_swap, (ToFunc) to_u32_swap}, 00112 #else 00113 {FMT_S16_BE, (FromFunc) from_s16, (ToFunc) to_s16}, 00114 {FMT_U16_BE, (FromFunc) from_u16, (ToFunc) to_u16}, 00115 {FMT_S24_BE, (FromFunc) from_s24, (ToFunc) to_s24}, 00116 {FMT_U24_BE, (FromFunc) from_u24, (ToFunc) to_u24}, 00117 {FMT_S32_BE, (FromFunc) from_s32, (ToFunc) to_s32}, 00118 {FMT_U32_BE, (FromFunc) from_u32, (ToFunc) to_u32}, 00119 00120 {FMT_S16_LE, (FromFunc) from_s16_swap, (ToFunc) to_s16_swap}, 00121 {FMT_U16_LE, (FromFunc) from_u16_swap, (ToFunc) to_u16_swap}, 00122 {FMT_S24_LE, (FromFunc) from_s24_swap, (ToFunc) to_s24_swap}, 00123 {FMT_U24_LE, (FromFunc) from_u24_swap, (ToFunc) to_u24_swap}, 00124 {FMT_S32_LE, (FromFunc) from_s32_swap, (ToFunc) to_s32_swap}, 00125 {FMT_U32_LE, (FromFunc) from_u32_swap, (ToFunc) to_u32_swap}, 00126 #endif 00127 }; 00128 00129 void audio_from_int (void * in, gint format, gfloat * out, gint samples) 00130 { 00131 gint entry; 00132 00133 for (entry = 0; entry < G_N_ELEMENTS (convert_table); entry ++) 00134 { 00135 if (convert_table[entry].format == format) 00136 { 00137 convert_table[entry].from (in, out, samples); 00138 return; 00139 } 00140 } 00141 } 00142 00143 void audio_to_int (gfloat * in, void * out, gint format, gint samples) 00144 { 00145 gint entry; 00146 00147 for (entry = 0; entry < G_N_ELEMENTS (convert_table); entry ++) 00148 { 00149 if (convert_table[entry].format == format) 00150 { 00151 convert_table[entry].to (in, out, samples); 00152 return; 00153 } 00154 } 00155 } 00156 00157 void audio_amplify (gfloat * data, gint channels, gint frames, gfloat * factors) 00158 { 00159 gfloat * end = data + channels * frames; 00160 gint channel; 00161 00162 while (data < end) 00163 { 00164 for (channel = 0; channel < channels; channel ++) 00165 { 00166 * data = * data * factors[channel]; 00167 data ++; 00168 } 00169 } 00170 }