/[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 835 - (hide annotations)
Tue Mar 8 04:25:12 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 4641 byte(s)
add initial support for multiple windows samplerates

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    
31     int g_dsp_fd;
32     ao_device *o_device = NULL;
33     int default_driver;
34 stargo 835 int g_samplerate;
35 stargo 833 BOOL g_dsp_busy = False;
36     static short g_samplewidth;
37    
38     static struct audio_packet
39     {
40     struct stream s;
41     uint16 tick;
42     uint8 index;
43     } packet_queue[MAX_QUEUE];
44     static unsigned int queue_hi, queue_lo;
45    
46     BOOL
47     wave_out_open(void)
48     {
49     ao_sample_format format;
50    
51     ao_initialize();
52     default_driver = ao_default_driver_id();
53    
54     format.bits = 16;
55     format.channels = 2;
56     format.rate = 44100;
57 stargo 835 g_samplerate = 44100;
58 stargo 833 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     queue_lo = queue_hi = 0;
68    
69     return True;
70     }
71    
72     void
73     wave_out_close(void)
74     {
75     /* Ack all remaining packets */
76     while (queue_lo != queue_hi)
77     {
78     rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
79     free(packet_queue[queue_lo].s.data);
80     queue_lo = (queue_lo + 1) % MAX_QUEUE;
81     }
82    
83     if (o_device != NULL)
84     ao_close(o_device);
85     ao_shutdown();
86     }
87    
88     BOOL
89     wave_out_format_supported(WAVEFORMATEX * pwfx)
90     {
91     if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
92     return False;
93     if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
94     return False;
95     if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
96     return False;
97     /* The only common denominator between libao output drivers is a sample-rate of
98 stargo 835 44100, we need to upsample 22050 to it */
99     if ((pwfx->nSamplesPerSec != 44100) && (pwfx->nSamplesPerSec != 22050))
100 stargo 833 return False;
101    
102     return True;
103     }
104    
105     BOOL
106     wave_out_set_format(WAVEFORMATEX * pwfx)
107     {
108     ao_sample_format format;
109    
110     format.bits = pwfx->wBitsPerSample;
111     format.channels = pwfx->nChannels;
112     format.rate = 44100;
113 stargo 835 g_samplerate = pwfx->nSamplesPerSec;
114 stargo 833 format.byte_format = AO_FMT_LITTLE;
115    
116     g_samplewidth = pwfx->wBitsPerSample / 8;
117    
118     if(o_device != NULL)
119     ao_close(o_device);
120    
121     o_device = ao_open_live(default_driver, &format, NULL);
122     if (o_device == NULL)
123     {
124     return False;
125     }
126    
127    
128     return True;
129     }
130    
131     void
132     wave_out_volume(uint16 left, uint16 right)
133     {
134     }
135    
136     void
137     wave_out_write(STREAM s, uint16 tick, uint8 index)
138     {
139     struct audio_packet *packet = &packet_queue[queue_hi];
140     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
141    
142     if (next_hi == queue_lo)
143     {
144     error("No space to queue audio packet\n");
145     return;
146     }
147    
148     queue_hi = next_hi;
149    
150     packet->s = *s;
151     packet->tick = tick;
152     packet->index = index;
153     packet->s.p += 4;
154    
155     /* we steal the data buffer from s, give it a new one */
156     s->data = malloc(s->size);
157    
158     if (!g_dsp_busy)
159     wave_out_play();
160     }
161    
162     void
163     wave_out_play(void)
164     {
165     struct audio_packet *packet;
166     STREAM out;
167 stargo 835 unsigned char expanded[16];
168     int offset,len,i;
169 stargo 833
170 stargo 835 if (queue_lo == queue_hi)
171 stargo 833 {
172 stargo 835 g_dsp_busy = 0;
173     return;
174     }
175 stargo 833
176 stargo 835 packet = &packet_queue[queue_lo];
177     out = &packet->s;
178 stargo 833
179 stargo 835 len = 0;
180 stargo 833
181 stargo 835 if (g_samplerate == 22050 )
182     {
183     /* Resample to 44100 */
184     for(i=0; (i<(2*(3-g_samplewidth))) && (out->p < out->end); i++)
185     {
186     offset=i*4*g_samplewidth;
187     memcpy(&expanded[0*g_samplewidth+offset],out->p,g_samplewidth);
188     memcpy(&expanded[2*g_samplewidth+offset],out->p,g_samplewidth);
189     out->p += 2;
190 stargo 833
191 stargo 835 memcpy(&expanded[1*g_samplewidth+offset],out->p,g_samplewidth);
192     memcpy(&expanded[3*g_samplewidth+offset],out->p,g_samplewidth);
193     out->p += 2;
194     len += 4*g_samplewidth;
195 stargo 833 }
196     }
197 stargo 835 else
198     {
199     len = (16 > (out->end - out->p)) ? (out->end - out->p) : 16;
200     memcpy(expanded,out->p,len);
201     out->p += len;
202     }
203    
204     ao_play(o_device, expanded, len);
205    
206     if (out->p == out->end)
207     {
208     rdpsnd_send_completion(packet->tick, packet->index);
209     free(out->data);
210     queue_lo = (queue_lo + 1) % MAX_QUEUE;
211     }
212    
213     g_dsp_busy = 1;
214     return;
215 stargo 833 }

  ViewVC Help
Powered by ViewVC 1.1.26