/[qemu]/qemu/audio/mixeng.c
ViewVC logotype

Diff of /qemu/audio/mixeng.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.1 by bellard, Sun Nov 7 18:04:02 2004 UTC revision 1.2 by bellard, Sun Oct 30 18:58:22 2005 UTC
# Line 1  Line 1 
1  /*  /*
2   * QEMU Mixing engine   * QEMU Mixing engine
3   *   *
4   * Copyright (c) 2004 Vassili Karpov (malc)   * Copyright (c) 2004-2005 Vassili Karpov (malc)
5   * Copyright (c) 1998 Fabrice Bellard   * Copyright (c) 1998 Fabrice Bellard
6   *   *
7   * Permission is hereby granted, free of charge, to any person obtaining a copy   * Permission is hereby granted, free of charge, to any person obtaining a copy
# Line 23  Line 23 
23   * THE SOFTWARE.   * THE SOFTWARE.
24   */   */
25  #include "vl.h"  #include "vl.h"
 //#define DEBUG_FP  
 #include "audio/mixeng.h"  
26    
27    #define AUDIO_CAP "mixeng"
28    #include "audio_int.h"
29    
30    #define NOVOL
31    
32    /* 8 bit */
33    #define ENDIAN_CONVERSION natural
34    #define ENDIAN_CONVERT(v) (v)
35    
36    /* Signed 8 bit */
37  #define IN_T int8_t  #define IN_T int8_t
38  #define IN_MIN CHAR_MIN  #define IN_MIN SCHAR_MIN
39  #define IN_MAX CHAR_MAX  #define IN_MAX SCHAR_MAX
40  #define SIGNED  #define SIGNED
41    #define SHIFT 8
42  #include "mixeng_template.h"  #include "mixeng_template.h"
43  #undef SIGNED  #undef SIGNED
44  #undef IN_MAX  #undef IN_MAX
45  #undef IN_MIN  #undef IN_MIN
46  #undef IN_T  #undef IN_T
47    #undef SHIFT
48    
49    /* Unsigned 8 bit */
50  #define IN_T uint8_t  #define IN_T uint8_t
51  #define IN_MIN 0  #define IN_MIN 0
52  #define IN_MAX UCHAR_MAX  #define IN_MAX UCHAR_MAX
53    #define SHIFT 8
54  #include "mixeng_template.h"  #include "mixeng_template.h"
55  #undef IN_MAX  #undef IN_MAX
56  #undef IN_MIN  #undef IN_MIN
57  #undef IN_T  #undef IN_T
58    #undef SHIFT
59    
60    #undef ENDIAN_CONVERT
61    #undef ENDIAN_CONVERSION
62    
63    /* Signed 16 bit */
64  #define IN_T int16_t  #define IN_T int16_t
65  #define IN_MIN SHRT_MIN  #define IN_MIN SHRT_MIN
66  #define IN_MAX SHRT_MAX  #define IN_MAX SHRT_MAX
67  #define SIGNED  #define SIGNED
68    #define SHIFT 16
69    #define ENDIAN_CONVERSION natural
70    #define ENDIAN_CONVERT(v) (v)
71  #include "mixeng_template.h"  #include "mixeng_template.h"
72    #undef ENDIAN_CONVERT
73    #undef ENDIAN_CONVERSION
74    #define ENDIAN_CONVERSION swap
75    #define ENDIAN_CONVERT(v) bswap16 (v)
76    #include "mixeng_template.h"
77    #undef ENDIAN_CONVERT
78    #undef ENDIAN_CONVERSION
79  #undef SIGNED  #undef SIGNED
80  #undef IN_MAX  #undef IN_MAX
81  #undef IN_MIN  #undef IN_MIN
82  #undef IN_T  #undef IN_T
83    #undef SHIFT
84    
85  #define IN_T uint16_t  #define IN_T uint16_t
86  #define IN_MIN 0  #define IN_MIN 0
87  #define IN_MAX USHRT_MAX  #define IN_MAX USHRT_MAX
88    #define SHIFT 16
89    #define ENDIAN_CONVERSION natural
90    #define ENDIAN_CONVERT(v) (v)
91    #include "mixeng_template.h"
92    #undef ENDIAN_CONVERT
93    #undef ENDIAN_CONVERSION
94    #define ENDIAN_CONVERSION swap
95    #define ENDIAN_CONVERT(v) bswap16 (v)
96  #include "mixeng_template.h"  #include "mixeng_template.h"
97    #undef ENDIAN_CONVERT
98    #undef ENDIAN_CONVERSION
99  #undef IN_MAX  #undef IN_MAX
100  #undef IN_MIN  #undef IN_MIN
101  #undef IN_T  #undef IN_T
102    #undef SHIFT
103    
104  t_sample *mixeng_conv[2][2][2] = {  t_sample *mixeng_conv[2][2][2][2] = {
105      {      {
106          {          {
107              conv_uint8_t_to_mono,              {
108              conv_uint16_t_to_mono                  conv_natural_uint8_t_to_mono,
109                    conv_natural_uint16_t_to_mono
110                },
111                {
112                    conv_natural_uint8_t_to_mono,
113                    conv_swap_uint16_t_to_mono
114                }
115          },          },
116          {          {
117              conv_int8_t_to_mono,              {
118              conv_int16_t_to_mono                  conv_natural_int8_t_to_mono,
119                    conv_natural_int16_t_to_mono
120                },
121                {
122                    conv_natural_int8_t_to_mono,
123                    conv_swap_int16_t_to_mono
124                }
125          }          }
126      },      },
127      {      {
128          {          {
129              conv_uint8_t_to_stereo,              {
130              conv_uint16_t_to_stereo                  conv_natural_uint8_t_to_stereo,
131                    conv_natural_uint16_t_to_stereo
132                },
133                {
134                    conv_natural_uint8_t_to_stereo,
135                    conv_swap_uint16_t_to_stereo
136                }
137          },          },
138          {          {
139              conv_int8_t_to_stereo,              {
140              conv_int16_t_to_stereo                  conv_natural_int8_t_to_stereo,
141                    conv_natural_int16_t_to_stereo
142                },
143                {
144                    conv_natural_int8_t_to_stereo,
145                    conv_swap_int16_t_to_stereo
146                }
147          }          }
148      }      }
149  };  };
150    
151  f_sample *mixeng_clip[2][2][2] = {  f_sample *mixeng_clip[2][2][2][2] = {
152      {      {
153          {          {
154              clip_uint8_t_from_mono,              {
155              clip_uint16_t_from_mono                  clip_natural_uint8_t_from_mono,
156                    clip_natural_uint16_t_from_mono
157                },
158                {
159                    clip_natural_uint8_t_from_mono,
160                    clip_swap_uint16_t_from_mono
161                }
162          },          },
163          {          {
164              clip_int8_t_from_mono,              {
165              clip_int16_t_from_mono                  clip_natural_int8_t_from_mono,
166                    clip_natural_int16_t_from_mono
167                },
168                {
169                    clip_natural_int8_t_from_mono,
170                    clip_swap_int16_t_from_mono
171                }
172          }          }
173      },      },
174      {      {
175          {          {
176              clip_uint8_t_from_stereo,              {
177              clip_uint16_t_from_stereo                  clip_natural_uint8_t_from_stereo,
178                    clip_natural_uint16_t_from_stereo
179                },
180                {
181                    clip_natural_uint8_t_from_stereo,
182                    clip_swap_uint16_t_from_stereo
183                }
184          },          },
185          {          {
186              clip_int8_t_from_stereo,              {
187              clip_int16_t_from_stereo                  clip_natural_int8_t_from_stereo,
188                    clip_natural_int16_t_from_stereo
189                },
190                {
191                    clip_natural_int8_t_from_stereo,
192                    clip_swap_int16_t_from_stereo
193                }
194          }          }
195      }      }
196  };  };
# Line 116  f_sample *mixeng_clip[2][2][2] = { Line 203  f_sample *mixeng_clip[2][2][2] = {
203   * Contributors with a more efficient algorithm.]   * Contributors with a more efficient algorithm.]
204   *   *
205   * This source code is freely redistributable and may be used for   * This source code is freely redistributable and may be used for
206   * any purpose.  This copyright notice must be maintained.   * any purpose.  This copyright notice must be maintained.
207   * Lance Norskog And Sundry Contributors are not responsible for   * Lance Norskog And Sundry Contributors are not responsible for
208   * the consequences of using this software.     * the consequences of using this software.
209   */   */
210    
211  /*  /*
# Line 156  void *st_rate_start (int inrate, int out Line 243  void *st_rate_start (int inrate, int out
243      rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff));      rate_t rate = (rate_t) qemu_mallocz (sizeof (struct ratestuff));
244    
245      if (!rate) {      if (!rate) {
246          exit (EXIT_FAILURE);          return NULL;
     }  
   
     if (inrate == outrate) {  
         // exit (EXIT_FAILURE);  
     }  
   
     if (inrate >= 65535 || outrate >= 65535) {  
         // exit (EXIT_FAILURE);  
247      }      }
248    
249      rate->opos = 0;      rate->opos = 0;
250    
251      /* increment */      /* increment */
252      rate->opos_inc = (inrate * ((int64_t) UINT_MAX)) / outrate;      rate->opos_inc = ((uint64_t) inrate << 32) / outrate;
253    
254      rate->ipos = 0;      rate->ipos = 0;
255      rate->ilast.l = 0;      rate->ilast.l = 0;
# Line 178  void *st_rate_start (int inrate, int out Line 257  void *st_rate_start (int inrate, int out
257      return rate;      return rate;
258  }  }
259    
260  /*  #define NAME st_rate_flow_mix
261   * Processed signed long samples from ibuf to obuf.  #define OP(a, b) a += b
262   * Return number of samples processed.  #include "rate_template.h"
263   */  
264  void st_rate_flow (void *opaque, st_sample_t *ibuf, st_sample_t *obuf,  #define NAME st_rate_flow
265                     int *isamp, int *osamp)  #define OP(a, b) a = b
266  {  #include "rate_template.h"
     rate_t rate = (rate_t) opaque;  
     st_sample_t *istart, *iend;  
     st_sample_t *ostart, *oend;  
     st_sample_t ilast, icur, out;  
     int64_t t;  
   
     ilast = rate->ilast;  
   
     istart = ibuf;  
     iend = ibuf + *isamp;  
   
     ostart = obuf;  
     oend = obuf + *osamp;  
   
     if (rate->opos_inc == 1ULL << 32) {  
         int i, n = *isamp > *osamp ? *osamp : *isamp;  
         for (i = 0; i < n; i++) {  
             obuf[i].l += ibuf[i].r;  
             obuf[i].r += ibuf[i].r;  
         }  
         *isamp = n;  
         *osamp = n;  
         return;  
     }  
   
     while (obuf < oend) {  
   
         /* Safety catch to make sure we have input samples.  */  
         if (ibuf >= iend)  
             break;  
   
         /* read as many input samples so that ipos > opos */  
   
         while (rate->ipos <= (rate->opos >> 32)) {  
             ilast = *ibuf++;  
             rate->ipos++;  
             /* See if we finished the input buffer yet */  
             if (ibuf >= iend) goto the_end;  
         }  
   
         icur = *ibuf;  
   
         /* interpolate */  
         t = rate->opos & 0xffffffff;  
         out.l = (ilast.l * (INT_MAX - t) + icur.l * t) / INT_MAX;  
         out.r = (ilast.r * (INT_MAX - t) + icur.r * t) / INT_MAX;  
   
         /* output sample & increment position */  
 #if 0  
         *obuf++ = out;  
 #else  
         obuf->l += out.l;  
         obuf->r += out.r;  
         obuf += 1;  
 #endif  
         rate->opos += rate->opos_inc;  
     }  
   
 the_end:  
     *isamp = ibuf - istart;  
     *osamp = obuf - ostart;  
     rate->ilast = ilast;  
 }  
267    
268  void st_rate_stop (void *opaque)  void st_rate_stop (void *opaque)
269  {  {
270      qemu_free (opaque);      qemu_free (opaque);
271  }  }
272    
273    void mixeng_clear (st_sample_t *buf, int len)
274    {
275        memset (buf, 0, len * sizeof (st_sample_t));
276    }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.2

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26