/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/rdpsnd_dsp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1277 - (hide annotations)
Sun Oct 1 12:26:01 2006 UTC (17 years, 7 months ago) by stargo
Original Path: sourceforge.net/trunk/rdesktop/rdpsnd_dsp.c
File MIME type: text/plain
File size: 6037 byte(s)
only resample when there is need

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 stargo 1277 if ((resample_to_bitspersample == format->wBitsPerSample) &&
163     (resample_to_channels == format->nChannels) &&
164     (resample_to_srate == format->nSamplesPerSec))
165     return 0;
166    
167 stargo 1276 if ((resample_to_bitspersample != format->wBitsPerSample) ||
168 stargo 1277 (resample_to_channels != format->nChannels) || (format->nSamplesPerSec != 22050))
169 stargo 1276 {
170     if (!warned)
171     {
172     warning("unsupported resample-settings (%u/%u/%u), not resampling!\n",
173     format->nSamplesPerSec, format->wBitsPerSample, format->nChannels);
174     warned = True;
175     }
176     return 0;
177     }
178    
179 stargo 1277 outsize = size * 2;
180     *out = xmalloc(outsize);
181    
182     /* Resample from 22050 to 44100 */
183     for (i = 0; i < (size / samplewidth); i++)
184 stargo 1276 {
185 stargo 1277 /* On a stereo-channel we must make sure that left and right
186     does not get mixed up, so we need to expand the sample-
187     data with channels in mind: 1234 -> 12123434
188     If we have a mono-channel, we can expand the data by simply
189     doubling the sample-data: 1234 -> 11223344 */
190     if (resample_to_channels == 2)
191     offset = ((i * 2) - (i & 1)) * samplewidth;
192     else
193     offset = (i * 2) * samplewidth;
194 stargo 1276
195 stargo 1277 memcpy(*out + offset, in + (i * samplewidth), samplewidth);
196     memcpy(*out + (resample_to_channels * samplewidth + offset),
197     in + (i * samplewidth), samplewidth);
198 stargo 1276
199     }
200    
201     return outsize;
202     }
203    
204 stargo 1263 STREAM
205 stargo 1276 rdpsnd_dsp_process(STREAM s, struct audio_driver * current_driver, WAVEFORMATEX * format)
206 stargo 1258 {
207 stargo 1263 static struct stream out;
208 stargo 1258
209 stargo 1263 /* softvol and byteswap do not change the amount of data they
210     return, so they can operate on the input-stream */
211 stargo 1258 if (current_driver->wave_out_volume == rdpsnd_dsp_softvol_set)
212 stargo 1263 rdpsnd_dsp_softvol(s->data, s->size, format);
213 stargo 1258
214 stargo 1260 #ifdef B_ENDIAN
215     if (current_driver->need_byteswap_on_be)
216 stargo 1263 rdpsnd_dsp_swapbytes(s->data, s->size, format);
217 stargo 1260 #endif
218    
219 stargo 1276 out.data = NULL;
220 stargo 1263
221 stargo 1276 if (current_driver->wave_out_format_supported == rdpsnd_dsp_resample_supported)
222     out.size = rdpsnd_dsp_resample(&out.data, s->data, s->size, format);
223 stargo 1263
224 stargo 1276 if (out.data == NULL)
225     {
226     out.data = xmalloc(s->size);
227     memcpy(out.data, s->data, s->size);
228     out.size = s->size;
229     }
230    
231 stargo 1263 out.p = out.data;
232     out.end = out.p + out.size;
233    
234     return &out;
235 stargo 1258 }

  ViewVC Help
Powered by ViewVC 1.1.26