/[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 1270 by stargo, Mon Sep 18 10:20:02 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 113  rdpsnd_dsp_swapbytes(unsigned char *buff Line 125  rdpsnd_dsp_swapbytes(unsigned char *buff
125          }          }
126  }  }
127    
128    BOOL
129    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)
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    #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    #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  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 126  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 = xmalloc(s->size);          out.data = NULL;
312    
313          memcpy(out.data, s->data, s->size);          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    
         out.size = s->size;  
323          out.p = out.data;          out.p = out.data;
324          out.end = out.p + out.size;          out.end = out.p + out.size;
325    

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

  ViewVC Help
Powered by ViewVC 1.1.26