/[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 1276 by stargo, Sun Oct 1 12:16:50 2006 UTC revision 1278 by stargo, Sun Oct 1 13:57:34 2006 UTC
# Line 22  Line 22 
22  #include "rdpsnd.h"  #include "rdpsnd.h"
23  #include "rdpsnd_dsp.h"  #include "rdpsnd_dsp.h"
24    
25    #ifdef HAVE_LIBSAMPLERATE
26    #include <samplerate.h>
27    
28    #define SRC_CONVERTER SRC_SINC_MEDIUM_QUALITY
29    #endif
30    
31  #define MAX_VOLUME 65535  #define MAX_VOLUME 65535
32    
33  static uint16 softvol_left = MAX_VOLUME;  static uint16 softvol_left = MAX_VOLUME;
# Line 29  static uint16 softvol_right = MAX_VOLUME Line 35  static uint16 softvol_right = MAX_VOLUME
35  static uint32 resample_to_srate = 44100;  static uint32 resample_to_srate = 44100;
36  static uint16 resample_to_bitspersample = 16;  static uint16 resample_to_bitspersample = 16;
37  static uint16 resample_to_channels = 2;  static uint16 resample_to_channels = 2;
38    #ifdef HAVE_LIBSAMPLERATE
39    static SRC_STATE *src_converter = NULL;
40    #endif
41    
42  void  void
43  rdpsnd_dsp_softvol_set(uint16 left, uint16 right)  rdpsnd_dsp_softvol_set(uint16 left, uint16 right)
# Line 119  rdpsnd_dsp_swapbytes(unsigned char *buff Line 128  rdpsnd_dsp_swapbytes(unsigned char *buff
128  BOOL  BOOL
129  rdpsnd_dsp_resample_set(uint32 device_srate, uint16 device_bitspersample, uint16 device_channels)  rdpsnd_dsp_resample_set(uint32 device_srate, uint16 device_bitspersample, uint16 device_channels)
130  {  {
131    #ifdef HAVE_LIBSAMPLERATE
132            int err;
133    #endif
134    
135    #ifdef HAVE_LIBSAMPLERATE
136            if (device_bitspersample != 16)
137                    return False;
138    #else
139          if (device_srate != 44100 && device_srate != 22050)          if (device_srate != 44100 && device_srate != 22050)
140                  return False;                  return False;
141    
142          if (device_bitspersample != 16 && device_bitspersample != 8)          if (device_bitspersample != 16 && device_bitspersample != 8)
143                  return False;                  return False;
144    #endif
145    
146          if (device_channels != 1 && device_channels != 2)          if (device_channels != 1 && device_channels != 2)
147                  return False;                  return False;
# Line 132  rdpsnd_dsp_resample_set(uint32 device_sr Line 150  rdpsnd_dsp_resample_set(uint32 device_sr
150          resample_to_bitspersample = device_bitspersample;          resample_to_bitspersample = device_bitspersample;
151          resample_to_channels = device_channels;          resample_to_channels = device_channels;
152    
153    #ifdef HAVE_LIBSAMPLERATE
154            if (src_converter != NULL)
155                    src_converter = src_delete(src_converter);
156    
157            if ((src_converter = src_new(SRC_CONVERTER, device_channels, &err)) == NULL)
158            {
159                    warning("src_new failed: %d!\n", err);
160                    return False;
161            }
162    #endif
163    
164          return True;          return True;
165  }  }
166    
# Line 142  rdpsnd_dsp_resample_supported(WAVEFORMAT Line 171  rdpsnd_dsp_resample_supported(WAVEFORMAT
171                  return False;                  return False;
172          if ((format->nChannels != 1) && (format->nChannels != 2))          if ((format->nChannels != 1) && (format->nChannels != 2))
173                  return False;                  return False;
174    #ifdef HAVE_LIBSAMPLERATE
175            if (format->wBitsPerSample != 16)
176                    return False;
177    #else
178          if ((format->wBitsPerSample != 8) && (format->wBitsPerSample != 16))          if ((format->wBitsPerSample != 8) && (format->wBitsPerSample != 16))
179                  return False;                  return False;
180          if ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050))          if ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050))
181                  return False;                  return False;
182    #endif
183    
184          return True;          return True;
185  }  }
186    
187  uint32  uint32
188  rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,  rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
189                      WAVEFORMATEX * format)                      WAVEFORMATEX * format, BOOL stream_be)
190  {  {
191    #ifdef HAVE_LIBSAMPLERATE
192            SRC_DATA resample_data;
193            float *infloat, *outfloat;
194            int innum, outnum;
195    #else
196            int offset;
197            int i;
198    #endif
199          static BOOL warned = False;          static BOOL warned = False;
         int outsize, offset;  
200          int samplewidth = format->wBitsPerSample / 8;          int samplewidth = format->wBitsPerSample / 8;
201          int i;          int outsize = 0;
202    
203          if ((resample_to_bitspersample != format->wBitsPerSample) ||          if ((resample_to_bitspersample == format->wBitsPerSample) &&
204              (resample_to_channels != format->nChannels) ||              (resample_to_channels == format->nChannels) &&
205              ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050)))              (resample_to_srate == format->nSamplesPerSec))
206          {                  return 0;
207                  if (!warned)  
208    #ifdef B_ENDIAN
209            if (!stream_be)
210                    rdpsnd_dsp_swapbytes(in, size, format)
211    #endif
212                            if ((resample_to_channels != format->nChannels) ||
213                                (resample_to_bitspersample != format->wBitsPerSample))
214                  {                  {
215                          warning("unsupported resample-settings (%u/%u/%u), not resampling!\n",                          warning("unsupported resample-settings (%u -> %u/%u -> %u/%u -> %u), not resampling!\n", format->nSamplesPerSec, resample_to_srate, format->wBitsPerSample, resample_to_bitspersample, format->nChannels, resample_to_channels);
                                 format->nSamplesPerSec, format->wBitsPerSample, format->nChannels);  
216                          warned = True;                          warned = True;
217                  }                  }
218    
219    #ifdef HAVE_LIBSAMPLERATE
220            if (src_converter == NULL)
221            {
222                    warning("no samplerate converter available!!\n");
223                  return 0;                  return 0;
224          }          }
225    
226          if (format->nSamplesPerSec == 22050)          innum = size / samplewidth;
227          {          outnum = innum * (resample_to_srate / format->nSamplesPerSec);
                 outsize = size * 2;  
                 *out = xmalloc(outsize);  
228    
229                  /* Resample to 44100 */          infloat = xmalloc(sizeof(float) * innum);
230                  for (i = 0; i < (size / samplewidth); i++)          outfloat = xmalloc(sizeof(float) * outnum);
231                  {  
232                          /* On a stereo-channel we must make sure that left and right          src_short_to_float_array((short *) in, infloat, innum);
                            does not get mixed up, so we need to expand the sample-  
                            data with channels in mind: 1234 -> 12123434  
                            If we have a mono-channel, we can expand the data by simply  
                            doubling the sample-data: 1234 -> 11223344 */  
                         if (resample_to_channels == 2)  
                                 offset = ((i * 2) - (i & 1)) * samplewidth;  
                         else  
                                 offset = (i * 2) * samplewidth;  
   
                         memcpy(*out + offset, in + (i * samplewidth), samplewidth);  
                         memcpy(*out + (resample_to_channels * samplewidth + offset),  
                                in + (i * samplewidth), samplewidth);  
233    
234            bzero(&resample_data, sizeof(resample_data));
235            resample_data.data_in = infloat;
236            resample_data.data_out = outfloat;
237            resample_data.input_frames = innum / resample_to_channels;
238            resample_data.output_frames = outnum / resample_to_channels;
239            resample_data.src_ratio = (double) resample_to_srate / (double) format->nSamplesPerSec;
240            resample_data.end_of_input = 0;
241    
242            src_process(src_converter, &resample_data);
243            xfree(infloat);
244    
245            outsize = outnum * samplewidth;
246            *out = xmalloc(outsize);
247            src_float_to_short_array(outfloat, (short *) *out, outnum);
248            xfree(outfloat);
249    
250    #else
251            if (format->nSamplesPerSec != 22050)
252            {
253                    if (!warned)
254                    {
255                            warning("unsupported source samplerate (%u), not resampling!\n",
256                                    format->nSamplesPerSec);
257                            warned = True;
258                  }                  }
259                    return 0;
260          }          }
261          else  
262            outsize = size * 2;
263            *out = xmalloc(outsize);
264    
265            /* Resample from 22050 to 44100 */
266            for (i = 0; i < (size / samplewidth); i++)
267          {          {
268                  outsize = 0;                  /* On a stereo-channel we must make sure that left and right
269                       does not get mixed up, so we need to expand the sample-
270                       data with channels in mind: 1234 -> 12123434
271                       If we have a mono-channel, we can expand the data by simply
272                       doubling the sample-data: 1234 -> 11223344 */
273                    if (resample_to_channels == 2)
274                            offset = ((i * 2) - (i & 1)) * samplewidth;
275                    else
276                            offset = (i * 2) * samplewidth;
277    
278                    memcpy(*out + offset, in + (i * samplewidth), samplewidth);
279                    memcpy(*out + (resample_to_channels * samplewidth + offset),
280                           in + (i * samplewidth), samplewidth);
281    
282          }          }
283    #endif
284    
285          return outsize;  #ifdef B_ENDIAN
286            if (!stream_be)
287                    rdpsnd_dsp_swapbytes(*out, outsize, format)
288    #endif
289                            return outsize;
290  }  }
291    
292  STREAM  STREAM
293  rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)  rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)
294  {  {
295          static struct stream out;          static struct stream out;
296            BOOL stream_be = False;
297    
298          /* softvol and byteswap do not change the amount of data they          /* softvol and byteswap do not change the amount of data they
299             return, so they can operate on the input-stream */             return, so they can operate on the input-stream */
# Line 216  rdpsnd_dsp_process(STREAM s, struct audi Line 302  rdpsnd_dsp_process(STREAM s, struct audi
302    
303  #ifdef B_ENDIAN  #ifdef B_ENDIAN
304          if (current_driver->need_byteswap_on_be)          if (current_driver->need_byteswap_on_be)
305            {
306                  rdpsnd_dsp_swapbytes(s->data, s->size, format);                  rdpsnd_dsp_swapbytes(s->data, s->size, format);
307                    stream_be = True;
308            }
309  #endif  #endif
310    
311          out.data = NULL;          out.data = NULL;
312    
313          if (current_driver->wave_out_format_supported == rdpsnd_dsp_resample_supported)          if (current_driver->wave_out_format_supported == rdpsnd_dsp_resample_supported)
314          {                  out.size = rdpsnd_dsp_resample(&out.data, s->data, s->size, format, stream_be);
                 out.size = rdpsnd_dsp_resample(&out.data, s->data, s->size, format);  
         }  
315    
316          if (out.data == NULL)          if (out.data == NULL)
317          {          {

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

  ViewVC Help
Powered by ViewVC 1.1.26