/[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

Contents of /sourceforge.net/trunk/rdesktop/rdpsnd_oss.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 491 - (show annotations)
Mon Oct 13 16:09:45 2003 UTC (20 years, 7 months ago) by stargo
File MIME type: text/plain
File size: 3897 byte(s)
Volume control for OSS & SUN
Ignore first 4 bytes of audio-packet (clicking noise)

1 /*
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 static struct audio_packet {
35 struct stream s;
36 uint16 tick;
37 uint8 index;
38 } packet_queue[MAX_QUEUE];
39 static unsigned int queue_hi, queue_lo;
40
41 BOOL
42 wave_out_open(void)
43 {
44 char *dsp_dev = "/dev/dsp";
45
46 if ((g_dsp_fd = open(dsp_dev, O_WRONLY|O_NONBLOCK)) == -1)
47 {
48 perror(dsp_dev);
49 return False;
50 }
51
52 /* Non-blocking so that user interface is responsive */
53 fcntl(g_dsp_fd, F_SETFL, fcntl(g_dsp_fd, F_GETFL)|O_NONBLOCK);
54 return True;
55 }
56
57 void
58 wave_out_close(void)
59 {
60 close(g_dsp_fd);
61 }
62
63 BOOL
64 wave_out_format_supported(WAVEFORMATEX *pwfx)
65 {
66 if (pwfx->wFormatTag != WAVE_FORMAT_PCM)
67 return False;
68 if ((pwfx->nChannels != 1) && (pwfx->nChannels != 2))
69 return False;
70 if ((pwfx->wBitsPerSample != 8) && (pwfx->wBitsPerSample != 16))
71 return False;
72
73 return True;
74 }
75
76 BOOL
77 wave_out_set_format(WAVEFORMATEX *pwfx)
78 {
79 int speed, channels, format;
80
81 ioctl(g_dsp_fd, SNDCTL_DSP_RESET, NULL);
82 ioctl(g_dsp_fd, SNDCTL_DSP_SYNC, NULL);
83
84 if (pwfx->wBitsPerSample == 8)
85 format = AFMT_U8;
86 else if (pwfx->wBitsPerSample == 16)
87 format = AFMT_S16_LE;
88
89 if (ioctl(g_dsp_fd, SNDCTL_DSP_SETFMT, &format) == -1)
90 {
91 perror("SNDCTL_DSP_SETFMT");
92 close(g_dsp_fd);
93 return False;
94 }
95
96 channels = pwfx->nChannels;
97 if (ioctl(g_dsp_fd, SNDCTL_DSP_CHANNELS, &channels) == -1)
98 {
99 perror("SNDCTL_DSP_CHANNELS");
100 close(g_dsp_fd);
101 return False;
102 }
103
104 speed = pwfx->nSamplesPerSec;
105 if (ioctl(g_dsp_fd, SNDCTL_DSP_SPEED, &speed) == -1)
106 {
107 perror("SNDCTL_DSP_SPEED");
108 close(g_dsp_fd);
109 return False;
110 }
111
112 return True;
113 }
114
115 void
116 wave_out_volume(uint16 left, uint16 right)
117 {
118 uint32 volume;
119
120 volume = left/(65536/100);
121 volume |= right/(65536/100) << 8;
122 if (ioctl(g_dsp_fd, MIXER_WRITE(SOUND_MIXER_PCM), &volume) == -1)
123 {
124 perror("MIXER_WRITE(SOUND_MIXER_PCM)");
125 return;
126 }
127 }
128
129 void
130 wave_out_write(STREAM s, uint16 tick, uint8 index)
131 {
132 struct audio_packet *packet = &packet_queue[queue_hi];
133 unsigned int next_hi = (queue_hi + 1) % MAX_QUEUE;
134
135 if (next_hi == queue_lo)
136 {
137 error("No space to queue audio packet\n");
138 return;
139 }
140
141 queue_hi = next_hi;
142
143 packet->s = *s;
144 packet->tick = tick;
145 packet->index = index;
146 packet->s.p += 4;
147
148 /* we steal the data buffer from s, give it a new one */
149 s->data = malloc(s->size);
150
151 if (!g_dsp_busy)
152 wave_out_play();
153 }
154
155 void
156 wave_out_play(void)
157 {
158 struct audio_packet *packet;
159 ssize_t len;
160 STREAM out;
161
162 while (1)
163 {
164 if (queue_lo == queue_hi)
165 {
166 g_dsp_busy = 0;
167 return;
168 }
169
170 packet = &packet_queue[queue_lo];
171 out = &packet->s;
172
173 len = write(g_dsp_fd, out->p, out->end-out->p);
174 if (len == -1)
175 {
176 if (errno != EWOULDBLOCK)
177 perror("write audio");
178 g_dsp_busy = 1;
179 return;
180 }
181
182 out->p += len;
183 if (out->p == out->end)
184 {
185 rdpsnd_send_completion(packet->tick, packet->index);
186 free(out->data);
187 queue_lo = (queue_lo + 1) % MAX_QUEUE;
188 }
189 }
190
191 }

  ViewVC Help
Powered by ViewVC 1.1.26