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(long max_volume,
53 long volume_step)
54 {
55 struct stepped_curve *curve;
56 curve = (struct stepped_curve *)calloc(1, sizeof(*curve));
57 if (curve == NULL)
58 return NULL;
59 curve->curve.get_dBFS = get_dBFS_step;
60 curve->max_vol = max_volume;
61 curve->step = volume_step;
62 return &curve->curve;
63 }
64
65 struct cras_volume_curve *
cras_volume_curve_create_explicit(long dB_values[NUM_VOLUME_STEPS])66 cras_volume_curve_create_explicit(long dB_values[NUM_VOLUME_STEPS])
67 {
68 struct explicit_curve *curve;
69 curve = (struct explicit_curve *)calloc(1, sizeof(*curve));
70 if (curve == NULL)
71 return NULL;
72 curve->curve.get_dBFS = get_dBFS_explicit;
73 memcpy(curve->dB_values, dB_values, sizeof(curve->dB_values));
74 return &curve->curve;
75 }
76
cras_volume_curve_destroy(struct cras_volume_curve * curve)77 void cras_volume_curve_destroy(struct cras_volume_curve *curve)
78 {
79 free(curve);
80 }
81