/[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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1276 - (hide annotations)
Sun Oct 1 12:16:50 2006 UTC (17 years, 8 months ago) by stargo
File MIME type: text/plain
File size: 5986 byte(s)
move simple resample algorithm from rdpsnd_libao.c to rdpsnd_dsp.c to
provide a base for a better resample-algorithm

1 stargo 1258 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Sound DSP routines
4     Copyright (C) Michael Gernoth 2006
5    
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21     #include "rdesktop.h"
22     #include "rdpsnd.h"
23     #include "rdpsnd_dsp.h"
24    
25     #define MAX_VOLUME 65535
26    
27     static uint16 softvol_left = MAX_VOLUME;
28     static uint16 softvol_right = MAX_VOLUME;
29 stargo 1276 static uint32 resample_to_srate = 44100;
30     static uint16 resample_to_bitspersample = 16;
31     static uint16 resample_to_channels = 2;
32 stargo 1258
33     void
34     rdpsnd_dsp_softvol_set(uint16 left, uint16 right)
35     {
36     softvol_left = left;
37     softvol_right = right;
38     DEBUG(("rdpsnd_dsp_softvol_set: left: %u, right: %u\n", left, right));
39     }
40    
41 stargo 1260 void
42 stargo 1259 rdpsnd_dsp_softvol(unsigned char *buffer, unsigned int size, WAVEFORMATEX * format)
43 stargo 1258 {
44     unsigned int factor_left, factor_right;
45 stargo 1259 unsigned char *posin = buffer;
46     unsigned char *posout = buffer;
47 stargo 1258
48 stargo 1259 if ((softvol_left == MAX_VOLUME) && (softvol_right == MAX_VOLUME))
49     return;
50    
51 stargo 1270 factor_left = (softvol_left * 256) / MAX_VOLUME;
52     factor_right = (softvol_right * 256) / MAX_VOLUME;
53 stargo 1258
54     if (format->nChannels == 1)
55     {
56     factor_left = factor_right = (factor_left + factor_right) / 2;
57     }
58    
59     if (format->wBitsPerSample == 8)
60     {
61 stargo 1262 sint8 val;
62 stargo 1258
63 stargo 1259 while (posout < buffer + size)
64 stargo 1258 {
65     /* Left */
66     val = *posin++;
67     val = (val * factor_left) >> 8;
68     *posout++ = val;
69    
70     /* Right */
71     val = *posin++;
72     val = (val * factor_right) >> 8;
73     *posout++ = val;
74     }
75     }
76     else
77     {
78 stargo 1262 sint16 val;
79 stargo 1258
80 stargo 1259 while (posout < buffer + size)
81 stargo 1258 {
82     /* Left */
83     val = *posin++;
84     val |= *posin++ << 8;
85     val = (val * factor_left) >> 8;
86     *posout++ = val & 0xff;
87     *posout++ = val >> 8;
88    
89     /* Right */
90     val = *posin++;
91     val |= *posin++ << 8;
92     val = (val * factor_right) >> 8;
93     *posout++ = val & 0xff;
94     *posout++ = val >> 8;
95     }
96     }
97    
98 stargo 1263 DEBUG(("using softvol with factors left: %d, right: %d (%d/%d)\n", factor_left,
99     factor_right, format->wBitsPerSample, format->nChannels));
100 stargo 1258 }
101    
102 stargo 1260 void
103     rdpsnd_dsp_swapbytes(unsigned char *buffer, unsigned int size, WAVEFORMATEX * format)
104     {
105     int i;
106     uint8 swap;
107    
108     if (format->wBitsPerSample == 8)
109     return;
110    
111     for (i = 0; i < size; i += 2)
112     {
113     swap = *(buffer + i);
114     *(buffer + i) = *(buffer + i + 1);
115     *(buffer + i + 1) = swap;
116     }
117     }
118    
119 stargo 1276 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 stargo 1263
125 stargo 1276 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
200     {
201     outsize = 0;
202     }
203    
204     return outsize;
205     }
206    
207 stargo 1263 STREAM
208 stargo 1276 rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)
209 stargo 1258 {
210 stargo 1263 static struct stream out;
211 stargo 1258
212 stargo 1263 /* softvol and byteswap do not change the amount of data they
213     return, so they can operate on the input-stream */
214 stargo 1258 if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)
215 stargo 1263 rdpsnd_dsp_softvol(s->data, s->size, format);
216 stargo 1258
217 stargo 1260 #ifdef B_ENDIAN
218     if (current_driver->need_byteswap_on_be)
219 stargo 1263 rdpsnd_dsp_swapbytes(s->data, s->size, format);
220 stargo 1260 #endif
221    
222 stargo 1276 out.data = NULL;
223 stargo 1263
224 stargo 1276 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 stargo 1263
229 stargo 1276 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 stargo 1263 out.p = out.data;
237     out.end = out.p + out.size;
238    
239     return &out;
240 stargo 1258 }

  ViewVC Help
Powered by ViewVC 1.1.26