Deluge Firmware
1.3.0
Build date: 2026.08.23
Toggle main menu visibility
Loading...
Searching...
No Matches
polyphony.h
1
/*
2
* Copyright (c) 2014-2023 Synthstrom Audible Limited
3
*
4
* This file is part of The Synthstrom Audible Deluge Firmware.
5
*
6
* The Synthstrom Audible Deluge Firmware is free software: you can redistribute it and/or modify it under the
7
* terms of the GNU General Public License as published by the Free Software Foundation,
8
* either version 3 of the License, or (at your option) any later version.
9
*
10
* This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
11
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
* See the GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License along with this program.
15
* If not, see <https://www.gnu.org/licenses/>.
16
*/
17
#pragma once
18
19
#include "definitions_cxx.hpp"
20
#include "gui/menu_item/selection.h"
21
#include "gui/ui/sound_editor.h"
22
#include "model/drum/drum.h"
23
#include "model/instrument/kit.h"
24
#include "model/song/song.h"
25
#include "processing/sound/sound.h"
26
#include "processing/sound/sound_drum.h"
27
28
#include <hid/display/oled.h>
29
30
namespace
deluge::gui::menu_item::voice {
31
class
VoiceCount
:
public
IntegerWithOff
{
32
public
:
33
using
IntegerWithOff::IntegerWithOff;
34
void
readCurrentValue
()
override
{
35
uint8_t voiceCount = soundEditor.currentSound->maxVoiceCount;
36
if
(voiceCount > getMaxValue()) {
37
voiceCount = 0;
38
}
39
this->setValue(voiceCount);
40
}
41
bool
usesAffectEntire
()
override
{
return
true
; }
42
void
writeCurrentValue()
override
{
43
int32_t current_value = this->getValue();
44
current_value = current_value == 0 ? 127 : current_value;
45
46
// If affect-entire button held, do whole kit
47
if
(currentUIMode == UI_MODE_HOLDING_AFFECT_ENTIRE_IN_SOUND_EDITOR && soundEditor.editingKitRow()) {
48
49
Kit
* kit = getCurrentKit();
50
51
for
(
Drum
* thisDrum = kit->firstDrum; thisDrum !=
nullptr
; thisDrum = thisDrum->next) {
52
if
(thisDrum->type == DrumType::SOUND) {
53
auto
* soundDrum =
static_cast<
SoundDrum
*
>
(thisDrum);
54
// Note: we need to apply the same filtering as stated in the isRelevant() function
55
if
(soundDrum->polyphonic == PolyphonyMode::POLY) {
56
soundDrum->maxVoiceCount = current_value;
57
}
58
}
59
}
60
}
61
// Or, the normal case of just one sound
62
else
{
63
soundEditor.currentSound->maxVoiceCount = current_value;
64
}
65
}
66
[[nodiscard]] int32_t getMinValue()
const override
{
return
0; }
67
[[nodiscard]] int32_t getMaxValue()
const override
{
return
16; }
68
[[nodiscard]] RenderingStyle getRenderingStyle()
const override
{
return
NUMBER; }
69
70
bool
isRelevant
(
ModControllableAudio
* modControllable, int32_t whichThing)
override
{
71
Sound
* sound =
static_cast<
Sound
*
>
(modControllable);
72
return
(sound->polyphonic == PolyphonyMode::POLY);
73
}
74
75
void
getColumnLabel(
StringBuf
& label)
override
{
76
label.append(deluge::l10n::get(l10n::String::STRING_FOR_MAX_VOICES_SHORT));
77
}
78
79
void
getNotificationValue
(
StringBuf
& valueBuf)
override
{
80
if
(
const
auto
value = getValue(); value == 0) {
81
valueBuf.append(l10n::get(l10n::String::STRING_FOR_OFF));
82
}
83
else
{
84
valueBuf.appendInt(value);
85
}
86
}
87
88
void
renderInHorizontalMenu(
const
SlotPosition
& slot)
override
{
89
if
(getValue() == 0) {
90
return
OLED::main.drawIconCentered(OLED::infinityIcon, slot.start_x, slot.width,
91
slot.start_y + kHorizontalMenuSlotYOffset + 1);
92
}
93
IntegerWithOff::renderInHorizontalMenu(slot);
94
}
95
};
96
97
extern
VoiceCount polyphonicVoiceCountMenu;
98
99
class
PolyphonyType
final :
public
Selection
{
100
public
:
101
using
Selection::Selection;
102
void
readCurrentValue
()
override
{ this->setValue(soundEditor.currentSound->polyphonic); }
103
bool
usesAffectEntire
()
override
{
return
true
; }
104
void
writeCurrentValue()
override
{
105
auto
current_value = this->getValue<PolyphonyMode>();
106
107
// If affect-entire button held, do whole kit
108
if
(currentUIMode == UI_MODE_HOLDING_AFFECT_ENTIRE_IN_SOUND_EDITOR && soundEditor.editingKitRow()) {
109
110
Kit
* kit = getCurrentKit();
111
112
for
(
Drum
* thisDrum = kit->firstDrum; thisDrum !=
nullptr
; thisDrum = thisDrum->next) {
113
if
(thisDrum->type == DrumType::SOUND) {
114
auto
* soundDrum =
static_cast<
SoundDrum
*
>
(thisDrum);
115
soundDrum->polyphonic = current_value;
116
}
117
}
118
}
119
// Or, the normal case of just one sound
120
else
{
121
soundEditor.currentSound->polyphonic = current_value;
122
}
123
}
124
125
deluge::vector<std::string_view> getOptions(OptType optType)
override
{
126
(void)optType;
127
deluge::vector<std::string_view> options = {
128
l10n::getView(l10n::String::STRING_FOR_AUTO),
129
l10n::getView(l10n::String::STRING_FOR_POLYPHONIC),
130
l10n::getView(l10n::String::STRING_FOR_MONOPHONIC),
131
l10n::getView(l10n::String::STRING_FOR_LEGATO),
132
};
133
134
if
(soundEditor.editingKit()) {
135
options.push_back(l10n::getView(l10n::String::STRING_FOR_CHOKE));
136
}
137
return
options;
138
}
139
MenuItem*
selectButtonPress
()
override
{
140
if
(this->getValue<PolyphonyMode>() == PolyphonyMode::POLY) {
141
return
&polyphonicVoiceCountMenu;
142
}
143
return
Selection::selectButtonPress
();
144
}
145
146
void
getColumnLabel(
StringBuf
& label)
override
{
147
label.append(deluge::l10n::get(l10n::String::STRING_FOR_POLYPHONY_SHORT));
148
}
149
};
150
}
// namespace deluge::gui::menu_item::voice
Drum
Definition
drum.h:44
Kit
Definition
kit.h:34
ModControllableAudio
Definition
mod_controllable_audio.h:47
SoundDrum
Definition
sound_drum.h:28
Sound
Definition
sound.h:71
StringBuf
Definition
d_stringbuf.h:16
deluge::gui::menu_item::IntegerWithOff
Definition
integer.h:40
deluge::gui::menu_item::Selection
Definition
selection.h:26
deluge::gui::menu_item::Selection::selectButtonPress
MenuItem * selectButtonPress() override
Handle a select button press.
Definition
selection.h:56
deluge::gui::menu_item::voice::PolyphonyType
Definition
polyphony.h:99
deluge::gui::menu_item::voice::PolyphonyType::selectButtonPress
MenuItem * selectButtonPress() override
Handle a select button press.
Definition
polyphony.h:139
deluge::gui::menu_item::voice::PolyphonyType::usesAffectEntire
bool usesAffectEntire() override
Claim support for Kit AFFECT_ENTIRE editing.
Definition
polyphony.h:103
deluge::gui::menu_item::voice::PolyphonyType::readCurrentValue
void readCurrentValue() override
Like readValueAgain, but does not redraw.
Definition
polyphony.h:102
deluge::gui::menu_item::voice::VoiceCount
Definition
polyphony.h:31
deluge::gui::menu_item::voice::VoiceCount::usesAffectEntire
bool usesAffectEntire() override
Claim support for Kit AFFECT_ENTIRE editing.
Definition
polyphony.h:41
deluge::gui::menu_item::voice::VoiceCount::getNotificationValue
void getNotificationValue(StringBuf &valueBuf) override
Get the parameter value string to show in the popup.
Definition
polyphony.h:79
deluge::gui::menu_item::voice::VoiceCount::isRelevant
bool isRelevant(ModControllableAudio *modControllable, int32_t whichThing) override
Check if this MenuItem should show up in a containing deluge::gui::menu_item::Submenu.
Definition
polyphony.h:70
deluge::gui::menu_item::voice::VoiceCount::readCurrentValue
void readCurrentValue() override
Like readValueAgain, but does not redraw.
Definition
polyphony.h:34
SlotPosition
Definition
menu_item.h:33