1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Sound Channel Process Functions - SGI/IRIX
4 Copyright (C) Matthew Chapman 2003
5 Copyright (C) GuoJunBo guojunbo@ict.ac.cn 2003
6 Copyright (C) Jeremy Meng void.foo@gmail.com 2004, 2005
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.
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.
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.
25 #include <dmedia/audio.h>
27 /* #define IRIX_DEBUG 1 */
29 #define IRIX_MAX_VOL 65535
37 BOOL This
->dsp_bu
= False
;
38 static BOOL g_swapaudio
;
39 static int g_snd_rate
;
40 static BOOL g_swapaudio
;
41 static int width
= AL_SAMPLE_16
;
43 double min_volume
, max_volume
, volume_range
;
44 int resource
, maxFillable
;
45 int combinedFrameSize
;
47 static struct audio_packet
52 } packet_queue
[MAX_QUEUE
];
53 static unsigned int queue_hi
, queue_lo
;
60 #if (defined(IRIX_DEBUG))
61 fprintf(stderr
, "wave_out_open: begin\n");
64 if (alGetParamInfo(AL_DEFAULT_OUTPUT
, AL_GAIN
, &pinfo
) < 0)
66 fprintf(stderr
, "wave_out_open: alGetParamInfo failed: %s\n",
67 alGetErrorString(oserror()));
69 min_volume
= alFixedToDouble(pinfo
.min
.ll
);
70 max_volume
= alFixedToDouble(pinfo
.max
.ll
);
71 volume_range
= (max_volume
- min_volume
);
72 #if (defined(IRIX_DEBUG))
73 fprintf(stderr
, "wave_out_open: minvol = %lf, maxvol= %lf, range = %lf.\n",
74 min_volume
, max_volume
, volume_range
);
77 queue_lo
= queue_hi
= 0;
79 audioconfig
= alNewConfig();
80 if (audioconfig
== (ALconfig
) 0)
82 fprintf(stderr
, "wave_out_open: alNewConfig failed: %s\n",
83 alGetErrorString(oserror()));
87 output_port
= alOpenPort("rdpsnd", "w", 0);
88 if (output_port
== (ALport
) 0)
90 fprintf(stderr
, "wave_out_open: alOpenPort failed: %s\n",
91 alGetErrorString(oserror()));
95 #if (defined(IRIX_DEBUG))
96 fprintf(stderr
, "wave_out_open: returning\n");
104 /* Ack all remaining packets */
105 #if (defined(IRIX_DEBUG))
106 fprintf(stderr
, "wave_out_close: begin\n");
109 while (queue_lo
!= queue_hi
)
111 rdpsnd_send_completion(packet_queue
[queue_lo
].tick
, packet_queue
[queue_lo
].index
);
112 free(packet_queue
[queue_lo
].s
.data
);
113 queue_lo
= (queue_lo
+ 1) % MAX_QUEUE
;
115 alDiscardFrames(output_port
, 0);
117 alClosePort(output_port
);
118 alFreeConfig(audioconfig
);
119 #if (defined(IRIX_DEBUG))
120 fprintf(stderr
, "wave_out_close: returning\n");
125 wave_out_format_supported(WAVEFORMATEX
* pwfx
)
127 if (pwfx
->wFormatTag
!= WAVE_FORMAT_PCM
)
129 if ((pwfx
->nChannels
!= 1) && (pwfx
->nChannels
!= 2))
131 if ((pwfx
->wBitsPerSample
!= 8) && (pwfx
->wBitsPerSample
!= 16))
138 wave_out_set_format(WAVEFORMATEX
* pwfx
)
141 int frameSize
, channelCount
;
144 #if (defined(IRIX_DEBUG))
145 fprintf(stderr
, "wave_out_set_format: init...\n");
149 if (pwfx
->wBitsPerSample
== 8)
151 else if (pwfx
->wBitsPerSample
== 16)
153 width
= AL_SAMPLE_16
;
154 /* Do we need to swap the 16bit values? (Are we BigEndian) */
155 #if (defined(B_ENDIAN))
162 /* Limited support to configure an opened audio port in IRIX. The
163 number of channels is a static setting and can not be changed after
164 a port is opened. So if the number of channels remains the same, we
165 can configure other settings; otherwise we have to reopen the audio
166 port, using same config. */
168 channels
= pwfx
->nChannels
;
169 g_snd_rate
= pwfx
->nSamplesPerSec
;
171 alSetSampFmt(audioconfig
, AL_SAMPFMT_TWOSCOMP
);
172 alSetWidth(audioconfig
, width
);
173 if (channels
!= alGetChannels(audioconfig
))
175 alClosePort(output_port
);
176 alSetChannels(audioconfig
, channels
);
177 output_port
= alOpenPort("rdpsnd", "w", audioconfig
);
179 if (output_port
== (ALport
) 0)
181 fprintf(stderr
, "wave_out_set_format: alOpenPort failed: %s\n",
182 alGetErrorString(oserror()));
188 resource
= alGetResource(output_port
);
189 maxFillable
= alGetFillable(output_port
);
190 channelCount
= alGetChannels(audioconfig
);
191 frameSize
= alGetWidth(audioconfig
);
193 if (frameSize
== 0 || channelCount
== 0)
195 fprintf(stderr
, "wave_out_set_format: bad frameSize or channelCount\n");
198 combinedFrameSize
= frameSize
* channelCount
;
200 params
.param
= AL_RATE
;
201 params
.value
.ll
= (long long) g_snd_rate
<< 32;
203 if (alSetParams(resource
, ¶ms
, 1) < 0)
205 fprintf(stderr
, "wave_set_format: alSetParams failed: %s\n",
206 alGetErrorString(oserror()));
209 if (params
.sizeOut
< 0)
211 fprintf(stderr
, "wave_set_format: invalid rate %d\n", g_snd_rate
);
215 #if (defined(IRIX_DEBUG))
216 fprintf(stderr
, "wave_out_set_format: returning...\n");
222 wave_out_volume(uint16 left
, uint16 right
)
224 double gainleft
, gainright
;
228 #if (defined(IRIX_DEBUG))
229 fprintf(stderr
, "wave_out_volume: begin\n");
230 fprintf(stderr
, "left='%d', right='%d'\n", left
, right
);
233 gainleft
= (double) left
/ IRIX_MAX_VOL
;
234 gainright
= (double) right
/ IRIX_MAX_VOL
;
236 gain
[0] = alDoubleToFixed(min_volume
+ gainleft
* volume_range
);
237 gain
[1] = alDoubleToFixed(min_volume
+ gainright
* volume_range
);
239 pv
[0].param
= AL_GAIN
;
240 pv
[0].value
.ptr
= gain
;
242 if (alSetParams(AL_DEFAULT_OUTPUT
, pv
, 1) < 0)
244 fprintf(stderr
, "wave_out_volume: alSetParams failed: %s\n",
245 alGetErrorString(oserror()));
249 #if (defined(IRIX_DEBUG))
250 fprintf(stderr
, "wave_out_volume: returning\n");
255 wave_out_write(STREAM s
, uint16 tick
, uint8 index
)
257 struct audio_packet
*packet
= &packet_queue
[queue_hi
];
258 unsigned int next_hi
= (queue_hi
+ 1) % MAX_QUEUE
;
260 if (next_hi
== queue_lo
)
262 fprintf(stderr
, "No space to queue audio packet\n");
270 packet
->index
= index
;
273 /* we steal the data buffer from s, give it a new one */
274 s
->data
= malloc(s
->size
);
283 struct audio_packet
*packet
;
288 static BOOL swapped
= False
;
293 if (queue_lo
== queue_hi
)
295 This
->dsp_bu
= False
;
299 packet
= &packet_queue
[queue_lo
];
302 /* Swap the current packet, but only once */
303 if (g_swapaudio
&& !swapped
)
305 for (i
= 0; i
< out
->end
- out
->p
; i
+= 2)
307 swap
= *(out
->p
+ i
);
308 *(out
->p
+ i
) = *(out
->p
+ i
+ 1);
309 *(out
->p
+ i
+ 1) = swap
;
314 len
= out
->end
- out
->p
;
316 alWriteFrames(output_port
, out
->p
, len
/ combinedFrameSize
);
319 if (out
->p
== out
->end
)
321 gf
= alGetFilled(output_port
);
322 if (gf
< (4 * maxFillable
/ 10))
324 rdpsnd_send_completion(packet
->tick
, packet
->index
);
326 queue_lo
= (queue_lo
+ 1) % MAX_QUEUE
;
331 #if (defined(IRIX_DEBUG))
332 /* fprintf(stderr,"Busy playing...\n"); */