/[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 836 - (hide annotations)
Tue Mar 8 12:09:20 2005 UTC (19 years, 3 months ago) by stargo
File MIME type: text/plain
File size: 4700 byte(s)
#define size of resampling buffer

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

  ViewVC Help
Powered by ViewVC 1.1.26