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

Parent Directory Parent Directory | Revision Log Revision Log


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

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 1258 #include "rdpsnd_dsp.h"
26 stargo 833 #include <unistd.h>
27     #include <fcntl.h>
28     #include <errno.h>
29     #include <ao/ao.h>
30 stargo 891 #include <sys/time.h>
31 stargo 833
32 stargo 1045 #define WAVEOUTBUF 16
33 stargo 833
34 stargo 1245 static ao_device *o_device = NULL;
35     static int default_driver;
36     static BOOL reopened;
37 stargo 1255 static char *libao_device = NULL;
38 stargo 833
39     BOOL
40 stargo 1255 libao_open(void)
41 stargo 833 {
42     ao_sample_format format;
43    
44 stargo 1266 ao_initialize();
45    
46     if (libao_device)
47 stargo 1255 {
48 stargo 1266 default_driver = ao_driver_id(libao_device);
49 stargo 1255 }
50 stargo 1266 else
51     {
52     default_driver = ao_default_driver_id();
53     }
54 stargo 1255
55 stargo 833 format.bits = 16;
56     format.channels = 2;
57     format.rate = 44100;
58     format.byte_format = AO_FMT_LITTLE;
59    
60     o_device = ao_open_live(default_driver, &format, NULL);
61     if (o_device == NULL)
62     {
63     return False;
64     }
65    
66     g_dsp_fd = 0;
67 stargo 1254 rdpsnd_queue_init();
68 stargo 833
69 stargo 1245 reopened = True;
70 stargo 891
71 stargo 833 return True;
72     }
73    
74     void
75 stargo 1255 libao_close(void)
76 stargo 833 {
77     /* Ack all remaining packets */
78 stargo 1254 while (!rdpsnd_queue_empty())
79 stargo 833 {
80 stargo 1254 rdpsnd_send_completion(rdpsnd_queue_current_packet()->tick,
81     rdpsnd_queue_current_packet()->index);
82     rdpsnd_queue_next();
83 stargo 833 }
84    
85     if (o_device != NULL)
86     ao_close(o_device);
87 stargo 838
88 stargo 833 ao_shutdown();
89     }
90    
91     BOOL
92 stargo 1255 libao_set_format(WAVEFORMATEX * pwfx)
93 stargo 833 {
94     ao_sample_format format;
95    
96     format.bits = pwfx->wBitsPerSample;
97     format.channels = pwfx->nChannels;
98     format.rate = 44100;
99     format.byte_format = AO_FMT_LITTLE;
100    
101 stargo 837 if (o_device != NULL)
102 stargo 833 ao_close(o_device);
103    
104     o_device = ao_open_live(default_driver, &format, NULL);
105     if (o_device == NULL)
106     {
107     return False;
108     }
109    
110 stargo 1276 if (rdpsnd_dsp_resample_set(44100, pwfx->wBitsPerSample, pwfx->nChannels) == False)
111     {
112     return False;
113     }
114    
115 stargo 1245 reopened = True;
116 stargo 833
117     return True;
118     }
119    
120     void
121 stargo 1255 libao_play(void)
122 stargo 833 {
123     struct audio_packet *packet;
124     STREAM out;
125 stargo 1276 int len;
126 stargo 891 static long prev_s, prev_us;
127     unsigned int duration;
128     struct timeval tv;
129     int next_tick;
130 stargo 833
131 stargo 1245 if (reopened)
132 stargo 891 {
133 stargo 1245 reopened = False;
134 stargo 891 gettimeofday(&tv, NULL);
135     prev_s = tv.tv_sec;
136     prev_us = tv.tv_usec;
137     }
138    
139 stargo 1254 if (rdpsnd_queue_empty())
140 stargo 833 {
141 stargo 835 g_dsp_busy = 0;
142     return;
143     }
144 stargo 833
145 stargo 1254 packet = rdpsnd_queue_current_packet();
146 stargo 835 out = &packet->s;
147 stargo 833
148 stargo 1254 next_tick = rdpsnd_queue_next_tick();
149 stargo 891
150 stargo 1276 len = (WAVEOUTBUF > (out->end - out->p)) ? (out->end - out->p) : WAVEOUTBUF;
151     ao_play(o_device, (char *) out->p, len);
152     out->p += len;
153 stargo 833
154 stargo 891 gettimeofday(&tv, NULL);
155    
156     duration = ((tv.tv_sec - prev_s) * 1000000 + (tv.tv_usec - prev_us)) / 1000;
157    
158     if (packet->tick > next_tick)
159     next_tick += 65536;
160    
161     if ((out->p == out->end) || duration > next_tick - packet->tick + 500)
162 stargo 835 {
163 stargo 891 prev_s = tv.tv_sec;
164     prev_us = tv.tv_usec;
165    
166     if (abs((next_tick - packet->tick) - duration) > 20)
167     {
168     DEBUG(("duration: %d, calc: %d, ", duration, next_tick - packet->tick));
169     DEBUG(("last: %d, is: %d, should: %d\n", packet->tick,
170     (packet->tick + duration) % 65536, next_tick % 65536));
171     }
172    
173 stargo 1254 rdpsnd_send_completion(((packet->tick + duration) % 65536), packet->index);
174     rdpsnd_queue_next();
175 stargo 835 }
176    
177     g_dsp_busy = 1;
178     return;
179 stargo 833 }
180 stargo 1255
181     struct audio_driver *
182     libao_register(char *options)
183     {
184 stargo 1256 static struct audio_driver libao_driver;
185 stargo 1268 struct ao_info *libao_info;
186 stargo 1266 static char description[101];
187 stargo 1256
188     libao_driver.wave_out_write = rdpsnd_queue_write;
189     libao_driver.wave_out_open = libao_open;
190     libao_driver.wave_out_close = libao_close;
191 stargo 1276 libao_driver.wave_out_format_supported = rdpsnd_dsp_resample_supported;
192 stargo 1256 libao_driver.wave_out_set_format = libao_set_format;
193 stargo 1258 libao_driver.wave_out_volume = rdpsnd_dsp_softvol_set;
194 stargo 1256 libao_driver.wave_out_play = libao_play;
195     libao_driver.name = xstrdup("libao");
196 stargo 1266 libao_driver.description = description;
197 stargo 1260 libao_driver.need_byteswap_on_be = 0;
198 stargo 1256 libao_driver.next = NULL;
199    
200 stargo 1266 ao_initialize();
201 stargo 1268
202     libao_info = ao_driver_info(ao_default_driver_id());
203    
204     if (libao_info)
205     {
206     snprintf(description, 100, "libao output driver, default device: %s",
207 stargo 1276 libao_info->short_name);
208 stargo 1268 }
209     else
210     {
211     snprintf(description, 100, "libao output driver, default device: none");
212     }
213    
214 stargo 1266 ao_shutdown();
215    
216 stargo 1255 if (options)
217     {
218     libao_device = xstrdup(options);
219     }
220    
221     return &libao_driver;
222     }

  ViewVC Help
Powered by ViewVC 1.1.26