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 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 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 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 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 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 78 void cras_volume_curve_destroy(struct cras_volume_curve *curve) 79 { 80 free(curve); 81 } 82