channelmix: add channelmap in properties

This commit is contained in:
Wim Taymans 2020-11-23 15:33:11 +01:00
parent abaf63dfe6
commit 231c3c8b8e

View file

@ -63,6 +63,8 @@ struct props {
bool mute; bool mute;
uint32_t n_channel_volumes; uint32_t n_channel_volumes;
float channel_volumes[SPA_AUDIO_MAX_CHANNELS]; float channel_volumes[SPA_AUDIO_MAX_CHANNELS];
uint32_t n_channels;
uint32_t channel_map[SPA_AUDIO_MAX_CHANNELS];
}; };
static void props_reset(struct props *props) static void props_reset(struct props *props)
@ -73,6 +75,9 @@ static void props_reset(struct props *props)
props->n_channel_volumes = 0; props->n_channel_volumes = 0;
for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++) for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
props->channel_volumes[i] = 1.0; props->channel_volumes[i] = 1.0;
props->n_channels = 0;
for (i = 0; i < SPA_AUDIO_MAX_CHANNELS; i++)
props->channel_map[i] = SPA_AUDIO_CHANNEL_UNKNOWN;
} }
struct buffer { struct buffer {
@ -200,10 +205,10 @@ static uint64_t default_mask(uint32_t channels)
return mask; return mask;
} }
static int remap_volumes(struct props *p, uint32_t target) static int remap_volumes(struct props *p, const struct spa_audio_info *info)
{ {
float s; float s;
uint32_t i; uint32_t i, target = info->info.raw.channels;
if (target == 0 || p->n_channel_volumes == target) if (target == 0 || p->n_channel_volumes == target)
return 0; return 0;
@ -219,6 +224,9 @@ static int remap_volumes(struct props *p, uint32_t target)
p->n_channel_volumes = target; p->n_channel_volumes = target;
for (i = 0; i < p->n_channel_volumes; i++) for (i = 0; i < p->n_channel_volumes; i++)
p->channel_volumes[i] = s; p->channel_volumes[i] = s;
p->n_channels = target;
for (i = 0; i < p->n_channels; i++)
p->channel_map[i] = info->info.raw.position[i];
return 1; return 1;
} }
@ -274,7 +282,7 @@ static int setup_convert(struct impl *this,
if ((res = channelmix_init(&this->mix)) < 0) if ((res = channelmix_init(&this->mix)) < 0)
return res; return res;
remap_volumes(&this->props, this->mix.src_chan); remap_volumes(&this->props, src_info);
channelmix_set_volume(&this->mix, this->props.volume, this->props.mute, channelmix_set_volume(&this->mix, this->props.volume, this->props.mute,
this->props.n_channel_volumes, this->props.channel_volumes); this->props.n_channel_volumes, this->props.channel_volumes);
@ -338,6 +346,13 @@ static int impl_node_enum_params(void *object, int seq,
SPA_PROP_INFO_name, SPA_POD_String("Channel Volumes"), SPA_PROP_INFO_name, SPA_POD_String("Channel Volumes"),
SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(p->volume, 0.0, 10.0)); SPA_PROP_INFO_type, SPA_POD_CHOICE_RANGE_Float(p->volume, 0.0, 10.0));
break; break;
case 3:
param = spa_pod_builder_add_object(&b,
SPA_TYPE_OBJECT_PropInfo, id,
SPA_PROP_INFO_id, SPA_POD_Id(SPA_PROP_channelMap),
SPA_PROP_INFO_name, SPA_POD_String("Channel Map"),
SPA_PROP_INFO_type, SPA_POD_Id(SPA_AUDIO_CHANNEL_UNKNOWN));
break;
default: default:
return 0; return 0;
} }
@ -356,7 +371,11 @@ static int impl_node_enum_params(void *object, int seq,
SPA_PROP_channelVolumes, SPA_POD_Array(sizeof(float), SPA_PROP_channelVolumes, SPA_POD_Array(sizeof(float),
SPA_TYPE_Float, SPA_TYPE_Float,
p->n_channel_volumes, p->n_channel_volumes,
p->channel_volumes)); p->channel_volumes),
SPA_PROP_channelMap, SPA_POD_Array(sizeof(uint32_t),
SPA_TYPE_Id,
p->n_channels,
p->channel_map));
break; break;
default: default:
return 0; return 0;
@ -399,13 +418,18 @@ static int apply_props(struct impl *this, const struct spa_pod *param)
if ((p->n_channel_volumes = spa_pod_copy_array(&prop->value, SPA_TYPE_Float, if ((p->n_channel_volumes = spa_pod_copy_array(&prop->value, SPA_TYPE_Float,
p->channel_volumes, SPA_AUDIO_MAX_CHANNELS)) > 0) p->channel_volumes, SPA_AUDIO_MAX_CHANNELS)) > 0)
changed++; changed++;
remap_volumes(p, this->mix.src_chan); break;
case SPA_PROP_channelMap:
if ((p->n_channels = spa_pod_copy_array(&prop->value, SPA_TYPE_Id,
p->channel_map, SPA_AUDIO_MAX_CHANNELS)) > 0)
changed++;
break; break;
default: default:
break; break;
} }
} }
if (changed && this->mix.set_volume) { if (changed && this->mix.set_volume) {
remap_volumes(&this->props, &GET_IN_PORT(this, 0)->format);
channelmix_set_volume(&this->mix, p->volume, p->mute, channelmix_set_volume(&this->mix, p->volume, p->mute,
p->n_channel_volumes, p->channel_volumes); p->n_channel_volumes, p->channel_volumes);
} }