Index: libao2/ao_alsa.c =================================================================== RCS file: /cvsroot/mplayer/main/libao2/ao_alsa.c,v retrieving revision 1.3 diff -u -r1.3 ao_alsa.c --- libao2/ao_alsa.c 2 Jul 2004 04:30:46 -0000 1.3 +++ libao2/ao_alsa.c 4 Jul 2004 00:25:33 -0000 @@ -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,41 +152,36 @@ } 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) { mp_msg(MSGT_AO,MSGL_ERR,"alsa-control: error setting left channel, %s\n", 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; - vol->left = vol->right = (int)calc_vol; + snd_mixer_selem_get_playback_volume(elem, 1, &get_vol); + vol->right = (get_vol * f_multi) - pmin; - 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 +192,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=\n" + " Sets device (change , to . and : to #)\n"); +} /* open & setup audio device @@ -206,7 +225,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 +302,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,53 +321,36 @@ mp_msg(MSGT_AO,MSGL_WARN,"alsa-init: couldn't convert to right format. setting bps to: %d", ao_data.bps); } + ao_mmap = 0; + ao_noblock = 0; 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 @@ -449,14 +452,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 +937,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 @@ -955,7 +950,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; @@ -974,8 +969,6 @@ } #endif - outbuffer = alloca(ao_data.buffersize); - //don't trust get_space() ;) frames_available = snd_pcm_avail_update(alsa_handler) * bytes_per_sample; if (frames_available < 0) @@ -1073,19 +1066,18 @@ { 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; - if (str_status != "open" && str_status != "prepared") str_status = "running"; break; case SND_PCM_STATE_PAUSED: @@ -1107,8 +1099,8 @@ } } - if (str_status != "running") - mp_msg(MSGT_AO,MSGL_V,"alsa-space: free space = %i, status=%i, %s --\n", ret, status, str_status); + if (strcmp(str_status,"running")) + mp_msg(MSGT_AO,MSGL_V,"alsa-space: free space = %i, status=%p, %s --\n", ret, status, str_status); if (ret < 0) { mp_msg(MSGT_AO,MSGL_ERR,"negative value!!\n"); Index: DOCS/man/en/mplayer.1 =================================================================== RCS file: /cvsroot/mplayer/main/DOCS/man/en/mplayer.1,v retrieving revision 1.618 diff -u -r1.618 mplayer.1 --- DOCS/man/en/mplayer.1 2 Jul 2004 13:10:58 -0000 1.618 +++ DOCS/man/en/mplayer.1 4 Jul 2004 00:25:59 -0000 @@ -1572,7 +1572,7 @@ .RSs .IPs "\-ao alsa,oss," Try the ALSA driver, then the OSS driver, then others. -.IPs "\-ao alsa:mmap:noblock:hw=0.3" +.IPs "\-ao alsa:mmap:noblock:device=hw#0.3" Sets noblock-mode, mmap-mode and the device-name as first card, fourth device. .RE .PD 1 @@ -1592,9 +1592,9 @@ Sets experimental mmap-mode (does not work for more than 2 channels). .IPs noblock Sets noblock-mode. -.IPs hw= +.IPs device= Sets the device name. -Replace the ',' with a '.' in the ALSA device name. +Replace any ',' with '.' and any ':' with '#' in the ALSA device name. .RE .PD 1 .TP