mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
Added possibility to disable also channel and format conversions + softvol.
Unified disable option using mode bits in snd_pcm_open().
This commit is contained in:
parent
6814d23d29
commit
ab8331c882
3 changed files with 55 additions and 38 deletions
|
|
@ -292,9 +292,17 @@ typedef unsigned long snd_pcm_uframes_t;
|
||||||
typedef long snd_pcm_sframes_t;
|
typedef long snd_pcm_sframes_t;
|
||||||
|
|
||||||
/** Non blocking mode (flag for open mode) \hideinitializer */
|
/** 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 */
|
/** 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 */
|
/** PCM handle */
|
||||||
typedef struct _snd_pcm snd_pcm_t;
|
typedef struct _snd_pcm snd_pcm_t;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
snd_interval_t t, buffer_size;
|
||||||
const snd_interval_t *srate, *crate;
|
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;
|
links |= SND_PCM_HW_PARBIT_RATE;
|
||||||
else {
|
else {
|
||||||
err = snd_pcm_hw_param_refine_multiple(slave, sparams, SND_PCM_HW_PARAM_RATE, params);
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plug->schannels == -2)
|
if (plug->schannels == -2 || (pcm->mode & SND_PCM_NO_AUTO_CHANNELS))
|
||||||
links |= SND_PCM_HW_PARBIT_CHANNELS;
|
links |= SND_PCM_HW_PARBIT_CHANNELS;
|
||||||
else {
|
else {
|
||||||
err = snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS, params);
|
err = snd_pcm_hw_param_refine_near(slave, sparams, SND_PCM_HW_PARAM_CHANNELS, params);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (plug->sformat == -2)
|
if (plug->sformat == -2 || (pcm->mode & SND_PCM_NO_AUTO_FORMAT))
|
||||||
links |= SND_PCM_HW_PARBIT_FORMAT;
|
links |= SND_PCM_HW_PARBIT_FORMAT;
|
||||||
else {
|
else {
|
||||||
format_mask = snd_pcm_hw_param_get_mask(params, SND_PCM_HW_PARAM_FORMAT);
|
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);
|
err = _snd_pcm_hw_params_refine(sparams, links, params);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
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;
|
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 *sbuffer_size;
|
||||||
const snd_interval_t *srate, *crate;
|
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;
|
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;
|
links |= SND_PCM_HW_PARBIT_FORMAT;
|
||||||
else {
|
else {
|
||||||
format_mask = snd_pcm_hw_param_get_mask(params,
|
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;
|
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;
|
links |= SND_PCM_HW_PARBIT_RATE;
|
||||||
else {
|
else {
|
||||||
unsigned int rate_min, srate_min;
|
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);
|
err = _snd_pcm_hw_params_refine(params, links, sparams);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
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 */
|
/* FIXME */
|
||||||
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
|
params->info &= ~(SND_PCM_INFO_MMAP | SND_PCM_INFO_MMAP_VALID);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -969,6 +969,15 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
|
||||||
SNDERR("Invalid resolution value %d", resolution);
|
SNDERR("Invalid resolution value %d", resolution);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
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);
|
||||||
|
} else {
|
||||||
|
snd_ctl_elem_id_alloca(&ctl_id);
|
||||||
err = snd_pcm_slave_conf(root, slave, &sconf, 1,
|
err = snd_pcm_slave_conf(root, slave, &sconf, 1,
|
||||||
SND_PCM_HW_PARAM_FORMAT, 0, &sformat);
|
SND_PCM_HW_PARAM_FORMAT, 0, &sformat);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
@ -988,7 +997,6 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
|
||||||
snd_config_delete(sconf);
|
snd_config_delete(sconf);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_ctl_elem_id_alloca(&ctl_id);
|
|
||||||
if ((err = snd_pcm_parse_control_id(control, ctl_id, &card, &cchannels, NULL)) < 0) {
|
if ((err = snd_pcm_parse_control_id(control, ctl_id, &card, &cchannels, NULL)) < 0) {
|
||||||
snd_pcm_close(spcm);
|
snd_pcm_close(spcm);
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -997,6 +1005,7 @@ int _snd_pcm_softvol_open(snd_pcm_t **pcmp, const char *name,
|
||||||
min_dB, max_dB, resolution, spcm, 1);
|
min_dB, max_dB, resolution, spcm, 1);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
snd_pcm_close(spcm);
|
snd_pcm_close(spcm);
|
||||||
|
}
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
#ifndef DOC_HIDDEN
|
#ifndef DOC_HIDDEN
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue