From: Jaroslav Kysela Date: Fri, 11 Jan 2008 16:21:44 +0000 (+0100) Subject: Added possibility to disable also channel and format conversions + softvol. X-Git-Tag: v1.0.16rc1~13 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=ab8331c8823157acfe3b24b837bd5f625acb9666;p=alsa-lib.git Added possibility to disable also channel and format conversions + softvol. Unified disable option using mode bits in snd_pcm_open(). --- diff --git a/include/pcm.h b/include/pcm.h index d217bb91..66082ce9 100644 --- a/include/pcm.h +++ b/include/pcm.h @@ -292,9 +292,17 @@ typedef unsigned long snd_pcm_uframes_t; typedef long snd_pcm_sframes_t; /** Non blocking mode (flag for open mode) \hideinitializer */ -#define SND_PCM_NONBLOCK 0x0001 +#define SND_PCM_NONBLOCK 0x00000001 /** Async notification (flag for open mode) \hideinitializer */ -#define SND_PCM_ASYNC 0x0002 +#define SND_PCM_ASYNC 0x00000002 +/** Disable automatic (but not forced!) rate resamplinig */ +#define SND_PCM_NO_AUTO_RESAMPLE 0x00010000 +/** Disable automatic (but not forced!) channel conversion */ +#define SND_PCM_NO_AUTO_CHANNELS 0x00020000 +/** Disable automatic (but not forced!) format conversion */ +#define SND_PCM_NO_AUTO_FORMAT 0x00040000 +/** Disable soft volume control */ +#define SND_PCM_NO_SOFTVOL 0x00080000 /** PCM handle */ typedef struct _snd_pcm snd_pcm_t; diff --git a/src/pcm/pcm_plug.c b/src/pcm/pcm_plug.c index 0c2ff6e3..ee74f44f 100644 --- a/src/pcm/pcm_plug.c +++ b/src/pcm/pcm_plug.c @@ -707,7 +707,9 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p snd_interval_t t, buffer_size; const snd_interval_t *srate, *crate; - if (plug->srate == -2) + if (plug->srate == -2 || + (pcm->mode & pcm->mode & SND_PCM_NO_AUTO_RESAMPLE) || + (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE)) links |= SND_PCM_HW_PARBIT_RATE; else { err = snd_pcm_hw_param_refine_multiple(slave, sparams, SND_PCM_HW_PARAM_RATE, params); @@ -715,14 +717,14 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p return err; } - if (plug->schannels == -2) + if (plug->schannels == -2 || (pcm->mode & SND_PCM_NO_AUTO_CHANNELS)) links |= SND_PCM_HW_PARBIT_CHANNELS; else { err = snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS, params); if (err < 0) return err; } - if (plug->sformat == -2) + if (plug->sformat == -2 || (pcm->mode & SND_PCM_NO_AUTO_FORMAT)) links |= SND_PCM_HW_PARBIT_FORMAT; else { format_mask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT); @@ -791,8 +793,6 @@ static int snd_pcm_plug_hw_refine_schange(snd_pcm_t *pcm, snd_pcm_hw_params_t *p err = _snd_pcm_hw_params_refine(sparams, links, params); if (err < 0) return err; - if (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE) - snd_interval_copy((snd_interval_t *)snd_pcm_hw_param_get_interval(params, SND_PCM_HW_PARAM_RATE), snd_pcm_hw_param_get_interval(sparams, SND_PCM_HW_PARAM_RATE)); return 0; } @@ -811,10 +811,10 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, const snd_interval_t *sbuffer_size; const snd_interval_t *srate, *crate; - if (plug->schannels == -2) + if (plug->schannels == -2 || (pcm->mode & SND_PCM_NO_AUTO_CHANNELS)) links |= SND_PCM_HW_PARBIT_CHANNELS; - if (plug->sformat == -2) + if (plug->sformat == -2 || (pcm->mode & SND_PCM_NO_AUTO_FORMAT)) links |= SND_PCM_HW_PARBIT_FORMAT; else { format_mask = snd_pcm_hw_param_get_mask(params, @@ -857,7 +857,9 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, return err; } - if (plug->srate == -2) + if (plug->srate == -2 || + (pcm->mode & SND_PCM_NO_AUTO_RESAMPLE) || + (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE)) links |= SND_PCM_HW_PARBIT_RATE; else { unsigned int rate_min, srate_min; @@ -895,8 +897,6 @@ static int snd_pcm_plug_hw_refine_cchange(snd_pcm_t *pcm ATTRIBUTE_UNUSED, err = _snd_pcm_hw_params_refine(params, links, sparams); if (err < 0) return err; - if (params->flags & SND_PCM_HW_PARAMS_NORESAMPLE) - snd_interval_copy((snd_interval_t *)snd_pcm_hw_param_get_interval(params, SND_PCM_HW_PARAM_RATE), snd_pcm_hw_param_get_interval(sparams, SND_PCM_HW_PARAM_RATE)); /* FIXME */ params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID); return 0; diff --git a/src/pcm/pcm_softvol.c b/src/pcm/pcm_softvol.c index 8f912045..7af7f40b 100644 --- a/src/pcm/pcm_softvol.c +++ b/src/pcm/pcm_softvol.c @@ -969,34 +969,43 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name, SNDERR("Invalid resolution value %d", resolution); return -EINVAL; } - err = snd_pcm_slave_conf(root, slave, &sconf, 1, - SND_PCM_HW_PARAM_FORMAT, 0, &sformat); - if (err < 0) - return err; - if (sformat != SND_PCM_FORMAT_UNKNOWN && - sformat != SND_PCM_FORMAT_S16_LE && - sformat != SND_PCM_FORMAT_S16_BE && - sformat != SND_PCM_FORMAT_S24_3LE && - sformat != SND_PCM_FORMAT_S32_LE && - sformat != SND_PCM_FORMAT_S32_BE) { - SNDERR("only S16_LE, S16_BE, S24_3LE, S32_LE or S32_BE format " - "is supported"); + if (mode & SND_PCM_NO_SOFTVOL) { + err = snd_pcm_slave_conf(root, slave, &sconf, 0); + if (err < 0) + return err; + err = snd_pcm_open_named_slave(pcmp, name, root, sconf, stream, + mode, conf); snd_config_delete(sconf); - return -EINVAL; - } - err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf); - snd_config_delete(sconf); - if (err < 0) - return err; - snd_ctl_elem_id_alloca(&ctl_id); - if ((err = snd_pcm_parse_control_id(control, ctl_id, &card, &cchannels, NULL)) < 0) { - snd_pcm_close(spcm); - return err; + } else { + snd_ctl_elem_id_alloca(&ctl_id); + err = snd_pcm_slave_conf(root, slave, &sconf, 1, + SND_PCM_HW_PARAM_FORMAT, 0, &sformat); + if (err < 0) + return err; + if (sformat != SND_PCM_FORMAT_UNKNOWN && + sformat != SND_PCM_FORMAT_S16_LE && + sformat != SND_PCM_FORMAT_S16_BE && + sformat != SND_PCM_FORMAT_S24_3LE && + sformat != SND_PCM_FORMAT_S32_LE && + sformat != SND_PCM_FORMAT_S32_BE) { + SNDERR("only S16_LE, S16_BE, S24_3LE, S32_LE or S32_BE format " + "is supported"); + snd_config_delete(sconf); + return -EINVAL; + } + err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode, conf); + snd_config_delete(sconf); + if (err < 0) + return err; + if ((err = snd_pcm_parse_control_id(control, ctl_id, &card, &cchannels, NULL)) < 0) { + snd_pcm_close(spcm); + return err; + } + err = snd_pcm_softvol_open(pcmp, name, sformat, card, ctl_id, cchannels, + min_dB, max_dB, resolution, spcm, 1); + if (err < 0) + snd_pcm_close(spcm); } - err = snd_pcm_softvol_open(pcmp, name, sformat, card, ctl_id, cchannels, - min_dB, max_dB, resolution, spcm, 1); - if (err < 0) - snd_pcm_close(spcm); return err; } #ifndef DOC_HIDDEN