@@ -31,6 +31,8 @@
#ifndef __ALSA_PCM_EXTPLUG_H
#define __ALSA_PCM_EXTPLUG_H
+#include <stdbool.h>
+
/**
* \defgroup PCM_ExtPlug External Filter plugin SDK
* \ingroup Plugin_SDK
@@ -180,17 +182,25 @@ int snd_pcm_extplug_delete(snd_pcm_extplug_t *ext);
void snd_pcm_extplug_params_reset(snd_pcm_extplug_t *ext);
/* hw_parameter setting */
-int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list);
-int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max);
+int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type,
+ unsigned int num_list,
+ const unsigned int *list,
+ const bool conversion_supported);
+int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type,
+ unsigned int min, unsigned int max,
+ const bool conversion_supported);
int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list);
int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max);
/**
* set the parameter constraint with a single value
*/
-static __inline__ int snd_pcm_extplug_set_param(snd_pcm_extplug_t *extplug, int type, unsigned int val)
+static __inline__ int snd_pcm_extplug_set_param(snd_pcm_extplug_t *extplug,
+ int type, unsigned int val,
+ const bool conversion_supported)
{
- return snd_pcm_extplug_set_param_list(extplug, type, 1, &val);
+ return snd_pcm_extplug_set_param_list(extplug, type, 1, &val,
+ conversion_supported);
}
/**
@@ -41,6 +41,7 @@ const char *_snd_module_pcm_extplug = "";
typedef struct snd_pcm_extplug_priv {
snd_pcm_plugin_t plug;
snd_pcm_extplug_t *data;
+ bool conversion_supported[SND_PCM_EXTPLUG_HW_PARAMS];
struct snd_ext_parm params[SND_PCM_EXTPLUG_HW_PARAMS];
struct snd_ext_parm sparams[SND_PCM_EXTPLUG_HW_PARAMS];
} extplug_priv_t;
@@ -232,7 +233,7 @@ static int snd_pcm_extplug_hw_refine_sprepare(snd_pcm_t *pcm,
return 0;
}
-static unsigned int get_links(struct snd_ext_parm *params)
+static unsigned int get_links(extplug_priv_t *ext, struct snd_ext_parm *params)
{
int i;
unsigned int links = (SND_PCM_HW_PARBIT_FORMAT |
@@ -249,7 +250,10 @@ static unsigned int get_links(struct snd_ext_parm *params)
SND_PCM_HW_PARBIT_TICK_TIME);
for (i = 0; i < SND_PCM_EXTPLUG_HW_PARAMS; i++) {
- if (params[i].active)
+ /* only disable the link if the param is set and conversion is
+ * supported by the extplug
+ */
+ if (params[i].active && ext->conversion_supported[i])
links &= ~excl_parbits[i];
}
return links;
@@ -260,7 +264,7 @@ static int snd_pcm_extplug_hw_refine_schange(snd_pcm_t *pcm,
snd_pcm_hw_params_t *sparams)
{
extplug_priv_t *ext = pcm->private_data;
- unsigned int links = get_links(ext->sparams);
+ unsigned int links = get_links(ext, ext->sparams);
return _snd_pcm_hw_params_refine(sparams, links, params);
}
@@ -270,7 +274,7 @@ static int snd_pcm_extplug_hw_refine_cchange(snd_pcm_t *pcm,
snd_pcm_hw_params_t *sparams)
{
extplug_priv_t *ext = pcm->private_data;
- unsigned int links = get_links(ext->params);
+ unsigned int links = get_links(ext, ext->params);
return _snd_pcm_hw_params_refine(params, links, sparams);
}
@@ -698,6 +702,9 @@ int snd_pcm_extplug_create(snd_pcm_extplug_t *extplug, const char *name,
ext->data = extplug;
extplug->stream = stream;
+ /* keep the old behaviour as default */
+ for (int i = 0; i < SND_PCM_EXTPLUG_HW_PARAMS; i++)
+ ext->conversion_supported[i] = true;
snd_pcm_plugin_init(&ext->plug);
ext->plug.read = snd_pcm_extplug_read_areas;
@@ -772,6 +779,11 @@ int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, u
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
+ if (!ext->conversion_supported[type]) {
+ SNDERR("EXTPLUG: do not call %s(%d) if conversion is not supported",
+ __func__, type);
+ return -EINVAL;
+ }
return snd_ext_parm_set_list(&ext->sparams[type], num_list, list);
}
@@ -798,6 +810,11 @@ int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type,
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
+ if (!ext->conversion_supported[type]) {
+ SNDERR("EXTPLUG: do not call %s(%d) if conversion is not supported",
+ __func__, type);
+ return -EINVAL;
+ }
return snd_ext_parm_set_minmax(&ext->sparams[type], min, max);
}
@@ -807,19 +824,30 @@ int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type,
* \param type parameter type
* \param num_list number of available values
* \param list the list of available values
+ * \param conversion_supported set true if the extplug is capabile to convert
+ * to any slave format/channels (defined by type)
* \return 0 if successful, or a negative error code
*
* Sets the master parameter as the list.
* The available values of the given parameter type of this PCM (as input) is restricted
* to the ones of the given list.
*/
-int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list)
+int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type,
+ unsigned int num_list,
+ const unsigned int *list,
+ const bool conversion_supported)
{
extplug_priv_t *ext = extplug->pcm->private_data;
if (type < 0 || type >= SND_PCM_EXTPLUG_HW_PARAMS) {
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
+ if (!conversion_supported && ext->sparams[type].active) {
+ SNDERR("EXTPLUG: do not call snd_pcm_extplug_set_slave_param*(%d) if conversion is not supported",
+ type);
+ return -EINVAL;
+ }
+ ext->conversion_supported[type] = conversion_supported;
return snd_ext_parm_set_list(&ext->params[type], num_list, list);
}
@@ -829,13 +857,17 @@ int snd_pcm_extplug_set_param_list(snd_pcm_extplug_t *extplug, int type, unsigne
* \param type parameter type
* \param min the minimum value
* \param max the maximum value
+ * \param conversion_supported set true if the extplug is capabile to convert
+ * to any slave format/channels (defined by type)
* \return 0 if successful, or a negative error code
*
* Sets the master parameter as the min/max values.
* The available values of the given parameter type of this PCM (as input) is restricted
* between the given minimum and maximum values.
*/
-int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max)
+int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type,
+ unsigned int min, unsigned int max,
+ const bool conversion_supported)
{
extplug_priv_t *ext = extplug->pcm->private_data;
if (type < 0 || type >= SND_PCM_EXTPLUG_HW_PARAMS) {
@@ -846,6 +878,12 @@ int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsig
SNDERR("EXTPLUG: invalid parameter type %d", type);
return -EINVAL;
}
+ if (!conversion_supported && ext->sparams[type].active) {
+ SNDERR("EXTPLUG: do not call snd_pcm_extplug_set_slave_param*(%d) if conversion is not supported",
+ type);
+ return -EINVAL;
+ }
+ ext->conversion_supported[type] = conversion_supported;
return snd_ext_parm_set_minmax(&ext->params[type], min, max);
}