Update channel edit/remove menu order when channels are re-ordered
[jack_mixer.git] / scale.c
blobf5dcb570452163f9988fe96bca853138019c63bc
1 /* -*- Mode: C ; c-basic-offset: 2 -*- */
2 /*****************************************************************************
4 * This file is part of jack_mixer
5 *
6 * Copyright (C) 2006 Nedko Arnaudov <nedko@arnaudov.name>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21 *****************************************************************************/
23 #include <stddef.h>
24 #include <stdbool.h>
25 #include <stdlib.h>
26 #include <math.h>
27 #include <assert.h>
29 #include "jack_mixer.h"
30 //#define LOG_LEVEL LOG_LEVEL_DEBUG
31 #include "log.h"
32 #include "list.h"
34 struct threshold
36 struct list_head scale_siblings;
37 double db;
38 double scale;
39 double a;
40 double b;
43 struct scale
45 struct list_head thresholds;
46 double max_db;
49 jack_mixer_scale_t
50 scale_create()
52 struct scale * scale_ptr;
54 scale_ptr = malloc(sizeof(struct scale));
55 if (scale_ptr == NULL)
57 return NULL;
60 INIT_LIST_HEAD(&scale_ptr->thresholds);
61 scale_ptr->max_db = -INFINITY;
63 LOG_DEBUG("Scale %p created", scale_ptr);
65 return (jack_mixer_scale_t)scale_ptr;
68 #define scale_ptr ((struct scale *)scale)
70 void
71 scale_destroy(
72 jack_mixer_scale_t scale)
74 scale_remove_thresholds(scale);
75 free(scale_ptr);
78 void
79 scale_remove_thresholds(
80 jack_mixer_scale_t scale)
83 struct threshold * threshold_ptr;
84 struct threshold * node_ptr;
86 list_for_each_entry_safe(threshold_ptr, node_ptr, &scale_ptr->thresholds, scale_siblings)
88 list_del(&(threshold_ptr->scale_siblings));
89 free(threshold_ptr);
90 threshold_ptr = NULL;
94 bool
95 scale_add_threshold(
96 jack_mixer_scale_t scale,
97 float db,
98 float scale_value)
100 struct threshold * threshold_ptr;
102 LOG_DEBUG("Adding threshold (%f dBFS -> %f) to scale %p", db, scale, scale_ptr);
104 threshold_ptr = malloc(sizeof(struct threshold));
105 LOG_DEBUG("Threshold %p created ", threshold_ptr, db, scale);
107 if (threshold_ptr == NULL)
109 return false;
112 threshold_ptr->db = db;
113 threshold_ptr->scale = scale_value;
115 list_add_tail(&threshold_ptr->scale_siblings, &scale_ptr->thresholds);
117 if (db > scale_ptr->max_db)
119 scale_ptr->max_db = db;
122 return true;
125 #undef threshold_ptr
127 void
128 scale_calculate_coefficients(
129 jack_mixer_scale_t scale)
131 struct threshold * threshold_ptr;
132 struct threshold * prev_ptr;
133 struct list_head * node_ptr;
135 prev_ptr = NULL;
137 list_for_each(node_ptr, &scale_ptr->thresholds)
139 threshold_ptr = list_entry(node_ptr, struct threshold, scale_siblings);
141 LOG_DEBUG("Calculating coefficients for threshold %p", threshold_ptr);
143 if (prev_ptr != NULL)
145 threshold_ptr->a = (prev_ptr->scale - threshold_ptr->scale) / (prev_ptr->db - threshold_ptr->db);
146 threshold_ptr->b = threshold_ptr->scale - threshold_ptr->a * threshold_ptr->db;
147 LOG_DEBUG("%.0f dB - %.0f dB: scale = %f * dB + %f", prev_ptr->db, threshold_ptr->db, threshold_ptr->a, threshold_ptr->b);
150 prev_ptr = threshold_ptr;
154 /* Convert dBFS value to number in range 0.0-1.0 */
155 double
156 scale_db_to_scale(
157 jack_mixer_scale_t scale,
158 double db)
160 struct threshold * threshold_ptr;
161 struct threshold * prev_ptr;
162 struct list_head * node_ptr;
164 prev_ptr = NULL;
166 list_for_each(node_ptr, &scale_ptr->thresholds)
168 threshold_ptr = list_entry(node_ptr, struct threshold, scale_siblings);
170 if (db < threshold_ptr->db)
172 LOG_DEBUG("Match at %f dB treshold", threshold_ptr->db);
173 if (prev_ptr == NULL)
175 return 0.0;
178 return threshold_ptr->a * db + threshold_ptr->b;
181 prev_ptr = threshold_ptr;
184 return 1.0;
187 /* Convert number in range 0.0-1.0 to dBFS value */
188 double
189 scale_scale_to_db(
190 jack_mixer_scale_t scale,
191 double scale_value)
193 struct threshold * threshold_ptr;
194 struct threshold * prev_ptr;
195 struct list_head * node_ptr;
197 prev_ptr = NULL;
199 list_for_each(node_ptr, &scale_ptr->thresholds)
201 threshold_ptr = list_entry(node_ptr, struct threshold, scale_siblings);
203 if (scale_value <= threshold_ptr->scale)
205 if (prev_ptr == NULL)
207 return -INFINITY;
210 return (scale_value - threshold_ptr->b) / threshold_ptr->a;
213 prev_ptr = threshold_ptr;
216 return scale_ptr->max_db;