2
* Copyright (c) 2004 by Hannu Savolainen < hannu@opensound.com>
4
* Parts of the code is derived from the alsa-lib package that is
5
* copyrighted by Jaroslav Kysela and the other ALSA team members.
7
* This library is free software; you can redistribute it and/or modify
8
* it under the terms of the GNU Lesser General Public License version 2.1 as
9
* published by the Free Software Foundation.
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU Lesser General Public License for more details.
16
* You should have received a copy of the GNU Lesser General Public
17
* License along with this library; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24
int alib_initialized = 0;
26
oss_sysinfo sysinfo = { 0 };
41
if ((devmixer=getenv("OSS_MIXERDEV"))==NULL)
42
devmixer = "/dev/mixer";
44
if ((p = getenv ("ALIB_DEBUG")) != NULL)
45
alib_verbose = atoi (p);
49
if ((mixer_fd = open (devmixer, O_RDONLY, 0)) == -1)
53
if (ioctl (mixer_fd, SNDCTL_SYSINFO, &sysinfo) == -1)
55
perror ("SNDCTL_SYSINFO");
62
char alib_appname[64] = "salsa";
68
* Some programs are known to support OSS at the same time with ALSA.
69
* Prevent them from using this library accidently.
81
char *name, *msg, *action;
84
static const prog_t banned_programs[] = {
85
{"artsd", "Please use 'artsd -a oss' instead.", NULL},
86
{"kcontrol", NULL, NULL},
89
{"kplay", NULL, NULL},
90
{"kamix", "Please use ossxmix instead", NULL},
91
{"qamix", "Please use ossxmix instead", NULL},
95
static const char *whitelist[] = {
98
"gnome-volume-control",
109
char tmp[64], *p, *cmd = tmp;
111
static int warned = 0;
113
if ((f = fopen ("/proc/self/cmdline", "r")) == NULL)
116
if (fgets (tmp, sizeof (tmp) - 1, f) == NULL)
126
while (*p && (*p != ' ' && *p != '\n'))
138
strcpy (alib_appname, cmd);
140
for (i = 0; i < strlen (alib_appname); i++)
141
if (alib_appname[i] < 'a' || alib_appname[i] > 'z')
142
if (alib_appname[i] < 'A' || alib_appname[i] > 'Z')
143
if (alib_appname[i] < '0' || alib_appname[i] > '9')
144
alib_appname[i] = '_';
146
for (i = 0; banned_programs[i].name != NULL; i++)
147
if (strcmp (banned_programs[i].name, cmd) == 0)
149
if (alib_verbose != 0)
154
"\n\n************** WARNING ***********************\n");
155
fprintf (stderr, "This program (%s) should not use ALSA emulation\n",
157
if (banned_programs[i].msg != NULL)
158
fprintf (stderr, "%s\n", banned_programs[i].msg);
160
"**************************************************\n\n");
162
if (banned_programs[i].action != NULL)
166
exit (system (banned_programs[i].action));
168
while (wait () != -1);
174
if (alib_verbose == 0)
178
for (i = 0; !ok && whitelist[i] != NULL; i++)
179
if (strcmp (cmd, whitelist[i]) == 0)
190
"\n\n******************** WARNING *******************************\n");
192
"Warning! %s uses ALSA emulation instead of the native OSS API\n",
195
"****************************************************************\n\n");
201
typedef struct _snd_ctl_card_info
204
} snd_ctl_card_info_t;
207
* \brief Try to determine the next card.
208
* \param rcard pointer to card number
209
* \result zero if success, otherwise a negative error code
211
* Tries to determine the next card from given card number.
212
* If card number is -1, then the first available card is
213
* returned. If the result card number is -1, no more cards
217
snd_card_next (int *rcard)
220
if (!alib_appcheck ())
228
if (*rcard >= sysinfo.numcards)
238
* \brief Convert card string to an integer value.
239
* \param string String containing card identifier
240
* \return zero if success, otherwise a negative error code
242
* The accepted format is an integer value in ASCII representation
243
* or the card identifier (the id parameter for sound-card drivers).
246
snd_card_get_index (const char *string)
248
dbg_printf ("snd_card_get_index(%s)\n", string);
253
* \brief Get card name from a CTL card info
254
* \param obj CTL card info
258
snd_ctl_card_info_get_name (const snd_ctl_card_info_t * obj)
260
return obj->info->longname;
264
* \brief get size of #snd_ctl_card_info_t
265
* \return size in bytes
268
snd_ctl_card_info_sizeof ()
270
return sizeof (snd_ctl_card_info_t);
275
* \param ctlp Returned CTL handle
276
* \param name ASCII identifier of the CTL handle
277
* \param mode Open mode (see #SND_CTL_NONBLOCK, #SND_CTL_ASYNC)
278
* \return 0 on success otherwise a negative error code
281
snd_ctl_open (snd_ctl_t ** ctlp, const char *name, int mode)
287
if (!alib_appcheck ())
292
if (strcmp (name, "default") == 0)
296
if (name[0] != 'h' && name[1] != 'w' && name[2] != ':')
299
if (sscanf (name + 3, "%d", &num) != 1)
303
if (num < 0 || num >= sysinfo.numcards)
307
if ((ctl = malloc (sizeof (*ctl))) == NULL)
310
memset (ctl, 0, sizeof (*ctl));
311
ctl->info.card = num;
312
if (ioctl (mixer_fd, SNDCTL_CARDINFO, &ctl->info) == -1)
314
perror ("SNDCTL_CARDINFO");
315
fprintf (stderr, "Mixer fd was %d\n", mixer_fd);
324
* \brief close CTL handle
325
* \param ctl CTL handle
326
* \return 0 on success otherwise a negative error code
328
* Closes the specified CTL handle and frees all associated
332
snd_ctl_close (snd_ctl_t * ctl)
339
* \brief Get card related information
340
* \param ctl CTL handle
341
* \param info Card info pointer
342
* \return 0 on success otherwise a negative error code
345
snd_ctl_card_info (snd_ctl_t * ctl, snd_ctl_card_info_t * info)
348
memset (info, 0, sizeof (*info));
349
info->info = &ctl->info;
355
* \brief Obtain the card name.
356
* \param card Card number
357
* \param name Result - card name corresponding to card number
358
* \result zero if success, otherwise a negative error code
361
snd_card_get_name (int card, char **name)
365
sprintf (tmp, "OSS%d", card);
367
*name = strdup (tmp);
372
snd_card_get_longname (int card, char **name)
377
if (ioctl (mixer_fd, SNDCTL_CARDINFO, &ci) == -1)
380
*name = strdup (ci.longname);
385
* \brief Get next PCM device number
386
* \param ctl CTL handle
387
* \param device current device on entry and next device on return
388
* \return 0 on success otherwise a negative error code
391
snd_ctl_pcm_next_device (snd_ctl_t * ctl, int *device)
395
dbg_printf ("snd_ctl_pcm_next_device(%d)\n", *device);
401
*device = *device + 1;
406
if (*device < 0 || *device >= sysinfo.numaudios)
412
ctl->ainfo.dev = *device;
413
if (ioctl (mixer_fd, SNDCTL_AUDIOINFO, &ctl->ainfo) < 0)
416
if (ctl->ainfo.card_number == ctl->info.card)
421
*device = *device + 1;
429
* \brief Get info about a PCM device
430
* \param ctl CTL handle
431
* \param info PCM device id/info pointer
432
* \return 0 on success otherwise a negative error code
435
snd_ctl_pcm_info (snd_ctl_t * ctl, snd_pcm_info_t * info)
437
dbg_printf ("snd_ctl_pcm_info()\n");
438
memset (info, 0, sizeof (*info));
439
info->ainfo = &ctl->ainfo;
444
* \brief Get card mixer name from a CTL card info
445
* \param obj CTL card info
446
* \return card mixer name
449
snd_ctl_card_info_get_mixername (const snd_ctl_card_info_t * obj)
451
return obj->info->longname;
455
* \brief Get info about a RawMidi device
456
* \param ctl CTL handle
457
* \param info RawMidi device id/info pointer
458
* \return 0 on success otherwise a negative error code
461
snd_ctl_rawmidi_info (snd_ctl_t * ctl, snd_rawmidi_info_t * info)
463
dbg_printf ("snd_ctl_rawmidi_info()\n");
469
* \brief Get next RawMidi device number
470
* \param ctl CTL handle
471
* \param device current device on entry and next device on return
472
* \return 0 on success otherwise a negative error code
475
snd_ctl_rawmidi_next_device (snd_ctl_t * ctl, int *device)
477
dbg_printf ("snd_ctl_rawmidi_next_device()\n");
488
* \brief Get card identifier from a CTL card info
489
* \param obj CTL card info
490
* \return card identifier
493
snd_ctl_card_info_get_id (const snd_ctl_card_info_t * obj)
495
dbg_printf ("snd_ctl_card_info_get_id()\n");
497
return "snd_ctl_card_info_get_id";