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;
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);
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);
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;
}
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,
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;
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;
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