/[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 833 - (hide annotations)
Tue Mar 8 03:33:36 2005 UTC (19 years, 3 months ago) by stargo
File MIME type: text/plain
File size: 4353 byte(s)
basic libao output-driver. works on Mac OSX.
no volume control possible

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     BOOL g_dsp_busy = False;
35     static short g_samplewidth;
36    
37     static struct audio_packet
38     {
39     struct stream s;
40     uint16 tick;
41     uint8 index;
42     } packet_queue[MAX_QUEUE];
43     static unsigned int queue_hi, queue_lo;
44    
45     BOOL
46     wave_out_open(void)
47     {
48     ao_sample_format format;
49    
50     ao_initialize();
51     default_driver = ao_default_driver_id();
52    
53     format.bits = 16;
54     format.channels = 2;
55     format.rate = 44100;
56     format.byte_format = AO_FMT_LITTLE;
57    
58     o_device = ao_open_live(default_driver, &format, NULL);
59     if (o_device == NULL)
60     {
61     return False;
62     }
63    
64     g_dsp_fd = 0;
65     queue_lo = queue_hi = 0;
66    
67     return True;
68     }
69    
70     void
71     wave_out_close(void)
72     {
73     /* Ack all remaining packets */
74     while (queue_lo != queue_hi)
75     {
76     rdpsnd_send_completion(packet_queue[queue_lo].tick, packet_queue[queue_lo].index);
77     free(packet_queue[queue_lo].s.data);
78     queue_lo = (queue_lo + 1) % MAX_QUEUE;
79     }
80    
81     if (o_device != NULL)
82     ao_close(o_device);
83     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     44100, windows gives a max of 22050. we need to upsample that...
97     TODO: support 11025, too */
98     if (pwfx->nSamplesPerSec != 22050)
99     return False;
100    
101     return True;
102     }
103    
104     BOOL
105     wave_out_set_format(WAVEFORMATEX * pwfx)
106     {
107     ao_sample_format format;
108    
109     printf("%d\n",pwfx->wBitsPerSample);
110     format.bits = pwfx->wBitsPerSample;
111     format.channels = pwfx->nChannels;
112     format.rate = 44100;
113     format.byte_format = AO_FMT_LITTLE;
114    
115     g_samplewidth = pwfx->wBitsPerSample / 8;
116    
117     if(o_device != NULL)
118     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    
127     return True;
128     }
129    
130     void
131     wave_out_volume(uint16 left, uint16 right)
132     {
133     }
134    
135     void
136     wave_out_write(STREAM s, uint16 tick, uint8 index)
137     {
138     struct audio_packet *packet = &packet_queue[queue_hi];
139     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
140    
141     if (next_hi == queue_lo)
142     {
143     error("No space to queue audio packet\n");
144     return;
145     }
146    
147     queue_hi = next_hi;
148    
149     packet->s = *s;
150     packet->tick = tick;
151     packet->index = index;
152     packet->s.p += 4;
153    
154     /* we steal the data buffer from s, give it a new one */
155     s->data = malloc(s->size);
156    
157     if (!g_dsp_busy)
158     wave_out_play();
159     }
160    
161     void
162     wave_out_play(void)
163     {
164     struct audio_packet *packet;
165     STREAM out;
166     unsigned char expanded[8];
167    
168     while (1)
169     {
170     if (queue_lo == queue_hi)
171     {
172     g_dsp_busy = 0;
173     return;
174     }
175    
176     packet = &packet_queue[queue_lo];
177     out = &packet->s;
178    
179     /* Resample 22050 -> 44100 */
180     /* TODO: Do this for 11025, too... */
181     memcpy(&expanded[0],out->p,g_samplewidth);
182     memcpy(&expanded[2*g_samplewidth],out->p,g_samplewidth);
183     out->p += 2;
184     memcpy(&expanded[1*g_samplewidth],out->p,g_samplewidth);
185     memcpy(&expanded[3*g_samplewidth],out->p,g_samplewidth);
186     out->p += 2;
187    
188     ao_play(o_device, expanded, g_samplewidth*4);
189    
190     if (out->p == out->end)
191     {
192     rdpsnd_send_completion(packet->tick, packet->index);
193     free(out->data);
194     queue_lo = (queue_lo + 1) % MAX_QUEUE;
195     } else {
196     g_dsp_busy = 1;
197     return;
198     }
199     }
200     }

  ViewVC Help
Powered by ViewVC 1.1.26