Mercurial > mplayer.hg
changeset 12805:0b154063a3ca
fixes provided by reimar drfinger. mixer, subdevice parsing, alsa#help,
set chunksize, others.
author | joyping |
---|---|
date | Tue, 13 Jul 2004 15:47:16 +0000 |
parents | 0106b9917013 |
children | 2a02e3dc8ba3 |
files | libao2/ao_alsa.c |
diffstat | 1 files changed, 74 insertions(+), 78 deletions(-) [+] |
line wrap: on
line diff
--- a/libao2/ao_alsa.c Mon Jul 12 21:49:37 2004 +0000 +++ b/libao2/ao_alsa.c Tue Jul 13 15:47:16 2004 +0000 @@ -79,7 +79,7 @@ #define ALSA_DEVICE_SIZE 256 #undef BUFFERTIME -#undef SET_CHUNKSIZE +#define SET_CHUNKSIZE #undef USE_POLL /* to set/get/query special features/parameters */ @@ -104,7 +104,7 @@ long pmin, pmax; long get_vol, set_vol; - float calc_vol, diff, f_multi; + float f_multi; if(mixer_channel) mix_name = mixer_channel; if(mixer_device) card = mixer_device; @@ -152,17 +152,11 @@ } snd_mixer_selem_get_playback_volume_range(elem,&pmin,&pmax); - f_multi = (100 / (float)pmax); + f_multi = (100 / (float)pmax - pmin); if (cmd == AOCONTROL_SET_VOLUME) { - diff = (vol->left+vol->right) / 2; - set_vol = rint(diff / f_multi); - - if (set_vol < 0) - set_vol = 0; - else if (set_vol > pmax) - set_vol = pmax; + set_vol = (vol->left + pmin) / f_multi + 0.5; //setting channels if ((err = snd_mixer_selem_set_playback_volume(elem, 0, set_vol)) < 0) { @@ -170,23 +164,25 @@ snd_strerror(err)); return CONTROL_ERROR; } + mp_msg(MSGT_AO,MSGL_DBG2,"left=%li, ", set_vol); + + set_vol = (vol->right + pmin) / f_multi + 0.5; + if ((err = snd_mixer_selem_set_playback_volume(elem, 1, set_vol)) < 0) { mp_msg(MSGT_AO,MSGL_ERR,"alsa-control: error setting right channel, %s\n", snd_strerror(err)); return CONTROL_ERROR; } - - mp_msg(MSGT_AO,MSGL_DBG2,"diff=%f, set_vol=%li, pmax=%li, mult=%f\n", - diff, set_vol, pmax, f_multi); + mp_msg(MSGT_AO,MSGL_DBG2,"right=%li, pmin=%li, pmax=%li, mult=%f\n", + set_vol, pmin, pmax, f_multi); } else { snd_mixer_selem_get_playback_volume(elem, 0, &get_vol); - calc_vol = get_vol; - calc_vol = rintf(calc_vol * f_multi); + vol->left = (get_vol * f_multi) - pmin; + snd_mixer_selem_get_playback_volume(elem, 1, &get_vol); + vol->right = (get_vol * f_multi) - pmin; - vol->left = vol->right = (int)calc_vol; - - mp_msg(MSGT_AO,MSGL_DBG2,"get_vol = %li, calc=%f\n",get_vol, calc_vol); + mp_msg(MSGT_AO,MSGL_DBG2,"left=%f, right=%f\n",vol->left,vol->right); } snd_mixer_close(handle); return CONTROL_OK; @@ -197,6 +193,30 @@ return(CONTROL_UNKNOWN); } +static void parse_device (char *dest, char *src, int len) +{ + char *tmp; + strncpy (dest, src, len); + while ((tmp = strrchr(dest, '.'))) + tmp[0] = ','; + while ((tmp = strrchr(dest, '#'))) + tmp[0] = ':'; +} + +static void print_help () +{ + mp_msg (MSGT_AO, MSGL_FATAL, + "\n-ao alsa commandline help:\n" + "Example: mplayer -ao alsa:mmap:device=hw#0.3\n" + " sets mmap-mode and first card fourth device\n" + "\nOptions:\n" + " mmap\n" + " Set memory-mapped mode, experimental\n" + " noblock\n" + " Sets non-blocking mode\n" + " device=<device-name>\n" + " Sets device (change , to . and : to #)\n"); +} /* open & setup audio device @@ -206,7 +226,6 @@ { int err; int cards = -1; - int period_val; snd_pcm_info_t *alsa_info; char *str_block_mode; int device_set = 0; @@ -284,6 +303,8 @@ break; case SND_PCM_FORMAT_S16_LE: case SND_PCM_FORMAT_U16_LE: + case SND_PCM_FORMAT_S16_BE: + case SND_PCM_FORMAT_U16_BE: ao_data.bps *= 2; break; case SND_PCM_FORMAT_S32_LE: @@ -301,55 +322,38 @@ mp_msg(MSGT_AO,MSGL_WARN,"alsa-init: couldn't convert to right format. setting bps to: %d", ao_data.bps); } + //subdevice parsing if (ao_subdevice) { - //start parsing ao_subdevice, ugly and not thread safe! - //maybe there's a better way? - int i2 = 1; - int i3 = 0; - char *sub_str; - - char *token_str[3]; - char* test_str = strdup(ao_subdevice); - - - if ((strcspn(ao_subdevice, ":")) > 0) { - - sub_str = strtok(test_str, ":"); - *(token_str) = sub_str; - - while (((sub_str = strtok(NULL, ":")) != NULL) && (i2 <= 3)) { - *(token_str+i2) = sub_str; - i2 += 1; - } - - for (i3=0; i3 <= i2-1; i3++) { - if (strcmp(*(token_str + i3), "mmap") == 0) { - ao_mmap = 1; - } - else if (strcmp(*(token_str+i3), "noblock") == 0) { - ao_noblock = 1; - } - else if (strcmp(*(token_str+i3), "hw") == 0) { - if ((i3 < i2-1) && (strcmp(*(token_str+i3+1), "noblock") != 0) && (strcmp(*(token_str+i3+1), "mmap") != 0)) { - char *tmp; - - snprintf(alsa_device, ALSA_DEVICE_SIZE, "hw:%s", *(token_str+(i3+1))); - if ((tmp = strrchr(alsa_device, '.')) && isdigit(*(tmp+1))) - *tmp = ','; - device_set = 1; - } - else { - strncpy (alsa_device, token_str[i3], ALSA_DEVICE_SIZE); - device_set = 1; - } - } - else if (device_set == 0 && (!ao_mmap || !ao_noblock)) { - strncpy (alsa_device, token_str[i3], ALSA_DEVICE_SIZE); - device_set = 1; - } - } + 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 + /* in any case for multichannel playback we should select * appropriate device */ @@ -449,14 +453,6 @@ } mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: %d soundcard%s found, using: %s\n", cards+1,(cards >= 0) ? "" : "s", alsa_device); - } else if (strcmp(alsa_device, "help") == 0) { - printf("alsa-help: available options are:\n"); - printf(" mmap: sets mmap-mode\n"); - printf(" noblock: sets noblock-mode\n"); - printf(" device-name: sets device name (change comma to point)\n"); - printf(" example -ao alsa9:mmap:noblock:hw:0.3 sets noblock-mode,\n"); - printf(" mmap-mode and the device-name as first card fourth device\n"); - return(0); } else { mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: soundcard set to %s\n", alsa_device); } @@ -942,7 +938,7 @@ mp_msg(MSGT_AO,MSGL_ERR,"alsa-play: write error %s", snd_strerror(res)); return 0; } - return res < 0 ? (int)res : len - len % bytes_per_sample; + return len - len % bytes_per_sample; } /* mmap-mode mainly based on descriptions by Joshua Haberman <joshua@haberman.com> @@ -955,7 +951,7 @@ snd_pcm_uframes_t frames_transmit, size, offset; const snd_pcm_channel_area_t *area; void *outbuffer; - int err, result; + int result; #ifdef USE_POLL //seems not really be needed struct pollfd *ufds; @@ -1073,15 +1069,15 @@ { case SND_PCM_STATE_OPEN: str_status = "open"; + ret = snd_pcm_status_get_avail(status) * bytes_per_sample; + break; case SND_PCM_STATE_PREPARED: - if (str_status != "open") { str_status = "prepared"; first = 1; ret = snd_pcm_status_get_avail(status) * bytes_per_sample; if (ret == 0) //ugly workaround for hang in mmap-mode ret = 10; break; - } case SND_PCM_STATE_RUNNING: ret = snd_pcm_status_get_avail(status) * bytes_per_sample; //avail_frames = snd_pcm_avail_update(alsa_handler) * bytes_per_sample; @@ -1107,7 +1103,7 @@ } } - if (str_status != "running") + if (snd_pcm_status_get_state(status) == SND_PCM_STATE_RUNNING) mp_msg(MSGT_AO,MSGL_V,"alsa-space: free space = %i, status=%i, %s --\n", ret, status, str_status); if (ret < 0) {