Audacious  $Id:Doxyfile42802007-03-2104:39:00Znenolod$
audio.c
Go to the documentation of this file.
1 /*
2  * audio.c
3  * Copyright 2009-2012 John Lindgren, MichaƂ Lipski, and Anders Johansson
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions, and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions, and the following disclaimer in the documentation
13  * provided with the distribution.
14  *
15  * This software is provided "as is" and without any warranty, express or
16  * implied. In no event shall the authors be liable for any damages arising from
17  * the use of this software.
18  */
19 
20 #include <glib.h>
21 #include <stdint.h>
22 #include <math.h>
23 
24 #include "audio.h"
25 
26 #define INTERLACE_LOOP(TYPE) \
27 for (int c = 0; c < channels; c ++) \
28 { \
29  const TYPE * get = in[c]; \
30  const TYPE * end = get + frames; \
31  TYPE * set = (TYPE *) out + c; \
32  while (get < end) \
33  { \
34  * set = * get ++; \
35  set += channels; \
36  } \
37 }
38 
39 EXPORT void audio_interlace (const void * const * in, int format, int channels,
40  void * out, int frames)
41 {
42  switch (format)
43  {
44  case FMT_FLOAT:
45  INTERLACE_LOOP (float);
46  break;
47 
48  case FMT_S8:
49  case FMT_U8:
50  INTERLACE_LOOP (int8_t);
51  break;
52 
53  case FMT_S16_LE:
54  case FMT_S16_BE:
55  case FMT_U16_LE:
56  case FMT_U16_BE:
57  INTERLACE_LOOP (int16_t);
58  break;
59 
60  case FMT_S24_LE:
61  case FMT_S24_BE:
62  case FMT_U24_LE:
63  case FMT_U24_BE:
64  case FMT_S32_LE:
65  case FMT_S32_BE:
66  case FMT_U32_LE:
67  case FMT_U32_BE:
68  INTERLACE_LOOP (int32_t);
69  break;
70  }
71 }
72 
73 #define FROM_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE) \
74 static void NAME (const TYPE * in, float * out, int samples) \
75 { \
76  const TYPE * end = in + samples; \
77  while (in < end) \
78  * out ++ = (TYPE) (SWAP (* in ++) - OFFSET) * (1.0 / (RANGE + 1.0)); \
79 }
80 
81 #define TO_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE) \
82 static void NAME (const float * in, TYPE * out, int samples) \
83 { \
84  const float * end = in + samples; \
85  while (in < end) \
86  { \
87  double f = (* in ++) * (RANGE + 1.0); \
88  * out ++ = SWAP (OFFSET + (TYPE) round (CLAMP (f, -RANGE - 1, RANGE))); \
89  } \
90 }
91 
92 FROM_INT_LOOP (from_s8, int8_t, , 0x00, 0x7f)
93 FROM_INT_LOOP (from_u8, int8_t, , 0x80, 0x7f)
94 FROM_INT_LOOP (from_s16, int16_t, , 0x0000, 0x7fff)
95 FROM_INT_LOOP (from_u16, int16_t, , 0x8000, 0x7fff)
96 FROM_INT_LOOP (from_s24, int32_t, , 0x000000, 0x7fffff)
97 FROM_INT_LOOP (from_u24, int32_t, , 0x800000, 0x7fffff)
98 FROM_INT_LOOP (from_s32, int32_t, , 0x00000000, 0x7fffffff)
99 FROM_INT_LOOP (from_u32, int32_t, , 0x80000000, 0x7fffffff)
100 
101 TO_INT_LOOP (to_s8, int8_t, , 0x00, 0x7f)
102 TO_INT_LOOP (to_u8, int8_t, , 0x80, 0x7f)
103 TO_INT_LOOP (to_s16, int16_t, , 0x0000, 0x7fff)
104 TO_INT_LOOP (to_u16, int16_t, , 0x8000, 0x7fff)
105 TO_INT_LOOP (to_s24, int32_t, , 0x000000, 0x7fffff)
106 TO_INT_LOOP (to_u24, int32_t, , 0x800000, 0x7fffff)
107 TO_INT_LOOP (to_s32, int32_t, , 0x00000000, 0x7fffffff)
108 TO_INT_LOOP (to_u32, int32_t, , 0x80000000, 0x7fffffff)
109 
110 static inline int16_t SWAP16 (int16_t i) {return GUINT16_SWAP_LE_BE (i);}
111 static inline int32_t SWAP32 (int32_t i) {return GUINT32_SWAP_LE_BE (i);}
112 
113 FROM_INT_LOOP (from_s16_swap, int16_t, SWAP16, 0x0000, 0x7fff)
114 FROM_INT_LOOP (from_u16_swap, int16_t, SWAP16, 0x8000, 0x7fff)
115 FROM_INT_LOOP (from_s24_swap, int32_t, SWAP32, 0x000000, 0x7fffff)
116 FROM_INT_LOOP (from_u24_swap, int32_t, SWAP32, 0x800000, 0x7fffff)
117 FROM_INT_LOOP (from_s32_swap, int32_t, SWAP32, 0x00000000, 0x7fffffff)
118 FROM_INT_LOOP (from_u32_swap, int32_t, SWAP32, 0x80000000, 0x7fffffff)
119 
120 TO_INT_LOOP (to_s16_swap, int16_t, SWAP16, 0x0000, 0x7fff)
121 TO_INT_LOOP (to_u16_swap, int16_t, SWAP16, 0x8000, 0x7fff)
122 TO_INT_LOOP (to_s24_swap, int32_t, SWAP32, 0x000000, 0x7fffff)
123 TO_INT_LOOP (to_u24_swap, int32_t, SWAP32, 0x800000, 0x7fffff)
124 TO_INT_LOOP (to_s32_swap, int32_t, SWAP32, 0x00000000, 0x7fffffff)
125 TO_INT_LOOP (to_u32_swap, int32_t, SWAP32, 0x80000000, 0x7fffffff)
126 
127 typedef void (* FromFunc) (const void * in, float * out, int samples);
128 typedef void (* ToFunc) (const float * in, void * out, int samples);
129 
130 struct
131 {
132  int format;
135 }
136 convert_table [] =
137 {
138  {FMT_S8, (FromFunc) from_s8, (ToFunc) to_s8},
139  {FMT_U8, (FromFunc) from_u8, (ToFunc) to_u8},
140 
141 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
142  {FMT_S16_LE, (FromFunc) from_s16, (ToFunc) to_s16},
143  {FMT_U16_LE, (FromFunc) from_u16, (ToFunc) to_u16},
144  {FMT_S24_LE, (FromFunc) from_s24, (ToFunc) to_s24},
145  {FMT_U24_LE, (FromFunc) from_u24, (ToFunc) to_u24},
146  {FMT_S32_LE, (FromFunc) from_s32, (ToFunc) to_s32},
147  {FMT_U32_LE, (FromFunc) from_u32, (ToFunc) to_u32},
148 
149  {FMT_S16_BE, (FromFunc) from_s16_swap, (ToFunc) to_s16_swap},
150  {FMT_U16_BE, (FromFunc) from_u16_swap, (ToFunc) to_u16_swap},
151  {FMT_S24_BE, (FromFunc) from_s24_swap, (ToFunc) to_s24_swap},
152  {FMT_U24_BE, (FromFunc) from_u24_swap, (ToFunc) to_u24_swap},
153  {FMT_S32_BE, (FromFunc) from_s32_swap, (ToFunc) to_s32_swap},
154  {FMT_U32_BE, (FromFunc) from_u32_swap, (ToFunc) to_u32_swap},
155 #else
156  {FMT_S16_BE, (FromFunc) from_s16, (ToFunc) to_s16},
157  {FMT_U16_BE, (FromFunc) from_u16, (ToFunc) to_u16},
158  {FMT_S24_BE, (FromFunc) from_s24, (ToFunc) to_s24},
159  {FMT_U24_BE, (FromFunc) from_u24, (ToFunc) to_u24},
160  {FMT_S32_BE, (FromFunc) from_s32, (ToFunc) to_s32},
161  {FMT_U32_BE, (FromFunc) from_u32, (ToFunc) to_u32},
162 
163  {FMT_S16_LE, (FromFunc) from_s16_swap, (ToFunc) to_s16_swap},
164  {FMT_U16_LE, (FromFunc) from_u16_swap, (ToFunc) to_u16_swap},
165  {FMT_S24_LE, (FromFunc) from_s24_swap, (ToFunc) to_s24_swap},
166  {FMT_U24_LE, (FromFunc) from_u24_swap, (ToFunc) to_u24_swap},
167  {FMT_S32_LE, (FromFunc) from_s32_swap, (ToFunc) to_s32_swap},
168  {FMT_U32_LE, (FromFunc) from_u32_swap, (ToFunc) to_u32_swap},
169 #endif
170 };
171 
172 EXPORT void audio_from_int (const void * in, int format, float * out, int samples)
173 {
174  int entry;
175 
176  for (entry = 0; entry < G_N_ELEMENTS (convert_table); entry ++)
177  {
178  if (convert_table[entry].format == format)
179  {
180  convert_table[entry].from (in, out, samples);
181  return;
182  }
183  }
184 }
185 
186 EXPORT void audio_to_int (const float * in, void * out, int format, int samples)
187 {
188  int entry;
189 
190  for (entry = 0; entry < G_N_ELEMENTS (convert_table); entry ++)
191  {
192  if (convert_table[entry].format == format)
193  {
194  convert_table[entry].to (in, out, samples);
195  return;
196  }
197  }
198 }
199 
200 EXPORT void audio_amplify (float * data, int channels, int frames, float * factors)
201 {
202  float * end = data + channels * frames;
203  int channel;
204 
205  while (data < end)
206  {
207  for (channel = 0; channel < channels; channel ++)
208  {
209  * data = * data * factors[channel];
210  data ++;
211  }
212  }
213 }
214 
215 /* linear approximation of y = sin(x) */
216 /* contributed by Anders Johansson */
217 EXPORT void audio_soft_clip (float * data, int samples)
218 {
219  float * end = data + samples;
220 
221  while (data < end)
222  {
223  float x = * data;
224  float y = fabsf (x);
225 
226  if (y <= 0.4)
227  ; /* (0, 0.4) -> (0, 0.4) */
228  else if (y <= 0.7)
229  y = 0.8 * y + 0.08; /* (0.4, 0.7) -> (0.4, 0.64) */
230  else if (y <= 1.0)
231  y = 0.7 * y + 0.15; /* (0.7, 1) -> (0.64, 0.85) */
232  else if (y <= 1.3)
233  y = 0.4 * y + 0.45; /* (1, 1.3) -> (0.85, 0.97) */
234  else if (y <= 1.5)
235  y = 0.15 * y + 0.775; /* (1.3, 1.5) -> (0.97, 1) */
236  else
237  y = 1.0; /* (1.5, inf) -> 1 */
238 
239  * data ++ = (x > 0) ? y : -y;
240  }
241 }
FromFunc from
Definition: audio.c:133
static int channels
Definition: equalizer.c:54
EXPORT void audio_from_int(const void *in, int format, float *out, int samples)
Definition: audio.c:172
void(* FromFunc)(const void *in, float *out, int samples)
Definition: audio.c:127
#define TO_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE)
Definition: audio.c:81
void(* ToFunc)(const float *in, void *out, int samples)
Definition: audio.c:128
int format
Definition: audio.c:132
Definition: audio.h:26
EXPORT void audio_soft_clip(float *data, int samples)
Definition: audio.c:217
struct @0 convert_table[]
Definition: audio.h:26
ToFunc to
Definition: audio.c:134
EXPORT void audio_interlace(const void *const *in, int format, int channels, void *out, int frames)
Definition: audio.c:39
#define FROM_INT_LOOP(NAME, TYPE, SWAP, OFFSET, RANGE)
Definition: audio.c:73
EXPORT void audio_amplify(float *data, int channels, int frames, float *factors)
Definition: audio.c:200
#define INTERLACE_LOOP(TYPE)
Definition: audio.c:26
static int32_t SWAP32(int32_t i)
Definition: audio.c:111
static int16_t SWAP16(int16_t i)
Definition: audio.c:110
EXPORT void audio_to_int(const float *in, void *out, int format, int samples)
Definition: audio.c:186
Index Index play entry
Definition: playlist-api.h:144