~ubuntu-branches/ubuntu/vivid/oss4/vivid

« back to all changes in this revision

Viewing changes to lib/libsalsa/main.c

  • Committer: Bazaar Package Importer
  • Author(s): Romain Beauxis, Samuel Thibault, Romain Beauxis, Sebastien NOEL
  • Date: 2011-06-14 10:06:56 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110614100656-cx4oc7u426zn812z
Tags: 4.2-build2004-1
[ Samuel Thibault ]
* debian/control: Add liboss4-salsa2, liboss4-salsa-dev and
  liboss4-salsa-asound2 packages, equivalent to (and will replace) those from
  the oss-libsalsa package (Closes: #589127).
* debian/patches/liboss4-salsa.patch: New patch to rename libsalsa into
  liboss4-salsa to avoid conflicts in the archive for no good reason.
* debian/rules: Make in libOSSlib and libsalsa.
* debian/liboss4-salsa-dev.install, debian/liboss4-salsa2.install,
  debian/liboss4-salsa-asound2.links, debian/liboss4-salsa-dev.links:
  Install liboss4-salsa libraries like was done in the oss-libsalsa package.
* include-alsa: Add a copy of ALSA 1.0.5 headers: Cf ALSA_1.0.* symbols in
  libsalsa, this is the roughly supported version.
* debian/copyright: Update for new include-alsa files.
* alsa.pc: New file for compatibility with libasound-dev.
* debian/control:
  - Add Vcs-Browser and Vcs-Svn fields.
  - Use linux-any instead of the list of Linux archs (Closes: #604679).
  - Make dkms dependency linux-any only.
* debian/patches/hurd_iot.patch: New patch to fix soundcard.h usage in
  libsalsa on hurd-i386.
* debian/patches/libsalsa_fixes.patch: New patch to fix some printf usages
  and ioctl declaration in libsalsa.
* debian/patches/no_EBADE.patch: New patch to cope with hurd-i386 not having
  EBADE.
* debian/patches/CFLAGS.patch: New patch to make oss4 take debian/rules
  CFLAGS into account.
* debian/patches/snd_asoundlib_version.patch: New patch to add
  snd_asoundlib_version().
* debian/patches/generic_srccconf.patch: New patch to fix source
  configuration on unknown archs.

[ Romain Beauxis ]
* Fixed README.Debian to only mention dkms' modules.
* Switch to dpkg-source 3.0 (quilt) format
* Added DM-Upload-Allowed: yes

[ Sebastien NOEL ]
* New upstream release (Closes: #595298, #619272).
* Fix typo in initscript (Closes: #627149).
* debian/control: adjust linux-headers dependencies (Closes: #628879).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  Copyright (c) 2004 by Hannu Savolainen < hannu@opensound.com>
 
3
 *
 
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.
 
6
 *
 
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.
 
10
 *
 
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.
 
15
 *
 
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
 
19
 *
 
20
 */
 
21
#include "local.h"
 
22
 
 
23
int mixer_fd = -1;
 
24
int alib_initialized = 0;
 
25
 
 
26
oss_sysinfo sysinfo = { 0 };
 
27
struct _snd_ctl
 
28
{
 
29
  oss_card_info info;
 
30
  oss_audioinfo ainfo;
 
31
};
 
32
 
 
33
int alib_verbose = 0;
 
34
 
 
35
int
 
36
alib_init (void)
 
37
{
 
38
  char *p;
 
39
  char *devmixer;
 
40
 
 
41
  if ((devmixer=getenv("OSS_MIXERDEV"))==NULL)
 
42
     devmixer = "/dev/mixer";
 
43
 
 
44
  if ((p = getenv ("ALIB_DEBUG")) != NULL)
 
45
    alib_verbose = atoi (p);
 
46
 
 
47
  if (mixer_fd == -1)
 
48
    {
 
49
      if ((mixer_fd = open (devmixer, O_RDONLY, 0)) == -1)
 
50
        return -errno;
 
51
    }
 
52
 
 
53
  if (ioctl (mixer_fd, SNDCTL_SYSINFO, &sysinfo) == -1)
 
54
    {
 
55
      perror ("SNDCTL_SYSINFO");
 
56
      return -errno;
 
57
    }
 
58
 
 
59
  return 0;
 
60
}
 
61
 
 
62
char alib_appname[64] = "salsa";
 
63
 
 
64
int
 
65
alib_appcheck (void)
 
66
{
 
67
  /*
 
68
   * Some programs are known to support OSS at the same time with ALSA.
 
69
   * Prevent them from using this library accidently.
 
70
   */
 
71
 
 
72
  static int done = 0;
 
73
 
 
74
  if (done)
 
75
    return 1;
 
76
 
 
77
  done = 1;
 
78
 
 
79
  typedef struct
 
80
  {
 
81
    char *name, *msg, *action;
 
82
  } prog_t;
 
83
 
 
84
  static const prog_t banned_programs[] = {
 
85
    {"artsd", "Please use 'artsd -a oss' instead.", NULL},
 
86
    {"kcontrol", NULL, NULL},
 
87
    {"kmid", NULL, NULL},
 
88
    {"krec", NULL, NULL},
 
89
    {"kplay", NULL, NULL},
 
90
    {"kamix", "Please use ossxmix instead", NULL},
 
91
    {"qamix", "Please use ossxmix instead", NULL},
 
92
    NULL
 
93
  };
 
94
 
 
95
  static const char *whitelist[] = {
 
96
    "esd",
 
97
    "kmix",
 
98
    "gnome-volume-control",
 
99
    "artsd",
 
100
    "xmms",
 
101
    "alsaplayer",
 
102
    "aplay",
 
103
    "alsamixer",
 
104
    "vkeybd",
 
105
    NULL
 
106
  };
 
107
 
 
108
  FILE *f;
 
109
  char tmp[64], *p, *cmd = tmp;
 
110
  int i;
 
111
  static int warned = 0;
 
112
 
 
113
  if ((f = fopen ("/proc/self/cmdline", "r")) == NULL)
 
114
    return 1;
 
115
 
 
116
  if (fgets (tmp, sizeof (tmp) - 1, f) == NULL)
 
117
    {
 
118
      fclose (f);
 
119
      return 1;
 
120
    }
 
121
 
 
122
  fclose (f);
 
123
 
 
124
  p = cmd;
 
125
 
 
126
  while (*p && (*p != ' ' && *p != '\n'))
 
127
    p++;
 
128
  *p = 0;
 
129
 
 
130
  p = cmd = tmp;
 
131
  while (*p)
 
132
    {
 
133
      if (*p == '/')
 
134
        cmd = p + 1;
 
135
      p++;
 
136
    }
 
137
 
 
138
  strcpy (alib_appname, cmd);
 
139
 
 
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] = '_';
 
145
 
 
146
  for (i = 0; banned_programs[i].name != NULL; i++)
 
147
    if (strcmp (banned_programs[i].name, cmd) == 0)
 
148
      {
 
149
        if (alib_verbose != 0)
 
150
          {
 
151
            return 1;
 
152
          }
 
153
        fprintf (stderr,
 
154
                 "\n\n**************   WARNING   ***********************\n");
 
155
        fprintf (stderr, "This program (%s) should not use ALSA emulation\n",
 
156
                 cmd);
 
157
        if (banned_programs[i].msg != NULL)
 
158
          fprintf (stderr, "%s\n", banned_programs[i].msg);
 
159
        fprintf (stderr,
 
160
                 "**************************************************\n\n");
 
161
 
 
162
        if (banned_programs[i].action != NULL)
 
163
          {
 
164
            if (fork () == 0)
 
165
              {
 
166
                exit (system (banned_programs[i].action));
 
167
              }
 
168
            while (wait () != -1);
 
169
            exit (1);
 
170
          }
 
171
        return 0;
 
172
      }
 
173
 
 
174
  if (alib_verbose == 0)
 
175
    {
 
176
      int ok = 0;
 
177
 
 
178
      for (i = 0; !ok && whitelist[i] != NULL; i++)
 
179
        if (strcmp (cmd, whitelist[i]) == 0)
 
180
          ok = 1;
 
181
 
 
182
 
 
183
      if (!ok)
 
184
        return 0;
 
185
    }
 
186
 
 
187
  if (!warned)
 
188
    {
 
189
      fprintf (stderr,
 
190
               "\n\n********************   WARNING   *******************************\n");
 
191
      fprintf (stderr,
 
192
               "Warning! %s uses ALSA emulation instead of the native OSS API\n",
 
193
               cmd);
 
194
      fprintf (stderr,
 
195
               "****************************************************************\n\n");
 
196
    }
 
197
  warned = 1;
 
198
  return 1;
 
199
}
 
200
 
 
201
typedef struct _snd_ctl_card_info
 
202
{
 
203
  oss_card_info *info;
 
204
} snd_ctl_card_info_t;
 
205
 
 
206
/**
 
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
 
210
 *
 
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
 
214
 * are available.
 
215
 */
 
216
int
 
217
snd_card_next (int *rcard)
 
218
{
 
219
  ALIB_INIT ();
 
220
  if (!alib_appcheck ())
 
221
    return -ENODEV;
 
222
 
 
223
  if (*rcard == -1)
 
224
    *rcard = 0;
 
225
  else
 
226
    *rcard = *rcard + 1;
 
227
 
 
228
  if (*rcard >= sysinfo.numcards)
 
229
    {
 
230
      *rcard = -1;
 
231
      return 0;
 
232
    }
 
233
 
 
234
  return 0;
 
235
}
 
236
 
 
237
/**
 
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
 
241
 *
 
242
 * The accepted format is an integer value in ASCII representation
 
243
 * or the card identifier (the id parameter for sound-card drivers).
 
244
 */
 
245
int
 
246
snd_card_get_index (const char *string)
 
247
{
 
248
  dbg_printf ("snd_card_get_index(%s)\n", string);
 
249
  return -EINVAL;
 
250
}
 
251
 
 
252
/**
 
253
 * \brief Get card name from a CTL card info
 
254
 * \param obj CTL card info
 
255
 * \return card name
 
256
 */
 
257
const char *
 
258
snd_ctl_card_info_get_name (const snd_ctl_card_info_t * obj)
 
259
{
 
260
  return obj->info->longname;
 
261
}
 
262
 
 
263
/**
 
264
 * \brief get size of #snd_ctl_card_info_t
 
265
 * \return size in bytes
 
266
 */
 
267
size_t
 
268
snd_ctl_card_info_sizeof ()
 
269
{
 
270
  return sizeof (snd_ctl_card_info_t);
 
271
}
 
272
 
 
273
/**
 
274
 * \brief Opens a CTL
 
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
 
279
 */
 
280
int
 
281
snd_ctl_open (snd_ctl_t ** ctlp, const char *name, int mode)
 
282
{
 
283
  int num;
 
284
  snd_ctl_t *ctl;
 
285
 
 
286
  ALIB_INIT ();
 
287
  if (!alib_appcheck ())
 
288
    return -ENODEV;
 
289
 
 
290
  *ctlp = NULL;
 
291
 
 
292
  if (strcmp (name, "default") == 0)
 
293
    num = 0;
 
294
  else
 
295
    {
 
296
      if (name[0] != 'h' && name[1] != 'w' && name[2] != ':')
 
297
        return -ENOENT;
 
298
 
 
299
      if (sscanf (name + 3, "%d", &num) != 1)
 
300
        return -ENOENT;
 
301
    }
 
302
 
 
303
  if (num < 0 || num >= sysinfo.numcards)
 
304
    return -ENXIO;
 
305
 
 
306
 
 
307
  if ((ctl = malloc (sizeof (*ctl))) == NULL)
 
308
    return -ENOMEM;
 
309
 
 
310
  memset (ctl, 0, sizeof (*ctl));
 
311
  ctl->info.card = num;
 
312
  if (ioctl (mixer_fd, SNDCTL_CARDINFO, &ctl->info) == -1)
 
313
    {
 
314
      perror ("SNDCTL_CARDINFO");
 
315
      fprintf (stderr, "Mixer fd was %d\n", mixer_fd);
 
316
      return -errno;
 
317
    }
 
318
 
 
319
  *ctlp = ctl;
 
320
  return 0;
 
321
}
 
322
 
 
323
/**
 
324
 * \brief close CTL handle
 
325
 * \param ctl CTL handle
 
326
 * \return 0 on success otherwise a negative error code
 
327
 *
 
328
 * Closes the specified CTL handle and frees all associated
 
329
 * resources.
 
330
 */
 
331
int
 
332
snd_ctl_close (snd_ctl_t * ctl)
 
333
{
 
334
  free (ctl);
 
335
  return 0;
 
336
}
 
337
 
 
338
/**
 
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
 
343
 */
 
344
int
 
345
snd_ctl_card_info (snd_ctl_t * ctl, snd_ctl_card_info_t * info)
 
346
{
 
347
 
 
348
  memset (info, 0, sizeof (*info));
 
349
  info->info = &ctl->info;
 
350
 
 
351
  return 0;
 
352
}
 
353
 
 
354
/**
 
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
 
359
 */
 
360
int
 
361
snd_card_get_name (int card, char **name)
 
362
{
 
363
  char tmp[256];
 
364
 
 
365
  sprintf (tmp, "OSS%d", card);
 
366
 
 
367
  *name = strdup (tmp);
 
368
  return 0;
 
369
}
 
370
 
 
371
int
 
372
snd_card_get_longname (int card, char **name)
 
373
{
 
374
  oss_card_info ci;
 
375
 
 
376
  ci.card = card;
 
377
  if (ioctl (mixer_fd, SNDCTL_CARDINFO, &ci) == -1)
 
378
    return -errno;
 
379
 
 
380
  *name = strdup (ci.longname);
 
381
  return 0;
 
382
}
 
383
 
 
384
/**
 
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
 
389
 */
 
390
int
 
391
snd_ctl_pcm_next_device (snd_ctl_t * ctl, int *device)
 
392
{
 
393
  ALIB_INIT ();
 
394
 
 
395
  dbg_printf ("snd_ctl_pcm_next_device(%d)\n", *device);
 
396
 
 
397
  if (*device < 0)
 
398
    *device = 0;
 
399
  else
 
400
    {
 
401
      *device = *device + 1;
 
402
    }
 
403
 
 
404
  while (1)
 
405
    {
 
406
      if (*device < 0 || *device >= sysinfo.numaudios)
 
407
        {
 
408
          *device = -1;
 
409
          return 0;
 
410
        }
 
411
 
 
412
      ctl->ainfo.dev = *device;
 
413
      if (ioctl (mixer_fd, SNDCTL_AUDIOINFO, &ctl->ainfo) < 0)
 
414
        return -errno;
 
415
 
 
416
      if (ctl->ainfo.card_number == ctl->info.card)
 
417
        {
 
418
          return 0;
 
419
        }
 
420
 
 
421
      *device = *device + 1;
 
422
    }
 
423
 
 
424
  *device = -1;
 
425
  return 0;
 
426
}
 
427
 
 
428
/**
 
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
 
433
 */
 
434
int
 
435
snd_ctl_pcm_info (snd_ctl_t * ctl, snd_pcm_info_t * info)
 
436
{
 
437
  dbg_printf ("snd_ctl_pcm_info()\n");
 
438
  memset (info, 0, sizeof (*info));
 
439
  info->ainfo = &ctl->ainfo;
 
440
  return 0;
 
441
}
 
442
 
 
443
/**
 
444
 * \brief Get card mixer name from a CTL card info
 
445
 * \param obj CTL card info
 
446
 * \return card mixer name
 
447
 */
 
448
const char *
 
449
snd_ctl_card_info_get_mixername (const snd_ctl_card_info_t * obj)
 
450
{
 
451
  return obj->info->longname;
 
452
}
 
453
 
 
454
/**
 
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
 
459
 */
 
460
int
 
461
snd_ctl_rawmidi_info (snd_ctl_t * ctl, snd_rawmidi_info_t * info)
 
462
{
 
463
  dbg_printf ("snd_ctl_rawmidi_info()\n");
 
464
 
 
465
  return 0;
 
466
}
 
467
 
 
468
/**
 
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
 
473
 */
 
474
int
 
475
snd_ctl_rawmidi_next_device (snd_ctl_t * ctl, int *device)
 
476
{
 
477
  dbg_printf ("snd_ctl_rawmidi_next_device()\n");
 
478
 
 
479
  if (*device < 0)
 
480
    *device = 0;
 
481
  else
 
482
    *device = -1;
 
483
 
 
484
  return 0;
 
485
}
 
486
 
 
487
/**
 
488
 * \brief Get card identifier from a CTL card info
 
489
 * \param obj CTL card info
 
490
 * \return card identifier
 
491
 */
 
492
const char *
 
493
snd_ctl_card_info_get_id (const snd_ctl_card_info_t * obj)
 
494
{
 
495
  dbg_printf ("snd_ctl_card_info_get_id()\n");
 
496
 
 
497
  return "snd_ctl_card_info_get_id";
 
498
}