Ardour  9.0-pre0-1699-gfaebc7ab35
value_as_string.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 David Robillard <d@drobilla.net>
3  * Copyright (C) 2016-2017 Robin Gareus <robin@gareus.org>
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along
16  * with this program; if not, write to the Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 #pragma once
21 
22 #include <stddef.h>
23 
24 #include "ardour/dB.h"
26 
27 #include "pbd/i18n.h"
28 
29 namespace ARDOUR {
30 
31 inline std::string
33  double v)
34 {
35  char buf[32];
36 
37  if (desc.scale_points) {
38  // Check if value is on a scale point
39  for (auto const & [label,val] : *desc.scale_points) {
40  if (val == v) {
41  return label;
42  }
43  }
44  }
45 
46  if (desc.toggled) {
47  return v > 0 ? _("on") : _("off");
48  }
49 
50  // Value is not a scale point, print it normally
52  snprintf(buf, sizeof(buf), "%s", ParameterDescriptor::midi_note_name (rint(v)).c_str());
53  } else if (desc.type == GainAutomation || desc.type == BusSendLevel || desc.type == TrimAutomation || desc.type == EnvelopeAutomation || desc.type == MainOutVolume || desc.type == SurroundSendLevel || desc.type == InsertReturnLevel) {
54 #ifdef PLATFORM_WINDOWS
55  if (v < GAIN_COEFF_SMALL) {
56  snprintf(buf, sizeof(buf), "-inf dB");
57  } else {
58  snprintf(buf, sizeof(buf), "%.2f dB", accurate_coefficient_to_dB (v));
59  }
60 #else
61  snprintf(buf, sizeof(buf), "%.2f dB", accurate_coefficient_to_dB (v));
62 #endif
63  } else if (desc.type == PanWidthAutomation) {
64  snprintf (buf, sizeof (buf), "%d%%", (int) floor (100.0 * v));
65  } else if (!desc.print_fmt.empty()) {
66  snprintf(buf, sizeof(buf), desc.print_fmt.c_str(), v);
67  } else if (desc.integer_step) {
68  snprintf(buf, sizeof(buf), "%d", (int)v);
69  } else if (desc.upper - desc.lower >= 1000) {
70  snprintf(buf, sizeof(buf), "%.1f", v);
71  } else if (desc.upper - desc.lower >= 100) {
72  snprintf(buf, sizeof(buf), "%.2f", v);
73  } else {
74  snprintf(buf, sizeof(buf), "%.3f", v);
75  }
76  if (desc.print_fmt.empty() && desc.unit == ARDOUR::ParameterDescriptor::DB) {
77  // TODO: Move proper dB printing from AutomationLine here
78  return std::string(buf) + " dB";
79  }
80  return buf;
81 }
82 
83 inline std::string
85  const ARDOUR::Variant& val)
86 {
87  // Only numeric support, for now
88  return value_as_string(desc, val.to_double());
89 }
90 
91 inline double
93  std::string const & str,
94  bool& legal)
95 {
96  legal = true; /* be optimistic */
97 
98  if (desc.scale_points) {
99  // Check if label matches a scale point
100  for (auto const & [label,value] : *desc.scale_points) {
101  if (label == str) {
102  return value; // Found it, return scale point value
103  }
104  }
105  legal = false;
106  return 0.;
107  }
108 
109  if (desc.toggled) {
110  if (str == _("on") || str == _("yes") || str == "1") {
111  return 1.0;
112  } else if (str == _("off") || str == _("no") || str == "0") {
113  return 0.0;
114  } else {
115  legal = false;
116  return 0.;
117  }
118  }
119 
120  // Value is not a scale point, print it normally
122 
124  legal = (nn == 255);
125  return nn;
126 
127  } else if (desc.type == GainAutomation ||
128  desc.type == TrimAutomation ||
129  desc.type == BusSendLevel ||
130  desc.type == EnvelopeAutomation ||
131  desc.type == MainOutVolume ||
132  desc.type == SurroundSendLevel ||
133  desc.type == InsertReturnLevel ||
135 
136  float f;
137  legal = (sscanf (str.c_str(), "%f", &f) == 1);
138  if (!legal) {
139  return 0.;
140  }
141 
142  /* clamp to range */
143 
144  float max_dB = accurate_coefficient_to_dB (desc.upper);
145  float min_dB = accurate_coefficient_to_dB (desc.lower);
146 
147  f = std::max (std::min (f, max_dB), min_dB);
148 
149  return dB_to_coefficient(f);
150 
151  } else if (desc.type == PanWidthAutomation) {
152  int tmp;
153  legal = (sscanf (str.c_str(), "%d", &tmp) == 1);
154  return tmp;
155  } else if (desc.integer_step) {
156  float tmp;
157  legal = (sscanf (str.c_str(), "%g", &tmp) == 1);
158  return (int) tmp;
159  }
160 
161  legal = false;
162  return 0.;
163 }
164 
165 } // namespace ARDOUR
double to_double() const
Definition: variant.h:104
static float dB_to_coefficient(float dB)
Definition: dB.h:31
static float accurate_coefficient_to_dB(float coeff)
Definition: dB.h:39
#define GAIN_COEFF_SMALL
Definition: dB.h:28
#define _(Text)
Definition: i18n.h:29
std::string value_as_string(const ARDOUR::ParameterDescriptor &desc, double v)
double string_as_value(const ARDOUR::ParameterDescriptor &desc, std::string const &str, bool &legal)
std::string print_fmt
format string for pretty printing
static uint8_t midi_note_num(const std::string &name)
std::shared_ptr< ScalePoints > scale_points
static std::string midi_note_name(uint8_t, bool translate=true)
float upper
Maximum value (in Hz, for frequencies)
float lower
Minimum value (in Hz, for frequencies)
bool toggled
True iff parameter is boolean.