]> git.alsa-project.org Git - alsa-utils.git/commitdiff
Ported aplay to named PCMs
authorAbramo Bagnara <abramo@alsa-project.org>
Thu, 24 Aug 2000 17:59:21 +0000 (17:59 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Thu, 24 Aug 2000 17:59:21 +0000 (17:59 +0000)
aplay/aplay.c

index 269a5f5b3a15924c3160f686f68698452af2b5c5..6c7f4cbb11cb7b25ead0d396e67a6449e45844e9 100644 (file)
@@ -183,13 +183,16 @@ Usage: %s [OPTION]... [FILE]...
 
 --help                   help
 --version                print current version
---list-devices           list all soundcards and digital audio devices
--C, --card=#             select card # or card id (0-%i), defaults to 0
+-l,--list-devices        list all soundcards and digital audio devices
+-L,--list-pcms           list all PCMs defined
+
+-P, --pcm=NAME           select PCM by name
+ or
+-C, --card=#             select card # (0-%i) or id, defaults to 0
 -D, --device=#           select device #, defaults to 0
--S, --subdevice=#        select subdevice #, defaults to first available
--P, --direct             don't use plugins for this PCM
--H, --pcm-channels=#     channels for last specified PCM 
--h, --bind-channel=C,S   bind stream channel C to PCM channel S
+-S, --subdevice=#        select subdevice #, defaults to first free
+-i, --direct             don't use plugins for this PCM
+
 -q, --quiet              quiet mode
 -t, --file-type TYPE     file type (voc, wav or raw)
 -c, --channels=#         channels
@@ -198,7 +201,6 @@ Usage: %s [OPTION]... [FILE]...
 -d, --duration=#         interrupt after # seconds
 -e, --frame-mode         use frame mode instead of default fragment mode
 -M, --mmap               mmap stream
--Q, --multi-direct       don't use plugins on top of multi
 -N, --nonblock           nonblocking mode
 -F, --fragment-length=#  fragment length is # milliseconds
 -B, --buffer-length=#    buffer length is # milliseconds
@@ -273,6 +275,19 @@ static void device_list(void)
        }
 }
 
+static void pcm_list(void)
+{
+       snd_config_t *conf;
+       int err = snd_config_update();
+       if (err < 0)
+               error("snd_pcm_update: %s\n", snd_strerror(err));
+       err = snd_config_search(snd_config, "pcm", &conf);
+       if (err < 0)
+               return;
+       fprintf(stderr, "PCM list:\n");
+       snd_config_save(conf, stderr);
+}
+
 static void version(void)
 {
        fprintf(stderr, "%s: version " SND_UTIL_VERSION_STR " by Jaroslav Kysela <perex@suse.cz>\n", command);
@@ -284,16 +299,17 @@ static void version(void)
 int main(int argc, char *argv[])
 {
        int option_index;
-       char *short_options = "lC:D:S:H:h:qt:c:f:r:d:eMPQA:B:F:NvI";
+       char *short_options = "lLP:C:D:S:iqt:c:f:r:d:eMNF:A:B:vI";
        static struct option long_options[] = {
                {"help", 0, 0, OPT_HELP},
                {"version", 0, 0, OPT_VERSION},
                {"list-devices", 0, 0, 'l'},
+               {"list-pcms", 0, 0, 'L'},
+               {"pcm", 1, 0, 'P'},
                {"card", 1, 0, 'C'},
                {"device", 1, 0, 'D'},
                {"subdevice", 1, 0, 'S'},
-               {"pcm-channels", 1, 0, 'H'},
-               {"bind-channel", 1, 0, 'h'},
+               {"direct", 0, 0, 'i'},
                {"quiet", 0, 0, 'q'},
                {"file-type", 1, 0, 't'},
                {"channels", 1, 0, 'c'},
@@ -302,58 +318,18 @@ int main(int argc, char *argv[])
                {"duration", 1, 0 ,'d'},
                {"frame-mode", 0, 0, 'e'},
                {"mmap", 0, 0, 'M'},
-               {"direct", 0, 0, 'P'},
-               {"multi-direct", 0, 0, 'Q'},
                {"nonblock", 0, 0, 'N'},
                {"fragment-length", 1, 0, 'F'},
-               {"buffer-length", 1, 0, 'B'},
                {"min-avail", 1, 0, 'A'},
+               {"buffer-length", 1, 0, 'B'},
                {"verbose", 0, 0, 'v'},
                {"separate-channels", 0, 0, 'I'},
                {0, 0, 0, 0}
        };
-       int binds_pcm[32];
-       int binds_client_channel[32];
-       int binds_slave_channel[32];
-       int pcms_card[32];
-       int pcms_dev[32];
-       int pcms_subdev[32];
-       size_t pcms_channels[32];
-       int pcms_direct[32];
        int direct = 0;
-       int multi_direct = 0;
-               
-       int pcm_card = 0, pcm_dev = 0, pcm_subdev = -1, pcm_channels = -1;
-       int tmp, err, c, client_channel, slave_channel;
-       int pcm;
-       int pcms_count = 0, binds_count = 0;
-       int multi;
-       char *ptr, *beg;
-
-       int get_pcm() {
-               int pcm;
-               if (pcm_channels < 0)
-                       pcm_channels = rformat.channels;
-               for (pcm = 0; pcm < pcms_count; ++pcm) {
-                       if (pcms_card[pcm] == pcm_card &&
-                           pcms_dev[pcm] == pcm_dev &&
-                           pcms_subdev[pcm] == pcm_subdev)
-                               break;
-               }
-               if (pcm == pcms_count) {
-                       pcms_card[pcm] = pcm_card;
-                       pcms_dev[pcm] = pcm_dev;
-                       pcms_subdev[pcm] = pcm_subdev;
-                       pcms_channels[pcm] = pcm_channels;
-                       pcms_direct[pcm] = direct;
-                       direct = 0;
-                       pcms_count++;
-               } else if (pcm_channels != pcms_channels[pcm]) {
-                       error("different channels count specified for the same pcm\n");
-                       exit(1);
-               }
-               return pcm;
-       }
+       char *pcm_name = NULL;
+       int pcm_card = -1, pcm_dev = -1, pcm_subdev = -1;
+       int tmp, err, c;
 
        command = argv[0];
        file_type = FORMAT_DEFAULT;
@@ -387,7 +363,22 @@ int main(int argc, char *argv[])
                case 'l':
                        device_list();
                        return 0;
+               case 'L':
+                       pcm_list();
+                       return 0;
+               case 'P':
+                       if (pcm_card >= 0 || pcm_dev >=0 || pcm_dev >=0 || 
+                           direct) {
+                               error("-P cannot be used together with -C, -D, -S or -i\n");
+                               return -1;
+                       }
+                       pcm_name = optarg;
+                       break;
                case 'C':
+                       if (pcm_name) {
+                               error("-P cannot be used together with -C, -D, -S or -i\n");
+                               return -1;
+                       }
                        pcm_card = snd_card_name(optarg);
                        if (pcm_card < 0) {
                                error("soundcard '%s' not found\n", optarg);
@@ -395,6 +386,10 @@ int main(int argc, char *argv[])
                        }
                        break;
                case 'D':
+                       if (pcm_name) {
+                               error("-P cannot be used together with -C, -D, -S or -i\n");
+                               return -1;
+                       }
                        pcm_dev = atoi(optarg);
                        if (pcm_dev < 0 || pcm_dev > 32) {
                                error("device %i is invalid\n", pcm_dev);
@@ -402,44 +397,22 @@ int main(int argc, char *argv[])
                        }
                        break;
                case 'S':
+                       if (pcm_name) {
+                               error("-P cannot be used together with -C, -D, -S or -i\n");
+                               return -1;
+                       }
                        pcm_subdev = atoi(optarg);
                        if (pcm_subdev < 0 || pcm_subdev > 32) {
                                error("subdevice %i is invalid\n", pcm_subdev);
                                return 1;
                        }
                        break;
-               case 'H':
-                       pcm_channels = atoi(optarg);
-                       if (pcm_channels < 1 || pcm_channels > 32) {
-                               error("value %i for channels is invalid\n", pcm_channels);
-                               return 1;
-                       }
-                       break;
-               case 'h':
-                       client_channel = strtol(optarg, &ptr, 10);
-                       if (*ptr != ',' || ptr == optarg) {
-                               error("invalid channel binding syntax\n");
-                               return 1;
-                       }
-                       beg = ptr + 1;
-                       slave_channel = strtol(beg, &ptr, 10);
-                       if (*ptr || ptr == optarg) {
-                               error("invalid channel binding syntax\n");
-                               return 1;
-                       }
-                       if (client_channel >= rformat.channels) {
-                               error("attempt to bind unavailable channel %d\n", client_channel);
-                               return 1;
-                       }
-                       if (slave_channel >= pcm_channels) {
-                               error("attempt to bind to an unavailable PCM channel %d\n", slave_channel);
-                               return 1;
+               case 'i':
+                       if (pcm_name) {
+                               error("-P cannot be used together with -C, -D, -S or -i\n");
+                               return -1;
                        }
-                       pcm = get_pcm();
-                       binds_pcm[binds_count] = pcm;
-                       binds_client_channel[binds_count] = client_channel;
-                       binds_slave_channel[binds_count] = slave_channel;
-                       ++binds_count;
+                       direct = 1;
                        break;
                case 'q':
                        quiet_mode = 1;
@@ -499,12 +472,6 @@ int main(int argc, char *argv[])
                case 'M':
                        mmap_flag = 1;
                        break;
-               case 'P':
-                       direct = 1;
-                       break;
-               case 'Q':
-                       multi_direct = 1;
-                       break;
                case 'N':
                        nonblock = 1;
                        open_mode |= SND_PCM_NONBLOCK;
@@ -530,86 +497,23 @@ int main(int argc, char *argv[])
                }
        }
 
-       if (binds_count == 0) {
-               pcm = get_pcm();
-               for (c = 0; c < rformat.channels; ++c) {
-                       if (c > pcm_channels) {
-                               error("attempt to bind to an unavailable PCM channel %d\n", c);
-                               return 1;
-                       }
-                       binds_pcm[binds_count] = pcm;
-                       binds_client_channel[binds_count] = c;
-                       binds_slave_channel[binds_count] = c;
-                       binds_count++;
-               }
-       }
-
-       if (!quiet_mode)
-               version();
-
-       assert(pcms_count > 0);
-
-       multi = 0;
-       if (pcms_count != 1 || rformat.channels != binds_count || 
-           pcm_channels != binds_count)
-               multi = 1;
+       if (pcm_name)
+               err = snd_pcm_open(&handle, pcm_name, stream, open_mode);
        else {
-               char mask[binds_count];
-               memset(mask, 0, sizeof(mask));
-               for (c = 0; c < binds_count; ++c) {
-                       if (binds_client_channel[c] != binds_slave_channel[c]) {
-                               multi = 1;
-                               break;
-                       }
-                       if (mask[c]) {
-                               multi = 1;
-                               break;
-                       }
-                       mask[c] = 1;
-               }
+               if (pcm_card < 0)
+                       pcm_card = 0;
+               if (pcm_dev < 0)
+                       pcm_dev = 0;
+               if (direct)
+                       err = snd_pcm_hw_open_subdevice(&handle, pcm_card, pcm_dev, pcm_subdev, stream, open_mode);
+               else
+                       err = snd_pcm_plug_open_subdevice(&handle, pcm_card, pcm_dev, pcm_subdev, stream, open_mode);
        }
-       if (!quiet_mode) {
-               for (pcm = 0; pcm < pcms_count; ++pcm) {
-                       char *cardname;
-                       if ((err = snd_card_get_longname(pcms_card[pcm], &cardname)) < 0) {
-                               error("unable to obtain longname: %s\n", snd_strerror(err));
-                               return 1;
-                       }
-                       fprintf(stderr, "Using soundcard '%s'\n", cardname);
-                       free(cardname);
-               }
+       if (err < 0) {
+               error("audio open error: %s\n", snd_strerror(err));
+               return 1;
        }
 
-       {
-               snd_pcm_t *handles[pcms_count];
-               for (pcm = 0; pcm < pcms_count; ++pcm) {
-                       if (pcms_direct[pcm])
-                               err = snd_pcm_hw_open_subdevice(&handles[pcm], pcms_card[pcm], pcms_dev[pcm], pcms_subdev[pcm], stream, open_mode);
-                       else
-                               err = snd_pcm_plug_open_subdevice(&handles[pcm], pcms_card[pcm], pcms_dev[pcm], pcms_subdev[pcm], stream, open_mode);
-                       if (err < 0) {
-                               error("audio open error: %s\n", snd_strerror(err));
-                               return 1;
-                       }
-               }
-               if (multi) {
-                       err = snd_pcm_multi_create(&handle, pcms_count, handles, pcms_channels, binds_count, binds_client_channel, binds_pcm, binds_slave_channel, 1);
-                       if (err < 0) {
-                               error("audio open error: %s\n", snd_strerror(err));
-                               return 1;
-                       }
-                       if (!multi_direct) {
-                               snd_pcm_t *h = handle;
-                               err = snd_pcm_plug_create(&handle, h, 1);
-                               if (err < 0) {
-                                       error("audio open error: %s\n", snd_strerror(err));
-                                       return 1;
-                               }
-                       }
-               } else {
-                       handle = handles[0];
-               }
-       }
        if (nonblock) {
                err = snd_pcm_nonblock(handle, 1);
                if (err < 0) {