/[rdesktop]/sourceforge.net/trunk/rdesktop/rdpsnd_oss.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_oss.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 499 - (hide annotations)
Wed Oct 15 14:01:32 2003 UTC (20 years, 7 months ago) by astrand
File MIME type: text/plain
File size: 3913 byte(s)
Fixed indentation

1 matthewc 475 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Sound Channel Process Functions - Open Sound System
4     Copyright (C) Matthew Chapman 2003
5     Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6    
7     This program is free software; you can redistribute it and/or modify
8     it under the terms of the GNU General Public License as published by
9     the Free Software Foundation; either version 2 of the License, or
10     (at your option) any later version.
11    
12     This program is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     GNU General Public License for more details.
16    
17     You should have received a copy of the GNU General Public License
18     along with this program; if not, write to the Free Software
19     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20     */
21    
22     #include "rdesktop.h"
23     #include <unistd.h>
24     #include <fcntl.h>
25     #include <errno.h>
26     #include <sys/ioctl.h>
27     #include <sys/soundcard.h>
28    
29     #define MAX_QUEUE 10
30    
31     int g_dsp_fd;
32     BOOL g_dsp_busy;
33    
34 astrand 499 static struct audio_packet
35     {
36 matthewc 475 struct stream s;
37     uint16 tick;
38     uint8 index;
39     } packet_queue[MAX_QUEUE];
40     static unsigned int queue_hi, queue_lo;
41    
42     BOOL
43     wave_out_open(void)
44     {
45     char *dsp_dev = "/dev/dsp";
46    
47 astrand 499 if ((g_dsp_fd = open(dsp_dev, O_WRONLY | O_NONBLOCK)) == -1)
48 matthewc 475 {
49     perror(dsp_dev);
50     return False;
51     }
52    
53     /* Non-blocking so that user interface is responsive */
54 astrand 499 fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL) | O_NONBLOCK);
55 matthewc 475 return True;
56     }
57    
58     void
59     wave_out_close(void)
60     {
61     close(g_dsp_fd);
62     }
63    
64     BOOL
65 astrand 499 wave_out_format_supported(WAVEFORMATEX * pwfx)
66 matthewc 475 {
67     if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
68     return False;
69     if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
70     return False;
71     if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
72     return False;
73    
74     return True;
75     }
76    
77     BOOL
78 astrand 499 wave_out_set_format(WAVEFORMATEX * pwfx)
79 matthewc 475 {
80     int speed, channels, format;
81    
82     ioctl(g_dsp_fd, SNDCTL_DSP_RESET, NULL);
83     ioctl(g_dsp_fd, SNDCTL_DSP_SYNC, NULL);
84    
85     if (pwfx->wBitsPerSample == 8)
86     format = AFMT_U8;
87     else if (pwfx->wBitsPerSample == 16)
88     format = AFMT_S16_LE;
89    
90     if (ioctl(g_dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1)
91     {
92     perror("SNDCTL_DSP_SETFMT");
93     close(g_dsp_fd);
94     return False;
95     }
96    
97     channels = pwfx->nChannels;
98     if (ioctl(g_dsp_fd, SNDCTL_DSP_CHANNELS, &channels) == -1)
99     {
100     perror("SNDCTL_DSP_CHANNELS");
101     close(g_dsp_fd);
102     return False;
103     }
104    
105     speed = pwfx->nSamplesPerSec;
106     if (ioctl(g_dsp_fd, SNDCTL_DSP_SPEED, &speed) == -1)
107     {
108     perror("SNDCTL_DSP_SPEED");
109     close(g_dsp_fd);
110     return False;
111     }
112    
113     return True;
114     }
115    
116     void
117 stargo 491 wave_out_volume(uint16 left, uint16 right)
118     {
119     uint32 volume;
120    
121 astrand 499 volume = left / (65536 / 100);
122     volume |= right / (65536 / 100) << 8;
123 stargo 491 if (ioctl(g_dsp_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
124     {
125     perror("MIXER_WRITE(SOUND_MIXER_PCM)");
126     return;
127     }
128     }
129    
130     void
131 matthewc 475 wave_out_write(STREAM s, uint16 tick, uint8 index)
132     {
133 matthewc 476 struct audio_packet *packet = &packet_queue[queue_hi];
134     unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
135 matthewc 475
136     if (next_hi == queue_lo)
137     {
138     error("No space to queue audio packet\n");
139     return;
140     }
141    
142     queue_hi = next_hi;
143    
144     packet->s = *s;
145     packet->tick = tick;
146     packet->index = index;
147 stargo 491 packet->s.p += 4;
148 matthewc 475
149     /* we steal the data buffer from s, give it a new one */
150     s->data = malloc(s->size);
151    
152     if (!g_dsp_busy)
153     wave_out_play();
154     }
155    
156     void
157     wave_out_play(void)
158     {
159     struct audio_packet *packet;
160     ssize_t len;
161     STREAM out;
162    
163     while (1)
164     {
165     if (queue_lo == queue_hi)
166     {
167     g_dsp_busy = 0;
168     return;
169     }
170    
171     packet = &packet_queue[queue_lo];
172     out = &packet->s;
173    
174 astrand 499 len = write(g_dsp_fd, out->p, out->end - out->p);
175 matthewc 475 if (len == -1)
176     {
177     if (errno != EWOULDBLOCK)
178     perror("write audio");
179     g_dsp_busy = 1;
180     return;
181     }
182    
183     out->p += len;
184     if (out->p == out->end)
185     {
186     rdpsnd_send_completion(packet->tick, packet->index);
187     free(out->data);
188     queue_lo = (queue_lo + 1) % MAX_QUEUE;
189     }
190     }
191    
192     }

  ViewVC Help
Powered by ViewVC 1.1.26