Commit 1ceb902b authored by Wim Taymans's avatar Wim Taymans

pulse-server: convert between client cubic volume and linear

parent 2e3556fa
Pipeline #217396 passed with stages
in 1 minute and 17 seconds
......@@ -283,7 +283,7 @@ static void channel_map_to_positions(const struct channel_map *map, uint32_t *po
pos[i] = channel_pa2id(map->map[i]);
}
struct cvolume {
struct volume {
uint8_t channels;
float values[CHANNELS_MAX];
};
......
......@@ -22,6 +22,27 @@
* DEALINGS IN THE SOFTWARE.
*/
#define VOLUME_MUTED ((uint32_t) 0U)
#define VOLUME_NORM ((uint32_t) 0x10000U)
#define VOLUME_MAX ((uint32_t) UINT32_MAX/2)
static inline uint32_t volume_from_linear(float vol)
{
uint32_t v;
if (vol <= 0.0f)
v = VOLUME_MUTED;
else
v = SPA_CLAMP((uint64_t) lround(cbrt(vol) * VOLUME_NORM),
VOLUME_MUTED, VOLUME_MAX);
return v;
}
static inline float volume_to_linear(uint32_t vol)
{
float v = ((float)vol) / VOLUME_NORM;
return v * v * v;
}
struct descriptor {
uint32_t length;
uint32_t channel;
......@@ -203,11 +224,11 @@ static int read_volume(struct message *m, float *vol)
uint32_t v;
if ((res = read_u32(m, &v)) < 0)
return res;
*vol = ((float)v) / 0x10000U;
*vol = volume_to_linear(v);
return 0;
}
static int read_cvolume(struct message *m, struct cvolume *vol)
static int read_cvolume(struct message *m, struct volume *vol)
{
int res;
uint8_t i;
......@@ -336,7 +357,7 @@ static int message_get(struct message *m, ...)
case TAG_CVOLUME:
if (dtag != tag)
return -EINVAL;
if ((res = read_cvolume(m, va_arg(va, struct cvolume*))) < 0)
if ((res = read_cvolume(m, va_arg(va, struct volume*))) < 0)
return res;
break;
case TAG_PROPLIST:
......@@ -462,16 +483,16 @@ static void write_channel_map(struct message *m, struct channel_map *map)
static void write_volume(struct message *m, float vol)
{
write_8(m, TAG_VOLUME);
write_32(m, vol * 0x10000U);
write_32(m, volume_from_linear(vol));
}
static void write_cvolume(struct message *m, struct cvolume *cvol)
static void write_cvolume(struct message *m, struct volume *vol)
{
uint8_t i;
write_8(m, TAG_CVOLUME);
write_8(m, cvol->channels);
for (i = 0; i < cvol->channels; i ++)
write_32(m, cvol->values[i] * 0x10000U);
write_8(m, vol->channels);
for (i = 0; i < vol->channels; i ++)
write_32(m, volume_from_linear(vol->values[i]));
}
static void write_props(struct message *m, struct pw_properties *props)
......@@ -545,7 +566,7 @@ static int message_put(struct message *m, ...)
write_channel_map(m, va_arg(va, struct channel_map*));
break;
case TAG_CVOLUME:
write_cvolume(m, va_arg(va, struct cvolume*));
write_cvolume(m, va_arg(va, struct volume*));
break;
case TAG_PROPLIST:
write_props(m, va_arg(va, struct pw_properties*));
......
......@@ -97,7 +97,7 @@ struct device {
enum pw_direction direction;
struct pw_properties *props;
struct sample_spec ss;
struct cvolume volume;
struct volume volume;
struct channel_map map;
bool muted;
struct device *monitor;
......@@ -139,7 +139,7 @@ struct stream {
struct buffer_attr attr;
uint32_t frame_size;
struct cvolume volume;
struct volume volume;
bool muted;
struct device *dev;
......@@ -1178,7 +1178,7 @@ static int do_create_playback_stream(struct client *client, uint32_t command, ui
fail_on_suspend = false,
relative_volume = false,
passthrough = false;
struct cvolume volume;
struct volume volume;
struct pw_properties *props = NULL;
uint8_t n_formats = 0;
struct stream *stream = NULL;
......@@ -1413,7 +1413,7 @@ static int do_create_record_stream(struct client *client, uint32_t command, uint
relative_volume = false,
passthrough = false;
uint32_t direct_on_input_idx;
struct cvolume volume;
struct volume volume;
struct pw_properties *props = NULL;
uint8_t n_formats = 0;
struct stream *stream = NULL;
......@@ -1795,7 +1795,7 @@ static int do_set_stream_volume(struct client *client, uint32_t command, uint32_
uint32_t channel;
struct stream *stream;
int res;
struct cvolume volume;
struct volume volume;
if ((res = message_get(m,
TAG_U32, &channel,
......@@ -3146,7 +3146,7 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
.format = SAMPLE_FLOAT32LE,
.rate = 44100,
.channels = 2, },
.volume = (struct cvolume) {
.volume = (struct volume) {
.channels = 2,
.values[0] = 1.0f,
.values[1] = 1.0f, },
......@@ -3169,7 +3169,7 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
.format = SAMPLE_FLOAT32LE,
.rate = 44100,
.channels = 2, },
.volume = (struct cvolume) {
.volume = (struct volume) {
.channels = 2,
.values[0] = 1.0f,
.values[1] = 1.0f, },
......@@ -3191,7 +3191,7 @@ struct pw_protocol_pulse *pw_protocol_pulse_new(struct pw_context *context,
.format = SAMPLE_FLOAT32LE,
.rate = 44100,
.channels = 2, },
.volume = (struct cvolume) {
.volume = (struct volume) {
.channels = 2,
.values[0] = 1.0f,
.values[1] = 1.0f, },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment