summaryrefslogtreecommitdiffstats
path: root/libao2/ao_alsa.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-01-03 14:23:18 +0000
committerreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2005-01-03 14:23:18 +0000
commitbf4f28d583f934a524681240017ddd4fe1a4f805 (patch)
tree859fa2dedc15264e8733a55541c6e8078bd4a50a /libao2/ao_alsa.c
parent60f4241a6dd6b31349a4e985927ae4806ad88835 (diff)
downloadmpv-bf4f28d583f934a524681240017ddd4fe1a4f805.tar.bz2
mpv-bf4f28d583f934a524681240017ddd4fe1a4f805.tar.xz
Use the subopt-helper for parsing suboptions.
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@14329 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'libao2/ao_alsa.c')
-rw-r--r--libao2/ao_alsa.c166
1 files changed, 57 insertions, 109 deletions
diff --git a/libao2/ao_alsa.c b/libao2/ao_alsa.c
index 022b056ad7..81a81b019c 100644
--- a/libao2/ao_alsa.c
+++ b/libao2/ao_alsa.c
@@ -20,6 +20,7 @@
#include <sys/poll.h>
#include "config.h"
+#include "subopt-helper.h"
#include "mixer.h"
#include "mp_msg.h"
@@ -214,10 +215,11 @@ static int control(int cmd, void *arg)
return(CONTROL_UNKNOWN);
}
-static void parse_device (char *dest, char *src, int len)
+static void parse_device (char *dest, const char *src, int len)
{
char *tmp;
- strncpy (dest, src, len);
+ memmove(dest, src, len);
+ dest[len] = 0;
while ((tmp = strrchr(dest, '.')))
tmp[0] = ',';
while ((tmp = strrchr(dest, '=')))
@@ -239,6 +241,12 @@ static void print_help ()
" Sets device (change , to . and : to =)\n");
}
+static int str_maxlen(strarg_t *str) {
+ if (str->len > ALSA_DEVICE_SIZE)
+ return 0;
+ return 1;
+}
+
/*
open & setup audio device
return: 1=success 0=fail
@@ -249,9 +257,17 @@ static int init(int rate_hz, int channels, int format, int flags)
int cards = -1;
snd_pcm_info_t *alsa_info;
char *str_block_mode;
- int device_set = 0;
int dir = 0;
+ int block;
+ strarg_t device;
snd_pcm_uframes_t bufsize;
+ opt_t subopts[] = {
+ {"mmap", OPT_ARG_BOOL, &ao_mmap, NULL},
+ {"block", OPT_ARG_BOOL, &block, NULL},
+ {"device", OPT_ARG_STR, &device, (opt_test_f)str_maxlen},
+ {NULL}
+ };
+
char alsa_device[ALSA_DEVICE_SIZE + 1];
// make sure alsa_device is null-terminated even when using strncpy etc.
memset(alsa_device, 0, ALSA_DEVICE_SIZE + 1);
@@ -343,138 +359,70 @@ static int init(int rate_hz, int channels, int format, int flags)
}
//subdevice parsing
- if (ao_subdevice) {
- int parse_err = 0;
- char *parse_pos = &ao_subdevice[0];
- while (parse_pos[0] && !parse_err) {
- if (strncmp (parse_pos, "mmap", 4) == 0) {
- parse_pos = &parse_pos[4];
- ao_mmap = 1;
- } else if (strncmp (parse_pos, "noblock", 7) == 0) {
- parse_pos = &parse_pos[7];
- ao_noblock = 1;
- } else if (strncmp (parse_pos, "device=", 7) == 0) {
- int name_len;
- parse_pos = &parse_pos[7];
- name_len = strcspn (parse_pos, ":");
- if (name_len < 0 || name_len > ALSA_DEVICE_SIZE) {
- parse_err = 1;
- break;
- }
- parse_device (alsa_device, parse_pos, name_len);
- parse_pos = &parse_pos[name_len];
- device_set = 1;
- }
- if (parse_pos[0] == ':') parse_pos = &parse_pos[1];
- else if (parse_pos[0]) parse_err = 1;
- }
- if (parse_err) {
- print_help();
- return 0;
- }
- } else { //end parsing ao_subdevice
+ // set defaults
+ ao_mmap = 0;
+ block = 1;
+ /* switch for spdif
+ * sets opening sequence for SPDIF
+ * sets also the playback and other switches 'on the fly'
+ * while opening the abstract alias for the spdif subdevice
+ * 'iec958'
+ */
+ if (format == AF_FORMAT_AC3) {
+ unsigned char s[4];
+ s[0] = IEC958_AES0_NONAUDIO |
+ IEC958_AES0_CON_EMPHASIS_NONE;
+ s[1] = IEC958_AES1_CON_ORIGINAL |
+ IEC958_AES1_CON_PCM_CODER;
+ s[2] = 0;
+ s[3] = IEC958_AES3_CON_FS_48000;
+
+ snprintf(alsa_device, ALSA_DEVICE_SIZE,
+ "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
+ s[0], s[1], s[2], s[3]);
+ device.str = alsa_device;
+
+ mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3, %i channels\n", channels);
+ }
+ else
/* in any case for multichannel playback we should select
* appropriate device
*/
switch (channels) {
case 1:
case 2:
+ device.str = "default";
mp_msg(MSGT_AO,MSGL_V,"alsa-init: setup for 1/2 channel(s)\n");
break;
case 4:
if (alsa_format == SND_PCM_FORMAT_FLOAT_LE)
// hack - use the converter plugin
- strncpy(alsa_device, "plug:surround40", ALSA_DEVICE_SIZE);
+ device.str = "plug:surround40";
else
- strncpy(alsa_device, "surround40", ALSA_DEVICE_SIZE);
- device_set = 1;
+ device.str = "surround40";
mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround40\n");
break;
case 6:
if (alsa_format == SND_PCM_FORMAT_FLOAT_LE)
- strncpy(alsa_device, "plug:surround51", ALSA_DEVICE_SIZE);
+ device.str = "plug:surround51";
else
- strncpy(alsa_device, "surround51", ALSA_DEVICE_SIZE);
- device_set = 1;
+ device.str = "surround51";
mp_msg(MSGT_AO,MSGL_V,"alsa-init: device set to surround51\n");
break;
default:
+ device.str = "default";
mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: %d channels are not supported\n",channels);
}
+ device.len = strlen(device.str);
+ if (subopt_parse(ao_subdevice, subopts) != 0) {
+ print_help();
+ return 0;
}
-
- if (!device_set) {
- /* switch for spdif
- * sets opening sequence for SPDIF
- * sets also the playback and other switches 'on the fly'
- * while opening the abstract alias for the spdif subdevice
- * 'iec958'
- */
- if (format == AF_FORMAT_AC3) {
- unsigned char s[4];
-
- switch (channels) {
- case 1:
- case 2:
-
- s[0] = IEC958_AES0_NONAUDIO |
- IEC958_AES0_CON_EMPHASIS_NONE;
- s[1] = IEC958_AES1_CON_ORIGINAL |
- IEC958_AES1_CON_PCM_CODER;
- s[2] = 0;
- s[3] = IEC958_AES3_CON_FS_48000;
-
- snprintf(alsa_device, ALSA_DEVICE_SIZE,
- "iec958:AES0=0x%x,AES1=0x%x,AES2=0x%x,AES3=0x%x",
- s[0], s[1], s[2], s[3]);
-
- mp_msg(MSGT_AO,MSGL_V,"alsa-spdif-init: playing AC3, %i channels\n", channels);
- break;
- case 4:
- strncpy(alsa_device, "surround40", ALSA_DEVICE_SIZE);
- break;
-
- case 6:
- strncpy(alsa_device, "surround51", ALSA_DEVICE_SIZE);
- break;
-
- default:
- mp_msg(MSGT_AO,MSGL_ERR,"alsa-spdif-init: %d channels are not supported\n", channels);
- }
- }
- else
-
- {
- int tmp_device, tmp_subdevice, err;
-
- snd_pcm_info_alloca(&alsa_info);
-
- if ((tmp_device = snd_pcm_info_get_device(alsa_info)) < 0)
- {
- mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: can't get device\n");
- }
-
- if ((tmp_subdevice = snd_pcm_info_get_subdevice(alsa_info)) < 0)
- {
- mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: can't get subdevice\n");
- }
-
- mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: got device=%i, subdevice=%i\n",
- tmp_device, tmp_subdevice);
-
- //we are setting here device to default cause it could be configured by the user
- //if its not set by the user, it defaults to hw:0,0
- if ((err = snprintf(alsa_device, ALSA_DEVICE_SIZE, "default")) <= 0)
- {
- mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: can't write device-id\n");
- }
+ ao_noblock = !block;
+ parse_device(alsa_device, device.str, device.len);
mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: %d soundcard%s found, using: %s\n", cards+1,(cards >= 0) ? "" : "s", alsa_device);
- }
- } else {
- mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: soundcard set to %s\n", alsa_device);
- }
//setting modes for block or nonblock-mode
if (ao_noblock) {