/[qemu]/qemu/audio/mixeng_template.h
ViewVC logotype

Diff of /qemu/audio/mixeng_template.h

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   *   *
6   * 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
7   * of this software and associated documentation files (the "Software"), to deal   * of this software and associated documentation files (the "Software"), to deal
8   * in the Software without restriction, including without limitation the rights   * in the Software without restriction, including without limitation the rights
# Line 27  Line 27 
27   * dec++'ified by Dscho   * dec++'ified by Dscho
28   */   */
29    
30    #ifndef SIGNED
31    #define HALF (IN_MAX >> 1)
32    #endif
33    
34    #ifdef NOVOL
35    #define VOL(a, b) a
36    #else
37    #ifdef FLOAT_MIXENG
38    #define VOL(a, b) ((a) * (b))
39    #else
40    #define VOL(a, b) ((a) * (b)) >> 32
41    #endif
42    #endif
43    
44    #define ET glue (ENDIAN_CONVERSION, glue (_, IN_T))
45    
46    #ifdef FLOAT_MIXENG
47    static real_t inline glue (conv_, ET) (IN_T v)
48    {
49        IN_T nv = ENDIAN_CONVERT (v);
50    
51    #ifdef RECIPROCAL
52    #ifdef SIGNED
53        return nv * (1.f / (real_t) (IN_MAX - IN_MIN));
54    #else
55        return (nv - HALF) * (1.f / (real_t) IN_MAX);
56    #endif
57    #else  /* !RECIPROCAL */
58  #ifdef SIGNED  #ifdef SIGNED
59  #define HALFT IN_MAX      return nv / (real_t) (IN_MAX - IN_MIN);
 #define HALF IN_MAX  
60  #else  #else
61  #define HALFT ((IN_MAX)>>1)      return (nv - HALF) / (real_t) IN_MAX;
 #define HALF HALFT  
62  #endif  #endif
63    #endif
64    }
65    
66  static int64_t inline glue(conv_,IN_T) (IN_T v)  static IN_T inline glue (clip_, ET) (real_t v)
67  {  {
68        if (v >= 0.5) {
69            return IN_MAX;
70        }
71        else if (v < -0.5) {
72            return IN_MIN;
73        }
74    
75    #ifdef SIGNED
76        return ENDIAN_CONVERT ((IN_T) (v * (IN_MAX - IN_MIN)));
77    #else
78        return ENDIAN_CONVERT ((IN_T) ((v * IN_MAX) + HALF));
79    #endif
80    }
81    
82    #else  /* !FLOAT_MIXENG */
83    
84    static inline int64_t glue (conv_, ET) (IN_T v)
85    {
86        IN_T nv = ENDIAN_CONVERT (v);
87  #ifdef SIGNED  #ifdef SIGNED
88      return (INT_MAX*(int64_t)v)/HALF;      return ((int64_t) nv) << (32 - SHIFT);
89  #else  #else
90      return (INT_MAX*((int64_t)v-HALFT))/HALF;      return ((int64_t) nv - HALF) << (32 - SHIFT);
91  #endif  #endif
92  }  }
93    
94  static IN_T inline glue(clip_,IN_T) (int64_t v)  static inline IN_T glue (clip_, ET) (int64_t v)
95  {  {
96      if (v >= INT_MAX)      if (v >= 0x7f000000) {
97          return IN_MAX;          return IN_MAX;
98      else if (v < -INT_MAX)      }
99        else if (v < -2147483648LL) {
100          return IN_MIN;          return IN_MIN;
101        }
102    
103  #ifdef SIGNED  #ifdef SIGNED
104      return (IN_T) (v*HALF/INT_MAX);      return ENDIAN_CONVERT ((IN_T) (v >> (32 - SHIFT)));
105  #else  #else
106      return (IN_T) (v+INT_MAX/2)*HALF/INT_MAX;      return ENDIAN_CONVERT ((IN_T) ((v >> (32 - SHIFT)) + HALF));
107  #endif  #endif
108  }  }
109    #endif
110    
111  static void glue(glue(conv_,IN_T),_to_stereo) (void *dst, const void *src,  static void glue (glue (conv_, ET), _to_stereo)
112                                                 int samples)      (st_sample_t *dst, const void *src, int samples, volume_t *vol)
113  {  {
114      st_sample_t *out = (st_sample_t *) dst;      st_sample_t *out = dst;
115      IN_T *in = (IN_T *) src;      IN_T *in = (IN_T *) src;
116    #ifndef NOVOL
117        if (vol->mute) {
118            mixeng_clear (dst, samples);
119            return;
120        }
121    #else
122        (void) vol;
123    #endif
124      while (samples--) {      while (samples--) {
125          out->l = glue(conv_,IN_T) (*in++);          out->l = VOL (glue (conv_, ET) (*in++), vol->l);
126          out->r = glue(conv_,IN_T) (*in++);          out->r = VOL (glue (conv_, ET) (*in++), vol->r);
127          out += 1;          out += 1;
128      }      }
129  }  }
130    
131  static void glue(glue(conv_,IN_T),_to_mono) (void *dst, const void *src,  static void glue (glue (conv_, ET), _to_mono)
132                                               int samples)      (st_sample_t *dst, const void *src, int samples, volume_t *vol)
133  {  {
134      st_sample_t *out = (st_sample_t *) dst;      st_sample_t *out = dst;
135      IN_T *in = (IN_T *) src;      IN_T *in = (IN_T *) src;
136    #ifndef NOVOL
137        if (vol->mute) {
138            mixeng_clear (dst, samples);
139            return;
140        }
141    #else
142        (void) vol;
143    #endif
144      while (samples--) {      while (samples--) {
145          out->l = glue(conv_,IN_T) (in[0]);          out->l = VOL (glue (conv_, ET) (in[0]), vol->l);
146          out->r = out->l;          out->r = out->l;
147          out += 1;          out += 1;
148          in += 1;          in += 1;
149      }      }
150  }  }
151    
152  static void glue(glue(clip_,IN_T),_from_stereo) (void *dst, const void *src,  static void glue (glue (clip_, ET), _from_stereo)
153                                                   int samples)      (void *dst, const st_sample_t *src, int samples)
154  {  {
155      st_sample_t *in = (st_sample_t *) src;      const st_sample_t *in = src;
156      IN_T *out = (IN_T *) dst;      IN_T *out = (IN_T *) dst;
157      while (samples--) {      while (samples--) {
158          *out++ = glue(clip_,IN_T) (in->l);          *out++ = glue (clip_, ET) (in->l);
159          *out++ = glue(clip_,IN_T) (in->r);          *out++ = glue (clip_, ET) (in->r);
160          in += 1;          in += 1;
161      }      }
162  }  }
163    
164  static void glue(glue(clip_,IN_T),_from_mono) (void *dst, const void *src,  static void glue (glue (clip_, ET), _from_mono)
165                                                 int samples)      (void *dst, const st_sample_t *src, int samples)
166  {  {
167      st_sample_t *in = (st_sample_t *) src;      const st_sample_t *in = src;
168      IN_T *out = (IN_T *) dst;      IN_T *out = (IN_T *) dst;
169      while (samples--) {      while (samples--) {
170          *out++ = glue(clip_,IN_T) (in->l + in->r);          *out++ = glue (clip_, ET) (in->l + in->r);
171          in += 1;          in += 1;
172      }      }
173  }  }
174    
175    #undef ET
176  #undef HALF  #undef HALF
177  #undef HALFT  #undef VOL
   

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