2
* Driver for IBM RS/6000 with AIX Ultimedia Services
4
* Code by Juergen Schoew <juergen.schoew@unix-ag.org>
6
* Tomas Oegren <stric@acc.umu.se>
7
* (code for audio_close delay)
9
* Cleanups and testing by Niklas Edmundsson <nikke@ing.umu.se>
19
#include <sys/audio.h>
21
#include <sys/types.h>
24
#include <sys/param.h>
28
/* use AUDIO_BSIZE to set the msec for audio buffering in Ultimedia library
30
/* #define AUDIO_BSIZE AUDIO_IGNORE */
31
#define AUDIO_BSIZE 200
34
int audio_open(struct audio_info_struct *ai)
40
if(getenv("AUDIODEV")) {
42
fprintf(stderr,"Using audio-device value from AUDIODEV environmentvariable!\n");
43
ai->device = getenv("AUDIODEV");
44
ai->fn = open(ai->device,O_WRONLY);
47
ai->device = "/dev/paud0/1"; /* paud0 for PCI */
48
ai->fn = open(ai->device,O_WRONLY);
49
if ((ai->fn == -1) & (errno == ENOENT)) {
50
ai->device = "/dev/baud0/1"; /* baud0 for MCA */
51
ai->fn = open(ai->device,O_WRONLY);
54
} else ai->fn = open(ai->device,O_WRONLY);
57
fprintf(stderr,"Can't open audio device!\n");
61
/* Init to default values */
62
memset ( & ainit, '\0', sizeof (ainit));
66
ainit.bits_per_sample = 16;
67
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT;
68
ainit.operation = PLAY;
69
ainit.bsize = AUDIO_BSIZE;
71
ret = ioctl (ai->fn, AUDIO_INIT, & ainit);
74
audio_reset_parameters(ai);
78
int audio_reset_parameters(struct audio_info_struct *ai)
80
audio_control acontrol;
85
memset ( & achange, '\0', sizeof (achange));
86
memset ( & acontrol, '\0', sizeof (acontrol));
88
achange.balance = 0x3fff0000;
89
achange.balance_delay = 0;
90
achange.volume = (long) (0x7fff << 16);
91
achange.volume_delay = 0;
92
achange.input = AUDIO_IGNORE;
93
if (ai->output == -1) achange.output = INTERNAL_SPEAKER;
96
if(ai->output & AUDIO_OUT_INTERNAL_SPEAKER)
97
achange.output |= INTERNAL_SPEAKER;
98
if(ai->output & AUDIO_OUT_HEADPHONES)
99
achange.output |= EXTERNAL_SPEAKER;
100
if(ai->output & AUDIO_OUT_LINE_OUT)
101
achange.output |= OUTPUT_1;
103
achange.output = AUDIO_IGNORE;
104
achange.treble = AUDIO_IGNORE;
105
achange.bass = AUDIO_IGNORE;
106
achange.pitch = AUDIO_IGNORE;
107
achange.monitor = AUDIO_IGNORE;
108
achange.dev_info = (char *) NULL;
110
acontrol.ioctl_request = AUDIO_CHANGE;
111
acontrol.position = 0;
112
acontrol.request_info = (char *) & achange;
114
ret = ioctl (ai->fn, AUDIO_CONTROL, & acontrol);
118
/* Init Device for new values */
120
memset ( & ainit, '\0', sizeof (ainit));
121
ainit.srate = audio_rate_best_match(ai);
122
if (ai->channels > 0)
123
ainit.channels = ai->channels;
126
switch (ai->format) {
129
ainit.bits_per_sample = 8;
130
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT;
132
case AUDIO_FORMAT_SIGNED_16:
134
ainit.bits_per_sample = 16;
135
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT;
137
case AUDIO_FORMAT_SIGNED_8:
139
ainit.bits_per_sample = 8;
140
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT;
142
case AUDIO_FORMAT_UNSIGNED_16:
144
ainit.bits_per_sample = 16;
145
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT | SIGNED;
147
case AUDIO_FORMAT_UNSIGNED_8:
149
ainit.bits_per_sample = 8;
150
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT | SIGNED;
152
case AUDIO_FORMAT_ULAW_8:
154
ainit.bits_per_sample = 8;
155
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT;
157
case AUDIO_FORMAT_ALAW_8:
159
ainit.bits_per_sample = 8;
160
ainit.flags = BIG_ENDIAN | TWOS_COMPLEMENT;
163
ainit.operation = PLAY;
164
ainit.bsize = AUDIO_BSIZE;
166
ret = ioctl (ai->fn, AUDIO_INIT, & ainit);
168
fprintf(stderr,"Can't set new audio parameters!\n");
173
acontrol.ioctl_request = AUDIO_START;
174
acontrol.request_info = NULL;
175
acontrol.position = 0;
177
ret = ioctl (ai->fn, AUDIO_CONTROL, & acontrol);
179
fprintf(stderr,"Can't reset audio!\n");
185
int audio_rate_best_match(struct audio_info_struct *ai)
187
static long valid [ ] = { 5510, 6620, 8000, 9600, 11025, 16000, 18900,
188
22050, 27420, 32000, 33075, 37800, 44100, 48000, 0 };
192
if(!ai || ai->fn < 0 || ai->rate < 0) {
198
if (abs(valid[i] - ai->rate) < abs(best - ai->rate))
209
int audio_set_rate(struct audio_info_struct *ai)
211
return audio_reset_parameters(ai);
214
int audio_set_channels(struct audio_info_struct *ai)
216
return audio_reset_parameters(ai);
219
int audio_set_format(struct audio_info_struct *ai)
221
return audio_reset_parameters(ai);
224
int audio_get_formats(struct audio_info_struct *ai)
226
/* ULTIMEDIA DOCUMENTATION SAYS:
227
The Ultimedia Audio Adapter supports fourteen sample rates you can use to
228
capture and playback audio data. The rates are (in kHz): 5.51, 6.62, 8.0,
229
9.6, 11.025, 16.0, 18.9, 22.050, 27.42, 32.0, 33.075, 37.8, 44.1, and 48.0.
230
These rates are supported for mono and stereo PCM (8- and 16-bit), mu-law,
237
audio_rate_best_match(ai);
238
if (ai->rate == rate)
239
return (AUDIO_FORMAT_SIGNED_16|AUDIO_FORMAT_UNSIGNED_16|
240
AUDIO_FORMAT_UNSIGNED_8|AUDIO_FORMAT_SIGNED_8|
241
AUDIO_FORMAT_ULAW_8|AUDIO_FORMAT_ALAW_8);
246
int audio_play_samples(struct audio_info_struct *ai,unsigned char *buf,int len)
248
return write(ai->fn,buf,len);
251
int audio_close(struct audio_info_struct *ai)
253
audio_control acontrol;
254
audio_buffer abuffer;
257
/* Don't close the audio-device until it's played all its contents */
258
memset ( & acontrol, '\0', sizeof ( acontrol ) );
259
acontrol.request_info = &abuffer;
260
acontrol.position = 0;
261
i=50; /* Don't do this forever on a bad day :-) */
263
if ((ioctl(ai->fn, AUDIO_BUFFER, &acontrol))< 0) {
264
fprintf(stderr, "buffer read failed: %d\n", errno);
267
if (abuffer.flags <= 0)
270
usleep(200000); /* sleep 0.2 sec */
273
memset ( & acontrol, '\0', sizeof ( acontrol ) );
274
acontrol.ioctl_request = AUDIO_STOP;
275
acontrol.request_info = NULL;
276
acontrol.position = 0;
278
ret = ioctl ( ai->fn, AUDIO_CONTROL, & acontrol );
280
fprintf(stderr,"Can't close audio!\n");
282
ret = close (ai->fn);
284
fprintf(stderr,"Can't close audio!\n");