# HG changeset patch # User William Pitcock # Date 1186921030 18000 # Node ID 7b3aa5513041053fd81d59d2d47dce04c5e2102d # Parent dd05a74648a73665f3da0f2e3d30996da2680ec2 Port some changes over from XMMS that: - fix a memory leak - make software volume adjustment logarithmic (can we move this to the core?) Patch from: Matti Hamalainen (ccr) diff -r dd05a74648a7 -r 7b3aa5513041 src/alsa/audio.c --- a/src/alsa/audio.c Sat Aug 11 23:51:50 2007 -0500 +++ b/src/alsa/audio.c Sun Aug 12 07:17:10 2007 -0500 @@ -2,7 +2,7 @@ * Copyright (C) 2001-2003 Matthieu Sozeau * Copyright (C) 1998-2003 Peter Alm, Mikael Alm, Olle Hallnas, * Thomas Nilsson and 4Front Technologies - * Copyright (C) 1999-2005 Haavard Kvaalen + * Copyright (C) 1999-2006 Haavard Kvaalen * Copyright (C) 2005 Takashi Iwai * * This program is free software; you can redistribute it and/or modify @@ -31,6 +31,7 @@ #include "alsa.h" #include +#include #include static snd_pcm_t *alsa_pcm; @@ -345,8 +346,6 @@ debug("alsa_get_mixer"); - dev = g_strdup_printf("hw:%i", card); - if ((err = snd_mixer_open(mixer, 0)) < 0) { g_warning("alsa_get_mixer(): Failed to open empty mixer: %s", @@ -354,12 +353,17 @@ mixer = NULL; return -1; } + + dev = g_strdup_printf("hw:%i", card); if ((err = snd_mixer_attach(*mixer, dev)) < 0) { g_warning("alsa_get_mixer(): Attaching to mixer %s failed: %s", dev, snd_strerror(-err)); + g_free(dev); return -1; } + g_free(dev); + if ((err = snd_mixer_selem_register(*mixer, NULL, NULL)) < 0) { g_warning("alsa_get_mixer(): Failed to register mixer: %s", @@ -373,8 +377,6 @@ return -1; } - g_free(dev); - return (*mixer != NULL); } @@ -459,7 +461,6 @@ mixer_timeout = 0; mixer_start = TRUE; - g_message("alsa mixer timed out"); return FALSE; } @@ -594,10 +595,10 @@ for (i = 0; i < length; i += 4) \ { \ *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) * \ - alsa_cfg.vol.left / 100); \ + lvol / 256); \ ptr++; \ *ptr = type2##_TO_##endian(type2##_FROM_##endian(*ptr) * \ - alsa_cfg.vol.right / 100); \ + rvol / 256); \ ptr++; \ } \ } while (0) @@ -608,7 +609,7 @@ for (i = 0; i < length; i += 2) \ { \ *ptr = type2##_TO_##endian(type2##_FROM_## endian(*ptr) * \ - vol / 100); \ + vol / 256); \ ptr++; \ } \ } while (0) @@ -626,9 +627,9 @@ type *ptr = data; \ for (i = 0; i < length; i += 2) \ { \ - *ptr = *ptr * alsa_cfg.vol.left / 100; \ + *ptr = *ptr * lvol / 256; \ ptr++; \ - *ptr = *ptr * alsa_cfg.vol.right / 100; \ + *ptr = *ptr * rvol / 256; \ ptr++; \ } \ } while (0) @@ -638,7 +639,7 @@ type *ptr = data; \ for (i = 0; i < length; i++) \ { \ - *ptr = *ptr * vol / 100; \ + *ptr = *ptr * vol / 256; \ ptr++; \ } \ } while (0) @@ -654,14 +655,16 @@ static void volume_adjust(void* data, int length, AFormat fmt, int channels) { - int i, vol; + int i, vol, lvol, rvol; if ((alsa_cfg.vol.left == 100 && alsa_cfg.vol.right == 100) || (channels == 1 && (alsa_cfg.vol.left == 100 || alsa_cfg.vol.right == 100))) return; - vol = MAX(alsa_cfg.vol.left, alsa_cfg.vol.right); + lvol = pow(10, (alsa_cfg.vol.left - 100) / 40.0) * 256; + rvol = pow(10, (alsa_cfg.vol.right - 100) / 40.0) * 256; + vol = MAX(lvol, rvol); switch (fmt) { @@ -971,8 +974,7 @@ int err; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; - uint alsa_buffer_time; - unsigned int alsa_period_time; + unsigned int alsa_buffer_time, alsa_period_time; snd_pcm_uframes_t alsa_buffer_size, alsa_period_size; debug("alsa_setup"); @@ -1149,11 +1151,11 @@ } alsa_can_pause = snd_pcm_hw_params_can_pause(hwparams); + debug("can pause: %d", alsa_can_pause); snd_pcm_sw_params_alloca(&swparams); snd_pcm_sw_params_current(alsa_pcm, swparams); - /* This has effect for non-mmap only */ if ((err = snd_pcm_sw_params_set_start_threshold(alsa_pcm, swparams, alsa_buffer_size - alsa_period_size) < 0)) g_warning("alsa_setup(): setting start "