/[rdesktop]/sourceforge.net/trunk/rdesktop/rdpsnd_libao.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_libao.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 841 - (hide annotations)
Tue Mar 8 17:23:26 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 5091 byte(s)
bugfix: correctly increment the out->p pointer

1 stargo 833 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions - libao-driver
4     Copyright (C) Matthew Chapman 2003
5     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6     Copyright (C) Michael Gernoth mike@zerfleddert.de 2005
7    
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version.
12    
13     This program is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     GNU General Public License for more details.
17    
18     You should have received a copy of the GNU General Public License
19     along with this program; if not, write to the Free Software
20     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21     */
22    
23     #include "rdesktop.h"
24     #include <unistd.h>
25     #include <fcntl.h>
26     #include <errno.h>
27     #include <ao/ao.h>
28    
29     #define MAX_QUEUE 10
30 stargo 840 #define WAVEOUTBUF 64
31 stargo 833
32     int g_dsp_fd;
33     ao_device *o_device = NULL;
34     int default_driver;
35 stargo 835 int g_samplerate;
36 stargo 840 int g_channels;
37 stargo 833 BOOL g_dsp_busy = False;
38     static short g_samplewidth;
39    
40     static struct audio_packet
41     {
42     struct stream s;
43     uint16 tick;
44     uint8 index;
45     } packet_queue[MAX_QUEUE];
46     static unsigned int queue_hi, queue_lo;
47    
48     BOOL
49     wave_out_open(void)
50     {
51     ao_sample_format format;
52    
53     ao_initialize();
54     default_driver = ao_default_driver_id();
55    
56     format.bits = 16;
57     format.channels = 2;
58 stargo 840 g_channels = 2;
59 stargo 833 format.rate = 44100;
60 stargo 835 g_samplerate = 44100;
61 stargo 833 format.byte_format = AO_FMT_LITTLE;
62    
63     o_device = ao_open_live(default_driver, &format, NULL);
64     if (o_device == NULL)
65     {
66     return False;
67     }
68    
69     g_dsp_fd = 0;
70     queue_lo = queue_hi = 0;
71    
72     return True;
73     }
74    
75     void
76     wave_out_close(void)
77     {
78     /* Ack all remaining packets */
79     while (queue_lo != queue_hi)
80     {
81     rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
82     free(packet_queue[queue_lo].s.data);
83     queue_lo = (queue_lo + 1) % MAX_QUEUE;
84     }
85    
86     if (o_device != NULL)
87     ao_close(o_device);
88 stargo 838
89 stargo 833 ao_shutdown();
90     }
91    
92     BOOL
93     wave_out_format_supported(WAVEFORMATEX * pwfx)
94     {
95     if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
96     return False;
97     if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
98     return False;
99     if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
100     return False;
101     /* The only common denominator between libao output drivers is a sample-rate of
102 stargo 835 44100, we need to upsample 22050 to it */
103     if ((pwfx->nSamplesPerSec != 44100) && (pwfx->nSamplesPerSec != 22050))
104 stargo 833 return False;
105    
106     return True;
107     }
108    
109     BOOL
110     wave_out_set_format(WAVEFORMATEX * pwfx)
111     {
112     ao_sample_format format;
113    
114     format.bits = pwfx->wBitsPerSample;
115     format.channels = pwfx->nChannels;
116 stargo 840 g_channels = pwfx->nChannels;
117 stargo 833 format.rate = 44100;
118 stargo 835 g_samplerate = pwfx->nSamplesPerSec;
119 stargo 833 format.byte_format = AO_FMT_LITTLE;
120    
121     g_samplewidth = pwfx->wBitsPerSample / 8;
122    
123 stargo 837 if (o_device != NULL)
124 stargo 833 ao_close(o_device);
125    
126     o_device = ao_open_live(default_driver, &format, NULL);
127     if (o_device == NULL)
128     {
129     return False;
130     }
131    
132    
133     return True;
134     }
135    
136     void
137     wave_out_volume(uint16 left, uint16 right)
138     {
139 stargo 838 warning("volume changes not supported with libao-output\n");
140 stargo 833 }
141    
142     void
143     wave_out_write(STREAM s, uint16 tick, uint8 index)
144     {
145     struct audio_packet *packet = &packet_queue[queue_hi];
146     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
147    
148     if (next_hi == queue_lo)
149     {
150     error("No space to queue audio packet\n");
151     return;
152     }
153    
154     queue_hi = next_hi;
155    
156     packet->s = *s;
157     packet->tick = tick;
158     packet->index = index;
159     packet->s.p += 4;
160    
161     /* we steal the data buffer from s, give it a new one */
162     s->data = malloc(s->size);
163    
164     if (!g_dsp_busy)
165     wave_out_play();
166     }
167    
168     void
169     wave_out_play(void)
170     {
171     struct audio_packet *packet;
172     STREAM out;
173 stargo 837 unsigned char outbuf[WAVEOUTBUF];
174     int offset, len, i;
175 stargo 833
176 stargo 835 if (queue_lo == queue_hi)
177 stargo 833 {
178 stargo 835 g_dsp_busy = 0;
179     return;
180     }
181 stargo 833
182 stargo 835 packet = &packet_queue[queue_lo];
183     out = &packet->s;
184 stargo 833
185 stargo 835 len = 0;
186 stargo 833
187 stargo 837 if (g_samplerate == 22050)
188 stargo 835 {
189     /* Resample to 44100 */
190 stargo 840 for (i = 0; (i < ((WAVEOUTBUF / 4) * (3 - g_samplewidth))) && (out->p < out->end);
191 stargo 837 i++)
192 stargo 835 {
193 stargo 841 /* On a stereo-channel we must make sure that left and right
194     does not get mixed up, so we need to expand the sample-
195     data with channels in mind: 1234 -> 12123434
196     If we have a mono-channel, we can expand the data by simply
197     doubling the sample-data: 1234 -> 11223344 */
198 stargo 840 if (g_channels == 2)
199     offset = ((i * 2) - (i & 1)) * g_samplewidth;
200     else
201     offset = (i * 2) * g_samplewidth;
202    
203     memcpy(&outbuf[offset], out->p, g_samplewidth);
204     memcpy(&outbuf[g_channels * g_samplewidth + offset], out->p, g_samplewidth);
205 stargo 833
206 stargo 841 out->p += g_samplewidth;
207 stargo 840 len += 2 * g_samplewidth;
208 stargo 833 }
209     }
210 stargo 835 else
211     {
212 stargo 836 len = (WAVEOUTBUF > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTBUF;
213 stargo 837 memcpy(outbuf, out->p, len);
214 stargo 835 out->p += len;
215     }
216    
217 stargo 837 ao_play(o_device, outbuf, len);
218 stargo 835
219     if (out->p == out->end)
220     {
221     rdpsnd_send_completion(packet->tick, packet->index);
222     free(out->data);
223     queue_lo = (queue_lo + 1) % MAX_QUEUE;
224     }
225    
226     g_dsp_busy = 1;
227     return;
228 stargo 833 }

  ViewVC Help
Powered by ViewVC 1.1.26