/[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 1254 - (hide annotations)
Sun Sep 17 10:32:18 2006 UTC (17 years, 8 months ago) by stargo
File MIME type: text/plain
File size: 5260 byte(s)
unify queue-handling in rdpsnd.c (remove private copies from all
drivers)

1 astrand 963 /* -*- c-basic-offset: 8 -*-
2 stargo 833 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 stargo 1254 Copyright (C) Michael Gernoth mike@zerfleddert.de 2005-2006
7 stargo 833
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 stargo 1254 #include "rdpsnd.h"
25 stargo 833 #include <unistd.h>
26     #include <fcntl.h>
27     #include <errno.h>
28     #include <ao/ao.h>
29 stargo 891 #include <sys/time.h>
30 stargo 833
31 stargo 1045 #define WAVEOUTBUF 16
32 stargo 833
33 stargo 1245 static ao_device *o_device = NULL;
34     static int default_driver;
35     static int samplerate;
36     static int audiochannels;
37     static BOOL reopened;
38     static short samplewidth;
39 stargo 833
40     BOOL
41     wave_out_open(void)
42     {
43     ao_sample_format format;
44    
45     ao_initialize();
46     default_driver = ao_default_driver_id();
47    
48     format.bits = 16;
49     format.channels = 2;
50 stargo 1245 audiochannels = 2;
51 stargo 833 format.rate = 44100;
52 stargo 1245 samplerate = 44100;
53 stargo 833 format.byte_format = AO_FMT_LITTLE;
54    
55     o_device = ao_open_live(default_driver, &format, NULL);
56     if (o_device == NULL)
57     {
58     return False;
59     }
60    
61     g_dsp_fd = 0;
62 stargo 1254 rdpsnd_queue_init();
63 stargo 833
64 stargo 1245 reopened = True;
65 stargo 891
66 stargo 833 return True;
67     }
68    
69     void
70     wave_out_close(void)
71     {
72     /* Ack all remaining packets */
73 stargo 1254 while (!rdpsnd_queue_empty())
74 stargo 833 {
75 stargo 1254 rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
76     rdpsnd_queue_current_packet()->index);
77     rdpsnd_queue_next();
78 stargo 833 }
79    
80     if (o_device != NULL)
81     ao_close(o_device);
82 stargo 838
83 stargo 833 ao_shutdown();
84     }
85    
86     BOOL
87     wave_out_format_supported(WAVEFORMATEX * pwfx)
88     {
89     if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
90     return False;
91     if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
92     return False;
93     if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
94     return False;
95     /* The only common denominator between libao output drivers is a sample-rate of
96 stargo 835 44100, we need to upsample 22050 to it */
97     if ((pwfx->nSamplesPerSec != 44100) && (pwfx->nSamplesPerSec != 22050))
98 stargo 833 return False;
99    
100     return True;
101     }
102    
103     BOOL
104     wave_out_set_format(WAVEFORMATEX * pwfx)
105     {
106     ao_sample_format format;
107    
108     format.bits = pwfx->wBitsPerSample;
109     format.channels = pwfx->nChannels;
110 stargo 1245 audiochannels = pwfx->nChannels;
111 stargo 833 format.rate = 44100;
112 stargo 1245 samplerate = pwfx->nSamplesPerSec;
113 stargo 833 format.byte_format = AO_FMT_LITTLE;
114    
115 stargo 1245 samplewidth = pwfx->wBitsPerSample / 8;
116 stargo 833
117 stargo 837 if (o_device != NULL)
118 stargo 833 ao_close(o_device);
119    
120     o_device = ao_open_live(default_driver, &format, NULL);
121     if (o_device == NULL)
122     {
123     return False;
124     }
125    
126 stargo 1245 reopened = True;
127 stargo 833
128     return True;
129     }
130    
131     void
132     wave_out_volume(uint16 left, uint16 right)
133     {
134 stargo 838 warning("volume changes not supported with libao-output\n");
135 stargo 833 }
136    
137     void
138     wave_out_play(void)
139     {
140     struct audio_packet *packet;
141     STREAM out;
142 stargo 1043 char outbuf[WAVEOUTBUF];
143 stargo 837 int offset, len, i;
144 stargo 891 static long prev_s, prev_us;
145     unsigned int duration;
146     struct timeval tv;
147     int next_tick;
148 stargo 833
149 stargo 1245 if (reopened)
150 stargo 891 {
151 stargo 1245 reopened = False;
152 stargo 891 gettimeofday(&tv, NULL);
153     prev_s = tv.tv_sec;
154     prev_us = tv.tv_usec;
155     }
156    
157 stargo 1254 if (rdpsnd_queue_empty())
158 stargo 833 {
159 stargo 835 g_dsp_busy = 0;
160     return;
161     }
162 stargo 833
163 stargo 1254 packet = rdpsnd_queue_current_packet();
164 stargo 835 out = &packet->s;
165 stargo 833
166 stargo 1254 next_tick = rdpsnd_queue_next_tick();
167 stargo 891
168 stargo 835 len = 0;
169 stargo 833
170 stargo 1245 if (samplerate == 22050)
171 stargo 835 {
172     /* Resample to 44100 */
173 stargo 1245 for (i = 0; (i < ((WAVEOUTBUF / 4) * (3 - samplewidth))) && (out->p < out->end);
174 stargo 837 i++)
175 stargo 835 {
176 stargo 841 /* On a stereo-channel we must make sure that left and right
177     does not get mixed up, so we need to expand the sample-
178     data with channels in mind: 1234 -> 12123434
179     If we have a mono-channel, we can expand the data by simply
180     doubling the sample-data: 1234 -> 11223344 */
181 stargo 1245 if (audiochannels == 2)
182     offset = ((i * 2) - (i & 1)) * samplewidth;
183 stargo 840 else
184 stargo 1245 offset = (i * 2) * samplewidth;
185 stargo 840
186 stargo 1245 memcpy(&outbuf[offset], out->p, samplewidth);
187     memcpy(&outbuf[audiochannels * samplewidth + offset], out->p, samplewidth);
188 stargo 833
189 stargo 1245 out->p += samplewidth;
190     len += 2 * samplewidth;
191 stargo 833 }
192     }
193 stargo 835 else
194     {
195 stargo 836 len = (WAVEOUTBUF > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTBUF;
196 stargo 837 memcpy(outbuf, out->p, len);
197 stargo 835 out->p += len;
198     }
199    
200 stargo 1043 ao_play(o_device, outbuf, len);
201 stargo 835
202 stargo 891 gettimeofday(&tv, NULL);
203    
204     duration = ((tv.tv_sec - prev_s) * 1000000 + (tv.tv_usec - prev_us)) / 1000;
205    
206     if (packet->tick > next_tick)
207     next_tick += 65536;
208    
209     if ((out->p == out->end) || duration > next_tick - packet->tick + 500)
210 stargo 835 {
211 stargo 891 prev_s = tv.tv_sec;
212     prev_us = tv.tv_usec;
213    
214     if (abs((next_tick - packet->tick) - duration) > 20)
215     {
216     DEBUG(("duration: %d, calc: %d, ", duration, next_tick - packet->tick));
217     DEBUG(("last: %d, is: %d, should: %d\n", packet->tick,
218     (packet->tick + duration) % 65536, next_tick % 65536));
219     }
220    
221 stargo 1254 rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);
222     rdpsnd_queue_next();
223 stargo 835 }
224    
225     g_dsp_busy = 1;
226     return;
227 stargo 833 }

  ViewVC Help
Powered by ViewVC 1.1.26