/[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 1260 by stargo, Sun Sep 17 15:25:10 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;
34  static uint16 softvol_right = MAX_VOLUME;  static uint16 softvol_right = MAX_VOLUME;
35    static uint32 resample_to_srate = 44100;
36    static uint16 resample_to_bitspersample = 16;
37    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 45  rdpsnd_dsp_softvol(unsigned char *buffer Line 57  rdpsnd_dsp_softvol(unsigned char *buffer
57          if ((softvol_left == MAX_VOLUME) && (softvol_right == MAX_VOLUME))          if ((softvol_left == MAX_VOLUME) && (softvol_right == MAX_VOLUME))
58                  return;                  return;
59    
60          factor_left = (softvol_left * 256) / 65535;          factor_left = (softvol_left * 256) / MAX_VOLUME;
61          factor_right = (softvol_right * 256) / 65535;          factor_right = (softvol_right * 256) / MAX_VOLUME;
62    
63          if (format->nChannels == 1)          if (format->nChannels == 1)
64          {          {
# Line 55  rdpsnd_dsp_softvol(unsigned char *buffer Line 67  rdpsnd_dsp_softvol(unsigned char *buffer
67    
68          if (format->wBitsPerSample == 8)          if (format->wBitsPerSample == 8)
69          {          {
70                  char val;                  sint8 val;
71    
72                  while (posout < buffer + size)                  while (posout < buffer + size)
73                  {                  {
# Line 72  rdpsnd_dsp_softvol(unsigned char *buffer Line 84  rdpsnd_dsp_softvol(unsigned char *buffer
84          }          }
85          else          else
86          {          {
87                  short val;                  sint16 val;
88    
89                  while (posout < buffer + size)                  while (posout < buffer + size)
90                  {                  {
# Line 92  rdpsnd_dsp_softvol(unsigned char *buffer Line 104  rdpsnd_dsp_softvol(unsigned char *buffer
104                  }                  }
105          }          }
106    
107          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,
108                 format->wBitsPerSample, format->nChannels));                 factor_right, format->wBitsPerSample, format->nChannels));
109  }  }
110    
111  void  void
# Line 113  rdpsnd_dsp_swapbytes(unsigned char *buff Line 125  rdpsnd_dsp_swapbytes(unsigned char *buff
125          }          }
126  }  }
127    
128  unsigned char *  BOOL
129  rdpsnd_dsp_process(unsigned char *inbuffer, unsigned int size, struct audio_driver *current_driver,  rdpsnd_dsp_resample_set(uint32 device_srate, uint16 device_bitspersample, uint16 device_channels)
130                     WAVEFORMATEX * format)  {
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)
140                    return False;
141    
142            if (device_bitspersample != 16 && device_bitspersample != 8)
143                    return False;
144    #endif
145    
146            if (device_channels != 1 && device_channels != 2)
147                    return False;
148    
149            resample_to_srate = device_srate;
150            resample_to_bitspersample = device_bitspersample;
151            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;
165    }
166    
167    BOOL
168    rdpsnd_dsp_resample_supported(WAVEFORMATEX * format)
169    {
170            if (format->wFormatTag != WAVE_FORMAT_PCM)
171                    return False;
172            if ((format->nChannels != 1) && (format->nChannels != 2))
173                    return False;
174    #ifdef HAVE_LIBSAMPLERATE
175            if (format->wBitsPerSample != 16)
176                    return False;
177    #else
178            if ((format->wBitsPerSample != 8) && (format->wBitsPerSample != 16))
179                    return False;
180            if ((format->nSamplesPerSec != 44100) && (format->nSamplesPerSec != 22050))
181                    return False;
182    #endif
183    
184            return True;
185    }
186    
187    uint32
188    rdpsnd_dsp_resample(unsigned char **out, unsigned char *in, unsigned int size,
189                        WAVEFORMATEX * format, BOOL stream_be)
190  {  {
191          unsigned char *outbuffer;  #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;
200            int samplewidth = format->wBitsPerSample / 8;
201            int outsize = 0;
202    
203            if ((resample_to_bitspersample == format->wBitsPerSample) &&
204                (resample_to_channels == format->nChannels) &&
205                (resample_to_srate == format->nSamplesPerSec))
206                    return 0;
207    
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 -> %u/%u -> %u), not resampling!\n", format->nSamplesPerSec, resample_to_srate, format->wBitsPerSample, resample_to_bitspersample, format->nChannels, resample_to_channels);
216                            warned = True;
217                    }
218    
219          outbuffer = xmalloc(size);  #ifdef HAVE_LIBSAMPLERATE
220            if (src_converter == NULL)
221            {
222                    warning("no samplerate converter available!!\n");
223                    return 0;
224            }
225    
226            innum = size / samplewidth;
227            outnum = innum * (resample_to_srate / format->nSamplesPerSec);
228    
229            infloat = xmalloc(sizeof(float) * innum);
230            outfloat = xmalloc(sizeof(float) * outnum);
231    
232            src_short_to_float_array((short *) in, infloat, innum);
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    
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                    /* 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    #ifdef B_ENDIAN
286            if (!stream_be)
287                    rdpsnd_dsp_swapbytes(*out, outsize, format)
288    #endif
289                            return outsize;
290    }
291    
292          memcpy(outbuffer, inbuffer, size);  STREAM
293    rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)
294    {
295            static struct stream out;
296            BOOL stream_be = False;
297    
298          /* Software volume control */          /* softvol and byteswap do not change the amount of data they
299               return, so they can operate on the input-stream */
300          if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)          if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)
301                  rdpsnd_dsp_softvol(outbuffer, size, format);                  rdpsnd_dsp_softvol(s->data, s->size, format);
302    
303  #ifdef B_ENDIAN  #ifdef B_ENDIAN
304          if (current_driver->need_byteswap_on_be)          if (current_driver->need_byteswap_on_be)
305                  rdpsnd_dsp_swapbytes(outbuffer, size, format);          {
306                    rdpsnd_dsp_swapbytes(s->data, s->size, format);
307                    stream_be = True;
308            }
309  #endif  #endif
310    
311          return outbuffer;          out.data = NULL;
312    
313            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);
315    
316            if (out.data == NULL)
317            {
318                    out.data = xmalloc(s->size);
319                    memcpy(out.data, s->data, s->size);
320                    out.size = s->size;
321            }
322    
323            out.p = out.data;
324            out.end = out.p + out.size;
325    
326            return &out;
327  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26