/[rdesktop]/sourceforge.net/trunk/rdesktop/rdpsnd_dsp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdpsnd_dsp.c

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

revision 1258 by stargo, Sun Sep 17 14:41:16 2006 UTC revision 1276 by stargo, Sun Oct 1 12:16:50 2006 UTC
# Line 26  Line 26 
26    
27  static uint16 softvol_left = MAX_VOLUME;  static uint16 softvol_left = MAX_VOLUME;
28  static uint16 softvol_right = MAX_VOLUME;  static uint16 softvol_right = MAX_VOLUME;
29    static uint32 resample_to_srate = 44100;
30    static uint16 resample_to_bitspersample = 16;
31    static uint16 resample_to_channels = 2;
32    
33  void  void
34  rdpsnd_dsp_softvol_set(uint16 left, uint16 right)  rdpsnd_dsp_softvol_set(uint16 left, uint16 right)
# Line 35  rdpsnd_dsp_softvol_set(uint16 left, uint Line 38  rdpsnd_dsp_softvol_set(uint16 left, uint
38          DEBUG(("rdpsnd_dsp_softvol_set: left: %u, right: %u\n", left, right));          DEBUG(("rdpsnd_dsp_softvol_set: left: %u, right: %u\n", left, right));
39  }  }
40    
41  inline void  void
42  rdpsnd_dsp_softvol(unsigned char *inbuffer, unsigned char *outbuffer, unsigned int size,  rdpsnd_dsp_softvol(unsigned char *buffer, unsigned int size, WAVEFORMATEX * format)
                    WAVEFORMATEX * format)  
43  {  {
44          unsigned int factor_left, factor_right;          unsigned int factor_left, factor_right;
45          unsigned char *posin = inbuffer;          unsigned char *posin = buffer;
46          unsigned char *posout = outbuffer;          unsigned char *posout = buffer;
47    
48            if ((softvol_left == MAX_VOLUME) && (softvol_right == MAX_VOLUME))
49                    return;
50    
51          factor_left = (softvol_left * 256) / 65535;          factor_left = (softvol_left * 256) / MAX_VOLUME;
52          factor_right = (softvol_right * 256) / 65535;          factor_right = (softvol_right * 256) / MAX_VOLUME;
53    
54          if (format->nChannels == 1)          if (format->nChannels == 1)
55          {          {
# Line 53  rdpsnd_dsp_softvol(unsigned char *inbuff Line 58  rdpsnd_dsp_softvol(unsigned char *inbuff
58    
59          if (format->wBitsPerSample == 8)          if (format->wBitsPerSample == 8)
60          {          {
61                  char val;                  sint8 val;
62    
63                  while (posout < outbuffer + size)                  while (posout < buffer + size)
64                  {                  {
65                          /* Left */                          /* Left */
66                          val = *posin++;                          val = *posin++;
# Line 70  rdpsnd_dsp_softvol(unsigned char *inbuff Line 75  rdpsnd_dsp_softvol(unsigned char *inbuff
75          }          }
76          else          else
77          {          {
78                  short val;                  sint16 val;
79    
80                  while (posout < outbuffer + size)                  while (posout < buffer + size)
81                  {                  {
82                          /* Left */                          /* Left */
83                          val = *posin++;                          val = *posin++;
# Line 90  rdpsnd_dsp_softvol(unsigned char *inbuff Line 95  rdpsnd_dsp_softvol(unsigned char *inbuff
95                  }                  }
96          }          }
97    
98          DEBUG(("using softvol with shifts left: %d, right: %d (%d/%d)\n", factor_left, factor_right,          DEBUG(("using softvol with factors left: %d, right: %d (%d/%d)\n", factor_left,
99                 format->wBitsPerSample, format->nChannels));                 factor_right, format->wBitsPerSample, format->nChannels));
100  }  }
101    
102  unsigned char *  void
103  rdpsnd_dsp_process(unsigned char *inbuffer, unsigned int size, struct audio_driver *current_driver,  rdpsnd_dsp_swapbytes(unsigned char *buffer, unsigned int size, WAVEFORMATEX * format)
                    WAVEFORMATEX * format)  
104  {  {
105          unsigned char *outbuffer;          int i;
106            uint8 swap;
107    
108          outbuffer = xmalloc(size);          if (format->wBitsPerSample == 8)
109                    return;
110    
111          /* Software volume control */          for (i = 0; i < size; i += 2)
         if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)  
112          {          {
113                  rdpsnd_dsp_softvol(inbuffer, outbuffer, size, format);                  swap = *(buffer + i);
114                    *(buffer + i) = *(buffer + i + 1);
115                    *(buffer + i + 1) = swap;
116            }
117    }
118    
119    BOOL
120    rdpsnd_dsp_resample_set(uint32 device_srate, uint16 device_bitspersample, uint16 device_channels)
121    {
122            if (device_srate != 44100 && device_srate != 22050)
123                    return False;
124    
125            if (device_bitspersample != 16 && device_bitspersample != 8)
126                    return False;
127    
128            if (device_channels != 1 && device_channels != 2)
129                    return False;
130    
131            resample_to_srate = device_srate;
132            resample_to_bitspersample = device_bitspersample;
133            resample_to_channels = device_channels;
134    
135            return True;
136    }
137    
138    BOOL
139    rdpsnd_dsp_resample_supported(WAVEFORMATEX * format)
140    {
141            if (format->wFormatTag != WAVE_FORMAT_PCM)
142                    return False;
143            if ((format->nChannels != 1) && (format->nChannels != 2))
144                    return False;
145            if ((format->wBitsPerSample != 8) && (format->wBitsPerSample != 16))
146                    return False;
147            if ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050))
148                    return False;
149    
150            return True;
151    }
152    
153    uint32
154    rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
155                        WAVEFORMATEX * format)
156    {
157            static BOOL warned = False;
158            int outsize, offset;
159            int samplewidth = format->wBitsPerSample / 8;
160            int i;
161    
162            if ((resample_to_bitspersample != format->wBitsPerSample) ||
163                (resample_to_channels != format->nChannels) ||
164                ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050)))
165            {
166                    if (!warned)
167                    {
168                            warning("unsupported resample-settings (%u/%u/%u), not resampling!\n",
169                                    format->nSamplesPerSec, format->wBitsPerSample, format->nChannels);
170                            warned = True;
171                    }
172                    return 0;
173            }
174    
175            if (format->nSamplesPerSec == 22050)
176            {
177                    outsize = size * 2;
178                    *out = xmalloc(outsize);
179    
180                    /* Resample to 44100 */
181                    for (i = 0; i < (size / samplewidth); i++)
182                    {
183                            /* On a stereo-channel we must make sure that left and right
184                               does not get mixed up, so we need to expand the sample-
185                               data with channels in mind: 1234 -> 12123434
186                               If we have a mono-channel, we can expand the data by simply
187                               doubling the sample-data: 1234 -> 11223344 */
188                            if (resample_to_channels == 2)
189                                    offset = ((i * 2) - (i & 1)) * samplewidth;
190                            else
191                                    offset = (i * 2) * samplewidth;
192    
193                            memcpy(*out + offset, in + (i * samplewidth), samplewidth);
194                            memcpy(*out + (resample_to_channels * samplewidth + offset),
195                                   in + (i * samplewidth), samplewidth);
196    
197                    }
198          }          }
199          else          else
200          {          {
201                  memcpy(outbuffer, inbuffer, size);                  outsize = 0;
202            }
203    
204            return outsize;
205    }
206    
207    STREAM
208    rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)
209    {
210            static struct stream out;
211    
212            /* softvol and byteswap do not change the amount of data they
213               return, so they can operate on the input-stream */
214            if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)
215                    rdpsnd_dsp_softvol(s->data, s->size, format);
216    
217    #ifdef B_ENDIAN
218            if (current_driver->need_byteswap_on_be)
219                    rdpsnd_dsp_swapbytes(s->data, s->size, format);
220    #endif
221    
222            out.data = NULL;
223    
224            if (current_driver->wave_out_format_supported == rdpsnd_dsp_resample_supported)
225            {
226                    out.size = rdpsnd_dsp_resample(&out.data, s->data, s->size, format);
227          }          }
228    
229          return outbuffer;          if (out.data == NULL)
230            {
231                    out.data = xmalloc(s->size);
232                    memcpy(out.data, s->data, s->size);
233                    out.size = s->size;
234            }
235    
236            out.p = out.data;
237            out.end = out.p + out.size;
238    
239            return &out;
240  }  }

Legend:
Removed from v.1258  
changed lines
  Added in v.1276

  ViewVC Help
Powered by ViewVC 1.1.26