1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file.
4 */
5
6 #include <stddef.h>
7 #include <stdlib.h>
8 #include <sys/param.h>
9
10 #include "cras_util.h"
11 #include "cras_volume_curve.h"
12
13 /* Simple curve with configurable max volume and volume step. */
14 struct stepped_curve {
15 struct cras_volume_curve curve;
16 long max_vol;
17 long step;
18 };
19
get_dBFS_step(const struct cras_volume_curve * curve,size_t volume)20 static long get_dBFS_step(const struct cras_volume_curve *curve, size_t volume)
21 {
22 const struct stepped_curve *c = (const struct stepped_curve *)curve;
23 return c->max_vol - (c->step * (MAX_VOLUME - volume));
24 }
25
26 /* Curve that has each step explicitly called out by value. */
27 struct explicit_curve {
28 struct cras_volume_curve curve;
29 long dB_values[NUM_VOLUME_STEPS];
30 };
31
get_dBFS_explicit(const struct cras_volume_curve * curve,size_t volume)32 static long get_dBFS_explicit(const struct cras_volume_curve *curve,
33 size_t volume)
34 {
35 const struct explicit_curve *c = (const struct explicit_curve *)curve;
36
37 /* Limit volume to (0, MAX_VOLUME). */
38 volume = MIN(MAX_VOLUME, MAX(0, volume));
39 return c->dB_values[volume];
40 }
41
42 /*
43 * Exported Interface.
44 */
45
cras_volume_curve_create_default()46 struct cras_volume_curve *cras_volume_curve_create_default()
47 {
48 /* Default to max volume of 0dBFS, and a step of 0.5dBFS. */
49 return cras_volume_curve_create_simple_step(0, 50);
50 }
51
cras_volume_curve_create_simple_step(long max_volume,long volume_step)52 struct cras_volume_curve *cras_volume_curve_create_simple_step(
53 long max_volume,
54 long volume_step)
55 {
56 struct stepped_curve *curve;
57 curve = (struct stepped_curve *)calloc(1, sizeof(*curve));
58 if (curve == NULL)
59 return NULL;
60 curve->curve.get_dBFS = get_dBFS_step;
61 curve->max_vol = max_volume;
62 curve->step = volume_step;
63 return &curve->curve;
64 }
65
cras_volume_curve_create_explicit(long dB_values[NUM_VOLUME_STEPS])66 struct cras_volume_curve *cras_volume_curve_create_explicit(
67 long dB_values[NUM_VOLUME_STEPS])
68 {
69 struct explicit_curve *curve;
70 curve = (struct explicit_curve *)calloc(1, sizeof(*curve));
71 if (curve == NULL)
72 return NULL;
73 curve->curve.get_dBFS = get_dBFS_explicit;
74 memcpy(curve->dB_values, dB_values, sizeof(curve->dB_values));
75 return &curve->curve;
76 }
77
cras_volume_curve_destroy(struct cras_volume_curve * curve)78 void cras_volume_curve_destroy(struct cras_volume_curve *curve)
79 {
80 free(curve);
81 }
82