Skip to content

Commit 367d529

Browse files
authored
Merge pull request #3740 from mikroffarad/feature/pitch-interface-improvements
Implement separate pitch parameters: cents, semitones, and octaves
2 parents e5e534d + 050bc97 commit 367d529

File tree

6 files changed

+110
-29
lines changed

6 files changed

+110
-29
lines changed

data/schemas/com.github.wwmm.easyeffects.pitch.gschema.xml

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,17 @@
1212
<range min="-36" max="36" />
1313
<default>0</default>
1414
</key>
15+
<key name="cents" type="d">
16+
<range min="-100" max="100" />
17+
<default>0</default>
18+
</key>
1519
<key name="semitones" type="d">
16-
<range min="-12.0" max="12.0" />
17-
<default>0.0</default>
20+
<range min="-12" max="12" />
21+
<default>0</default>
22+
</key>
23+
<key name="octaves" type="d">
24+
<range min="-3" max="3" />
25+
<default>0</default>
1826
</key>
1927
<key name="quick-seek" type="b">
2028
<default>false</default>
@@ -43,4 +51,4 @@
4351
<default>0</default>
4452
</key>
4553
</schema>
46-
</schemalist>
54+
</schemalist>

data/ui/pitch.ui

Lines changed: 47 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,28 @@
129129
<object class="AdwPreferencesGroup">
130130
<property name="title" translatable="yes">Pitch</property>
131131

132+
<child>
133+
<object class="AdwActionRow">
134+
<property name="title" translatable="yes">Cents</property>
135+
<property name="title-lines">2</property>
136+
<child>
137+
<object class="GtkSpinButton" id="cents">
138+
<property name="valign">center</property>
139+
<property name="width-chars">10</property>
140+
<property name="digits">0</property>
141+
<property name="adjustment">
142+
<object class="GtkAdjustment">
143+
<property name="lower">-100</property>
144+
<property name="upper">100</property>
145+
<property name="step-increment">1</property>
146+
<property name="page-increment">1</property>
147+
</object>
148+
</property>
149+
</object>
150+
</child>
151+
</object>
152+
</child>
153+
132154
<child>
133155
<object class="AdwActionRow">
134156
<property name="title" translatable="yes">Semitones</property>
@@ -137,13 +159,35 @@
137159
<object class="GtkSpinButton" id="semitones">
138160
<property name="valign">center</property>
139161
<property name="width-chars">10</property>
140-
<property name="digits">2</property>
162+
<property name="digits">0</property>
141163
<property name="adjustment">
142164
<object class="GtkAdjustment">
143165
<property name="lower">-12</property>
144166
<property name="upper">12</property>
145-
<property name="step-increment">0.01</property>
146-
<property name="page-increment">0.1</property>
167+
<property name="step-increment">1</property>
168+
<property name="page-increment">1</property>
169+
</object>
170+
</property>
171+
</object>
172+
</child>
173+
</object>
174+
</child>
175+
176+
<child>
177+
<object class="AdwActionRow">
178+
<property name="title" translatable="yes">Octaves</property>
179+
<property name="title-lines">2</property>
180+
<child>
181+
<object class="GtkSpinButton" id="octaves">
182+
<property name="valign">center</property>
183+
<property name="width-chars">10</property>
184+
<property name="digits">0</property>
185+
<property name="adjustment">
186+
<object class="GtkAdjustment">
187+
<property name="lower">-3</property>
188+
<property name="upper">3</property>
189+
<property name="step-increment">1</property>
190+
<property name="page-increment">1</property>
147191
</object>
148192
</property>
149193
</object>

include/pitch.hpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,13 @@ class Pitch : public PluginBase {
7575
int seek_window_ms = 15;
7676
int overlap_length_ms = 8;
7777

78-
double semitones = 0.0;
78+
int cents = 0;
79+
int semitones = 0;
80+
int octaves = 0;
7981
double tempo_difference = 0.0;
8082
double rate_difference = 0.0;
8183

82-
void set_semitones();
84+
void update_pitch();
8385
void set_sequence_length();
8486
void set_seek_window();
8587
void set_overlap_length();

src/pitch.cpp

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -179,17 +179,36 @@ Pitch::Pitch(const std::string& tag,
179179
}),
180180
this));
181181

182-
gconnections.push_back(g_signal_connect(settings, "changed::semitones",
182+
gconnections.push_back(g_signal_connect(settings, "changed::cents",
183183
G_CALLBACK(+[](GSettings* settings, char* key, gpointer user_data) {
184184
auto* self = static_cast<Pitch*>(user_data);
185+
self->cents = g_settings_get_double(settings, key);
186+
if (!self->soundtouch_ready) {
187+
return;
188+
}
189+
self->update_pitch();
190+
}),
191+
this));
185192

193+
gconnections.push_back(g_signal_connect(settings, "changed::semitones",
194+
G_CALLBACK(+[](GSettings* settings, char* key, gpointer user_data) {
195+
auto* self = static_cast<Pitch*>(user_data);
186196
self->semitones = g_settings_get_double(settings, key);
187-
188197
if (!self->soundtouch_ready) {
189198
return;
190199
}
200+
self->update_pitch();
201+
}),
202+
this));
191203

192-
self->set_semitones();
204+
gconnections.push_back(g_signal_connect(settings, "changed::octaves",
205+
G_CALLBACK(+[](GSettings* settings, char* key, gpointer user_data) {
206+
auto* self = static_cast<Pitch*>(user_data);
207+
self->octaves = g_settings_get_double(settings, key);
208+
if (!self->soundtouch_ready) {
209+
return;
210+
}
211+
self->update_pitch();
193212
}),
194213
this));
195214

@@ -331,16 +350,6 @@ void Pitch::process(std::span<float>& left_in,
331350
}
332351
}
333352

334-
void Pitch::set_semitones() {
335-
if (snd_touch == nullptr) {
336-
return;
337-
}
338-
339-
std::scoped_lock<std::mutex> lock(data_mutex);
340-
341-
snd_touch->setPitchSemiTones(semitones);
342-
}
343-
344353
void Pitch::set_sequence_length() {
345354
if (snd_touch == nullptr) {
346355
return;
@@ -413,13 +422,10 @@ void Pitch::set_rate_difference() {
413422

414423
void Pitch::init_soundtouch() {
415424
delete snd_touch;
416-
417425
snd_touch = new soundtouch::SoundTouch();
418-
419426
snd_touch->setSampleRate(rate);
420427
snd_touch->setChannels(2);
421-
422-
set_semitones();
428+
update_pitch();
423429
set_quick_seek();
424430
set_anti_alias();
425431
set_sequence_length();
@@ -432,3 +438,13 @@ void Pitch::init_soundtouch() {
432438
auto Pitch::get_latency_seconds() -> float {
433439
return latency_value;
434440
}
441+
442+
void Pitch::update_pitch() {
443+
if (snd_touch == nullptr) {
444+
return;
445+
}
446+
double total_semitones = semitones + (octaves * 12.0) + (cents / 100.0);
447+
std::scoped_lock<std::mutex> lock(data_mutex);
448+
snd_touch->setPitchSemiTones(total_semitones);
449+
}
450+

src/pitch_preset.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@ void PitchPreset::save(nlohmann::json& json) {
5757
json[section][instance_name]["rate-difference"] = g_settings_get_double(settings, "rate-difference");
5858

5959
json[section][instance_name]["semitones"] = g_settings_get_double(settings, "semitones");
60+
61+
json[section][instance_name]["cents"] = g_settings_get_double(settings, "cents");
62+
63+
json[section][instance_name]["octaves"] = g_settings_get_double(settings, "octaves");
6064
}
6165

6266
void PitchPreset::load(const nlohmann::json& json) {
@@ -81,4 +85,8 @@ void PitchPreset::load(const nlohmann::json& json) {
8185
update_key<double>(json.at(section).at(instance_name), settings, "rate-difference", "rate-difference");
8286

8387
update_key<double>(json.at(section).at(instance_name), settings, "semitones", "semitones");
88+
89+
update_key<double>(json.at(section).at(instance_name), settings, "cents", "cents");
90+
91+
update_key<double>(json.at(section).at(instance_name), settings, "octaves", "octaves");
8492
}

src/pitch_ui.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct _PitchBox {
6060
GtkLabel *input_level_left_label, *input_level_right_label, *output_level_left_label, *output_level_right_label,
6161
*plugin_credit;
6262

63-
GtkSpinButton *semitones, *sequence_length, *seek_window, *overlap_length, *tempo_difference, *rate_difference;
63+
GtkSpinButton *cents, *semitones, *octaves, *sequence_length, *seek_window, *overlap_length, *tempo_difference, *rate_difference;
6464

6565
GtkSwitch *quick_seek, *anti_alias;
6666

@@ -126,9 +126,10 @@ void setup(PitchBox* self, std::shared_ptr<Pitch> pitch, const std::string& sche
126126
gsettings_bind_widgets<"input-gain", "output-gain">(self->settings, self->input_gain, self->output_gain);
127127

128128
gsettings_bind_widgets<"quick-seek", "anti-alias", "sequence-length", "seek-window", "overlap-length",
129-
"tempo-difference", "rate-difference", "semitones">(
130-
self->settings, self->quick_seek, self->anti_alias, self->sequence_length, self->seek_window,
131-
self->overlap_length, self->tempo_difference, self->rate_difference, self->semitones);
129+
"tempo-difference", "rate-difference", "semitones", "cents", "octaves">(
130+
self->settings, self->quick_seek, self->anti_alias, self->sequence_length, self->seek_window,
131+
self->overlap_length, self->tempo_difference, self->rate_difference, self->semitones, self->cents, self->octaves);
132+
132133
}
133134

134135
void dispose(GObject* object) {
@@ -193,6 +194,8 @@ void pitch_box_class_init(PitchBoxClass* klass) {
193194
gtk_widget_class_bind_template_child(widget_class, PitchBox, tempo_difference);
194195
gtk_widget_class_bind_template_child(widget_class, PitchBox, rate_difference);
195196
gtk_widget_class_bind_template_child(widget_class, PitchBox, semitones);
197+
gtk_widget_class_bind_template_child(widget_class, PitchBox, cents);
198+
gtk_widget_class_bind_template_child(widget_class, PitchBox, octaves);
196199

197200
gtk_widget_class_bind_template_callback(widget_class, on_reset);
198201
}

0 commit comments

Comments
 (0)