| /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #include <stddef.h> |
| #include <stdlib.h> |
| #include <sys/param.h> |
| |
| #include "cras_util.h" |
| #include "cras_volume_curve.h" |
| |
| /* Simple curve with configurable max volume and volume step. */ |
| struct stepped_curve { |
| struct cras_volume_curve curve; |
| long max_vol; |
| long step; |
| }; |
| |
| static long get_dBFS_step(const struct cras_volume_curve *curve, size_t volume) |
| { |
| const struct stepped_curve *c = (const struct stepped_curve *)curve; |
| return c->max_vol - (c->step * (MAX_VOLUME - volume)); |
| } |
| |
| /* Curve that has each step explicitly called out by value. */ |
| struct explicit_curve { |
| struct cras_volume_curve curve; |
| long dB_values[NUM_VOLUME_STEPS]; |
| }; |
| |
| static long get_dBFS_explicit(const struct cras_volume_curve *curve, |
| size_t volume) |
| { |
| const struct explicit_curve *c = (const struct explicit_curve *)curve; |
| |
| /* Limit volume to (0, MAX_VOLUME). */ |
| volume = MIN(MAX_VOLUME, MAX(0, volume)); |
| return c->dB_values[volume]; |
| } |
| |
| /* |
| * Exported Interface. |
| */ |
| |
| struct cras_volume_curve *cras_volume_curve_create_default() |
| { |
| /* Default to max volume of 0dBFS, and a step of 0.5dBFS. */ |
| return cras_volume_curve_create_simple_step(0, 50); |
| } |
| |
| struct cras_volume_curve *cras_volume_curve_create_simple_step(long max_volume, |
| long volume_step) |
| { |
| struct stepped_curve *curve; |
| curve = (struct stepped_curve *)calloc(1, sizeof(*curve)); |
| if (curve == NULL) |
| return NULL; |
| curve->curve.get_dBFS = get_dBFS_step; |
| curve->max_vol = max_volume; |
| curve->step = volume_step; |
| return &curve->curve; |
| } |
| |
| struct cras_volume_curve * |
| cras_volume_curve_create_explicit(long dB_values[NUM_VOLUME_STEPS]) |
| { |
| struct explicit_curve *curve; |
| curve = (struct explicit_curve *)calloc(1, sizeof(*curve)); |
| if (curve == NULL) |
| return NULL; |
| curve->curve.get_dBFS = get_dBFS_explicit; |
| memcpy(curve->dB_values, dB_values, sizeof(curve->dB_values)); |
| return &curve->curve; |
| } |
| |
| void cras_volume_curve_destroy(struct cras_volume_curve *curve) |
| { |
| free(curve); |
| } |