Guitarix
tunerswitcher.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Andreas Degert
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  * --------------------------------------------------------------------------
18  */
19 
20 #include "engine.h"
21 
22 /****************************************************************
23  ** class TunerSwitcher
24  */
25 
26 static const int no_note = 1000;
27 static const int bad_note = 1002;
28 
29 inline bool is_no_note(float n) {
30  return abs(n - no_note) < 1;
31 }
32 
34  : settings(settings_),
35  engine(engine_),
36  display(),
37  set_state(),
38  selection_done(),
39  switcher_conn(),
40  timeout_conn(),
41  current_note(),
42  state(normal_mode),
43  old_engine_state(),
44  new_engine_state(),
45  old_tuner_active(),
46  new_tuner_active(),
47  last_bank_idx(),
48  last_preset_idx() {
49 }
50 
51 bool TunerSwitcher::display_bank_key(int idx) {
52  last_bank_idx = settings.banks.size() - idx - 1;
53  Glib::ustring bank = settings.banks.get_name(last_bank_idx);
54  if (bank.empty()) {
55  display("--", "--");
56  return false;
57  }
58  display(bank, "");
59  return true;
60 }
61 
62 bool TunerSwitcher::display_preset_key(int idx) {
63  last_preset_idx = idx;
64  Glib::ustring bank = settings.banks.get_name(last_bank_idx);
65  if (bank.empty()) {
66  display("??", gx_system::to_string(idx+1));
67  return false;
68  }
69  gx_system::PresetFile *f = settings.banks.get_file(bank);
70  if (idx >= f->size()) {
71  display(bank, gx_system::to_string(idx+1));
72  return false;
73  }
74  display(bank, f->get_name(idx));
75  return true;
76 }
77 
78 void TunerSwitcher::try_load_preset() {
79  switch (last_bank_idx) {
80  case mute_on: new_engine_state = gx_engine::kEngineOff; break;
81  case mute_off: new_engine_state = gx_engine::kEngineOn; break;
82  case bypass_on: new_engine_state = gx_engine::kEngineBypass; break;
83  case bypass_off: new_engine_state = gx_engine::kEngineOn; break;
84  case tuner_on: new_tuner_active = true; break;
85  case tuner_off: new_tuner_active = false; break;
86  default:
87  Glib::ustring bank = settings.banks.get_name(last_bank_idx);
88  if (!bank.empty()) {
89  gx_system::PresetFile *f = settings.banks.get_file(bank);
90  if (last_preset_idx < f->size()) {
91  Glib::ustring preset = f->get_name(last_preset_idx);
92  if (preset != settings.get_current_name() || bank != settings.get_current_bank()) {
93  settings.load_preset(f, preset);
94  }
95  }
96  }
97  break;
98  }
99 }
100 
101 void TunerSwitcher::change_state(SwitcherState newstate) {
102  if (state == newstate) {
103  return;
104  }
105  state = newstate;
106  set_state(state);
107 }
108 
109 bool TunerSwitcher::on_note_timeout() {
110  if (-24 <= current_note && current_note < -10) {
111  change_state(listening);
112  display_bank_key(current_note - (-24));
113  } else if (current_note >= -10 && current_note <= 7) {
114  if (display_preset_key(current_note - (-10))) {
115  change_state(wait_stop);
116  } else {
117  change_state(listening);
118  }
119  } else if (current_note == -25) {
120  if (old_engine_state != gx_engine::kEngineOff) {
121  display("", _("MUTE"));
122  last_bank_idx = mute_on;
123  } else {
124  display("", _("UNMUTE"));
125  last_bank_idx = mute_off;
126  }
127  change_state(wait_stop);
128  } else if (current_note == -26) {
129  if (old_engine_state != gx_engine::kEngineBypass) {
130  display("", _("BYPASS"));
131  last_bank_idx = bypass_on;
132  } else {
133  display("", _("BYPASS OFF"));
134  last_bank_idx = bypass_off;
135  }
136  change_state(wait_stop);
137  } else if (current_note < 26) {
138  if (!old_tuner_active) {
139  display("", _("TUNER ON"));
140  last_bank_idx = tuner_on;
141  } else {
142  display("", _("TUNER OFF"));
143  last_bank_idx = tuner_off;
144  }
145  change_state(wait_stop);
146  }
147  return false;
148 }
149 
150 bool TunerSwitcher::on_state_timeout() {
151  if (state == wait_start) {
152  change_state(listening);
153  current_note = no_note;
154  if (settings.setting_is_preset()) {
155  last_bank_idx = settings.banks.get_index(settings.get_current_bank());
156  last_preset_idx = settings.get_current_bank_file()->get_index(settings.get_current_name());
157  } else {
158  last_bank_idx = last_preset_idx = 0; //FIXME
159  }
160  } else {
161  assert(state == wait_stop);
162  try_load_preset();
163  deactivate();
164  }
165  return false;
166 }
167 
168 void TunerSwitcher::on_tuner_freq_changed() {
169  const float precision = 0.3;
170  float note = engine.tuner.get_note();
171  if (state == wait_start) {
172  if (is_no_note(note)) {
173  if (!timeout_conn.connected()) {
174  current_note = no_note;
175  timeout_conn = Glib::signal_timeout().connect(
176  sigc::mem_fun(this, &TunerSwitcher::on_state_timeout),
177  40);
178  }
179  } else {
180  timeout_conn.disconnect();
181  }
182  return;
183  }
184  if (abs(current_note - note) < precision) {
185  return;
186  }
187  if (state == wait_stop) {
188  if (is_no_note(note)) {
189  if (!is_no_note(current_note)) {
190  timeout_conn.disconnect();
191  }
192  if (!timeout_conn.connected()) {
193  current_note = no_note;
194  timeout_conn = Glib::signal_timeout().connect(
195  sigc::mem_fun(this, &TunerSwitcher::on_state_timeout),
196  40);
197  }
198  return;
199  }
200  }
201  timeout_conn.disconnect();
202  float n = round(note);
203  if (abs(note - n) < precision) {
204  current_note = n;
205  if (!is_no_note(current_note)) {
206  timeout_conn = Glib::signal_timeout().connect(
207  sigc::mem_fun(this, &TunerSwitcher::on_note_timeout),
208  40);
209  }
210  } else {
211  current_note = bad_note;
212  }
213 }
214 
215 void TunerSwitcher::activate(bool tuner_active) {
216  if (get_active()) {
217  return;
218  }
219  bool running = engine.tuner.plugin.get_on_off();
220  engine.tuner.used_for_switching(true);
221  state = normal_mode;
222  change_state(wait_start);
223  new_engine_state = old_engine_state = engine.get_state();
225  new_tuner_active = old_tuner_active = tuner_active;
226  switcher_conn = engine.tuner.signal_freq_changed().connect(
227  sigc::mem_fun(this, &TunerSwitcher::on_tuner_freq_changed));
228  if (running) {
229  on_tuner_freq_changed();
230  }
231 }
232 
234  if (!get_active()) {
235  return;
236  }
237  switcher_conn.disconnect();
238  timeout_conn.disconnect();
239  engine.tuner.used_for_switching(false);
240  change_state(normal_mode);
241  if (new_tuner_active && new_engine_state == gx_engine::kEngineOn) {
242  new_engine_state = gx_engine::kEngineBypass;
243  }
244  engine.set_state(new_engine_state);
245  selection_done(new_tuner_active);
246 }
247 
248 void TunerSwitcher::toggle(bool tuner_active) {
249  if (get_active()) {
250  deactivate();
251  } else {
252  if (tuner_active) {
253  if (engine.get_state() == gx_engine::kEngineBypass) {
255  }
256  selection_done(false);
257  } else {
258  activate(false);
259  }
260  }
261 }
TunerSwitcher(gx_preset::GxSettings &settings, gx_engine::GxEngine &engine)
PresetFile * get_current_bank_file()
Definition: gx_json.h:482
TunerAdapter tuner
Definition: gx_engine.h:86
void activate(bool tuner_active)
PresetFile * get_file(const Glib::ustring &bank) const
Definition: gx_json.cpp:1623
Glib::ustring get_name(int n)
Definition: gx_json.cpp:1687
int precision(double n)
int get_index(const Glib::ustring &bank) const
Definition: gx_json.cpp:1632
bool get_active()
Definition: tunerswitcher.h:66
int get_index(const Glib::ustring &name)
Definition: gx_json.cpp:1134
void load_preset(PresetFile *pf, const Glib::ustring &name)
Definition: gx_json.cpp:1756
std::string to_string(const T &t)
Definition: gx_system.h:523
void set_state(GxEngineState state)
const Glib::ustring & get_current_name()
Definition: gx_json.h:483
bool is_no_note(float n)
Glib::Dispatcher & signal_freq_changed()
const Glib::ustring & get_name(int n)
Definition: gx_json.cpp:1129
bool get_on_off() const
void toggle(bool tuner_active)
const Glib::ustring & get_current_bank()
Definition: gx_json.h:481