mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Added snd_pcm_hw_params_set_rate_resample function
- snd_pcm_hw_params_set_rate_resample() - snd_pcm_hw_params_get_rate_resample()
This commit is contained in:
parent
72ad0e9ae7
commit
f65d9f3108
9 changed files with 72 additions and 4 deletions
|
|
@ -585,6 +585,8 @@ int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *param
|
|||
int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
|
||||
int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
|
||||
int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
|
||||
int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
|
||||
int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
|
||||
|
||||
int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
|
||||
int snd_pcm_hw_params_get_period_time_min(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir);
|
||||
|
|
@ -735,6 +737,8 @@ int snd_pcm_hw_params_set_rate_minmax(snd_pcm_t *pcm, snd_pcm_hw_params_t *param
|
|||
unsigned int snd_pcm_hw_params_set_rate_near(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val, int *dir);
|
||||
unsigned int snd_pcm_hw_params_set_rate_first(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
|
||||
unsigned int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, int *dir);
|
||||
int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val);
|
||||
int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val);
|
||||
|
||||
asm(".symver snd_pcm_hw_params_get_period_time,snd_pcm_hw_params_get_period_time@ALSA_0.9");
|
||||
asm(".symver snd_pcm_hw_params_get_period_time_min,snd_pcm_hw_params_get_period_time_min@ALSA_0.9");
|
||||
|
|
|
|||
|
|
@ -340,7 +340,7 @@ enum sndrv_pcm_hw_param {
|
|||
SNDRV_PCM_HW_PARAM_LAST_INTERVAL = SNDRV_PCM_HW_PARAM_TICK_TIME
|
||||
};
|
||||
|
||||
#define SNDRV_PCM_HW_PARAMS_RUNTIME (1<<0)
|
||||
#define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */
|
||||
|
||||
struct sndrv_interval {
|
||||
unsigned int min, max;
|
||||
|
|
|
|||
|
|
@ -174,6 +174,9 @@ ALSA_1.0.8 {
|
|||
ALSA_1.0.9 {
|
||||
global:
|
||||
|
||||
snd_pcm_hw_params_set_rate_resample;
|
||||
snd_pcm_hw_params_get_rate_resample;
|
||||
|
||||
snd_pcm_ioplug_create;
|
||||
snd_pcm_ioplug_delete;
|
||||
snd_pcm_ioplug_reinit_status;
|
||||
|
|
|
|||
|
|
@ -744,6 +744,7 @@ int snd_pcm_hw_params_current(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
if (!pcm->setup)
|
||||
return -EBADFD;
|
||||
memset(params, 0, snd_pcm_hw_params_sizeof());
|
||||
params->flags = pcm->hw_flags;
|
||||
snd_mask_copy(¶ms->masks[SND_PCM_HW_PARAM_ACCESS - SND_PCM_HW_PARAM_FIRST_MASK], (snd_mask_t *)&pcm->access);
|
||||
snd_mask_copy(¶ms->masks[SND_PCM_HW_PARAM_FORMAT - SND_PCM_HW_PARAM_FIRST_MASK], (snd_mask_t *)&pcm->format);
|
||||
snd_mask_copy(¶ms->masks[SND_PCM_HW_PARAM_SUBFORMAT - SND_PCM_HW_PARAM_FIRST_MASK], (snd_mask_t *)&pcm->subformat);
|
||||
|
|
@ -3909,6 +3910,35 @@ int snd_pcm_hw_params_set_rate_last(snd_pcm_t *pcm, snd_pcm_hw_params_t *params,
|
|||
return snd_pcm_hw_param_set_last(pcm, params, SND_PCM_HW_PARAM_RATE, val, dir);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Restrict a configuration space to contain only real hardware rates
|
||||
* \param pcm PCM handle
|
||||
* \param params Configuration space
|
||||
* \param val 0 = disable, 1 = enable (default) rate resampling
|
||||
* \return 0 otherwise a negative error code
|
||||
*/
|
||||
int snd_pcm_hw_params_set_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)
|
||||
{
|
||||
assert(pcm && params);
|
||||
if (!val)
|
||||
params->flags |= SND_PCM_HW_PARAMS_NORESAMPLE;
|
||||
else
|
||||
params->flags &= ~SND_PCM_HW_PARAMS_NORESAMPLE;
|
||||
return snd_pcm_hw_refine(pcm, params);
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Extract resample state from a configuration space
|
||||
* \param pcm PCM handle
|
||||
* \param *val 0 = disable, 1 = enable rate resampling
|
||||
* \return 0 otherwise a negative error code
|
||||
*/
|
||||
int snd_pcm_hw_params_get_rate_resample(snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val)
|
||||
{
|
||||
assert(pcm && params && val);
|
||||
*val = params->flags & SND_PCM_HW_PARAMS_NORESAMPLE ? 0 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* \brief Extract period time from a configuration space
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
|
|||
#define SND_PCM_HW_PARAM_BUFFER_BYTES SNDRV_PCM_HW_PARAM_BUFFER_BYTES
|
||||
#define SND_PCM_HW_PARAM_TICK_TIME SNDRV_PCM_HW_PARAM_TICK_TIME
|
||||
#define SND_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_LAST_INTERVAL
|
||||
#define SND_PCM_HW_PARAMS_RUNTIME SNDRV_PCM_HW_PARAMS_RUNTIME
|
||||
#define SND_PCM_HW_PARAM_LAST_MASK SNDRV_PCM_HW_PARAM_LAST_MASK
|
||||
#define SND_PCM_HW_PARAM_FIRST_MASK SNDRV_PCM_HW_PARAM_FIRST_MASK
|
||||
#define SND_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_LAST_INTERVAL
|
||||
|
|
@ -93,6 +92,12 @@ typedef enum sndrv_pcm_hw_param snd_pcm_hw_param_t;
|
|||
/** device can do a kind of synchronized start */
|
||||
#define SND_PCM_INFO_SYNC_START SNDRV_PCM_INFO_SYNC_START
|
||||
|
||||
#ifndef SNDRV_PCM_HW_PARAMS_NORESAMPLE
|
||||
#define SND_PCM_HW_PARAMS_NORESAMPLE (1<<0)
|
||||
#else
|
||||
#define SND_PCM_HW_PARAMS_NORESAMPLE SNDRV_PCM_HW_PARAMS_NORESAMPLE
|
||||
#endif
|
||||
|
||||
typedef struct _snd_pcm_rbptr {
|
||||
snd_pcm_t *master;
|
||||
volatile snd_pcm_uframes_t *ptr;
|
||||
|
|
@ -199,6 +204,7 @@ struct _snd_pcm {
|
|||
unsigned int msbits; /* used most significant bits */
|
||||
unsigned int rate_num; /* rate numerator */
|
||||
unsigned int rate_den; /* rate denominator */
|
||||
unsigned int hw_flags; /* actual hardware flags */
|
||||
snd_pcm_uframes_t fifo_size; /* chip FIFO size in frames */
|
||||
snd_pcm_uframes_t buffer_size;
|
||||
snd_interval_t buffer_time;
|
||||
|
|
|
|||
|
|
@ -2281,6 +2281,7 @@ int _snd_pcm_hw_params(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
|
|||
}
|
||||
pcm->min_align = min_align;
|
||||
|
||||
pcm->hw_flags = params->flags;
|
||||
pcm->info = params->info;
|
||||
pcm->msbits = params->msbits;
|
||||
pcm->rate_num = params->rate_num;
|
||||
|
|
|
|||
|
|
@ -728,6 +728,8 @@ 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;
|
||||
}
|
||||
|
||||
|
|
@ -830,6 +832,8 @@ 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;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ int block = 0; /* block mode */
|
|||
int tick_time = 0; /* disabled, otherwise in us */
|
||||
int tick_time_ok = 0;
|
||||
int use_poll = 0;
|
||||
int resample = 1;
|
||||
unsigned long loop_limit;
|
||||
|
||||
snd_output_t *output = NULL;
|
||||
|
|
@ -67,6 +68,11 @@ int setparams_stream(snd_pcm_t *handle,
|
|||
printf("Broken configuration for %s PCM: no configurations available: %s\n", snd_strerror(err), id);
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
|
||||
if (err < 0) {
|
||||
printf("Resample setup failed for %s (val %i): %s\n", id, resample, snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
err = snd_pcm_hw_params_set_access(handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||
if (err < 0) {
|
||||
printf("Access type not available for %s: %s\n", id, snd_strerror(err));
|
||||
|
|
@ -518,7 +524,7 @@ int main(int argc, char *argv[])
|
|||
morehelp = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
if ((c = getopt_long(argc, argv, "hP:C:m:M:F:f:c:r:s:bt:pe", long_option, NULL)) < 0)
|
||||
if ((c = getopt_long(argc, argv, "hP:C:m:M:F:f:c:r:s:bt:pen", long_option, NULL)) < 0)
|
||||
break;
|
||||
switch (c) {
|
||||
case 'h':
|
||||
|
|
@ -580,6 +586,9 @@ int main(int argc, char *argv[])
|
|||
case 'e':
|
||||
effect = 1;
|
||||
break;
|
||||
case 'n':
|
||||
resample = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
13
test/pcm.c
13
test/pcm.c
|
|
@ -20,6 +20,7 @@ unsigned int buffer_time = 500000; /* ring buffer length in us */
|
|||
unsigned int period_time = 100000; /* period time in us */
|
||||
double freq = 440; /* sinusoidal wave frequency in Hz */
|
||||
int verbose = 0; /* verbose flag */
|
||||
int resample = 1; /* enable alsa-lib resampling */
|
||||
|
||||
snd_pcm_sframes_t buffer_size;
|
||||
snd_pcm_sframes_t period_size;
|
||||
|
|
@ -80,6 +81,12 @@ static int set_hwparams(snd_pcm_t *handle,
|
|||
printf("Broken configuration for playback: no configurations available: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
/* set hardware resampling */
|
||||
err = snd_pcm_hw_params_set_rate_resample(handle, params, resample);
|
||||
if (err < 0) {
|
||||
printf("Resampling setup failed for playback: %s\n", snd_strerror(err));
|
||||
return err;
|
||||
}
|
||||
/* set the interleaved read/write format */
|
||||
err = snd_pcm_hw_params_set_access(handle, params, access);
|
||||
if (err < 0) {
|
||||
|
|
@ -729,6 +736,7 @@ int main(int argc, char *argv[])
|
|||
{"period", 1, NULL, 'p'},
|
||||
{"method", 1, NULL, 'm'},
|
||||
{"verbose", 1, NULL, 'v'},
|
||||
{"noresample", 1, NULL, 'n'},
|
||||
{NULL, 0, NULL, 0},
|
||||
};
|
||||
snd_pcm_t *handle;
|
||||
|
|
@ -746,7 +754,7 @@ int main(int argc, char *argv[])
|
|||
morehelp = 0;
|
||||
while (1) {
|
||||
int c;
|
||||
if ((c = getopt_long(argc, argv, "hD:r:c:f:b:p:m:v", long_option, NULL)) < 0)
|
||||
if ((c = getopt_long(argc, argv, "hD:r:c:f:b:p:m:vn", long_option, NULL)) < 0)
|
||||
break;
|
||||
switch (c) {
|
||||
case 'h':
|
||||
|
|
@ -790,6 +798,9 @@ int main(int argc, char *argv[])
|
|||
case 'v':
|
||||
verbose = 1;
|
||||
break;
|
||||
case 'n':
|
||||
resample = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue