33 Transpose(l10n::String name, l10n::String title_format_str, int32_t newP, uint8_t source_id)
34 :
source::Transpose(name, newP, source_id), FormattedTitle(title_format_str, source_id + 1) {}
36 [[nodiscard]] std::string_view
getTitle()
const override {
return FormattedTitle::title(); }
39 int32_t transpose = 0;
42 Source& source = soundEditor.currentSound->sources[source_id_];
44 if (source.ranges.getNumElements() && soundEditor.currentSound->getSynthMode() != SynthMode::FM
45 && source.oscType == OscType::SAMPLE) {
46 const auto* multi_sample_range =
47 soundEditor.currentSourceIndex == source_id_ && soundEditor.currentMultiRange !=
nullptr
50 transpose = multi_sample_range->sampleHolder.transpose;
51 cents = multi_sample_range->sampleHolder.cents;
54 transpose = source.transpose;
57 this->setValue(computeCurrentValueForTranspose(transpose, cents));
62 void writeCurrentValue()
override {
63 int32_t transpose, cents;
64 computeFinalValuesForTranspose(this->getValue(), &transpose, ¢s);
67 if (currentUIMode == UI_MODE_HOLDING_AFFECT_ENTIRE_IN_SOUND_EDITOR && soundEditor.editingKit()) {
69 Kit* kit = getCurrentKit();
71 for (
Drum* thisDrum = kit->firstDrum; thisDrum !=
nullptr; thisDrum = thisDrum->next) {
72 if (thisDrum->type == DrumType::SOUND) {
73 auto* soundDrum =
static_cast<SoundDrum*
>(thisDrum);
74 Source& source = soundDrum->sources[source_id_];
76 if (source.ranges.getNumElements() && soundDrum->getSynthMode() != SynthMode::FM
77 && source.oscType == OscType::SAMPLE) {
78 auto* multi_sample_range =
static_cast<MultisampleRange*
>(source.ranges.getElement(0));
79 multi_sample_range->sampleHolder.transpose = transpose;
80 multi_sample_range->sampleHolder.setCents(cents);
83 source.transpose = transpose;
84 source.setCents(cents);
87 char modelStackMemoryForSoundDrum[MODEL_STACK_MAX_SIZE];
89 getModelStackFromSoundDrum(modelStackMemoryForSoundDrum, soundDrum)->addSoundFlags();
91 soundDrum->recalculateAllVoicePhaseIncrements(modelStackForSoundDrum);
97 Source& source = soundEditor.currentSound->sources[source_id_];
99 if (source.ranges.getNumElements() && soundEditor.currentSound->getSynthMode() != SynthMode::FM
100 && source.oscType == OscType::SAMPLE) {
101 auto* multi_sample_range =
102 soundEditor.currentSourceIndex == source_id_ && soundEditor.currentMultiRange !=
nullptr
103 ?
static_cast<MultisampleRange*
>(soundEditor.currentMultiRange)
104 : static_cast<MultisampleRange*>(source.ranges.getElement(0));
105 multi_sample_range->sampleHolder.transpose = transpose;
106 multi_sample_range->sampleHolder.setCents(cents);
109 source.transpose = transpose;
110 source.setCents(cents);
113 char modelStackMemory[MODEL_STACK_MAX_SIZE];
114 ModelStackWithSoundFlags* modelStack = soundEditor.getCurrentModelStack(modelStackMemory)->addSoundFlags();
116 soundEditor.currentSound->recalculateAllVoicePhaseIncrements(modelStack);
120 MenuPermission checkPermissionToBeginSession(ModControllableAudio* modControllable, int32_t,
121 ::MultiRange** currentRange)
override {
122 if (!
isRelevant(modControllable, source_id_)) {
123 return MenuPermission::NO;
126 const auto sound =
static_cast<Sound*
>(modControllable);
127 const Source& source = sound->sources[source_id_];
129 if (sound->getSynthMode() == SynthMode::FM
130 || (source.oscType != OscType::SAMPLE && source.oscType != OscType::WAVETABLE)) {
131 return MenuPermission::YES;
134 return soundEditor.checkPermissionToBeginSessionForRangeSpecificParam(sound, source_id_, currentRange);
140 const auto sound =
static_cast<Sound*
>(modControllable);
141 if (
Source& source = sound->sources[source_id_];
142 source.oscType == OscType::SAMPLE || source.oscType == OscType::WAVETABLE) {
143 return source.hasAtLeastOneAudioFileLoaded();
151 Source& source = soundEditor.currentSound->sources[source_id_];
152 const int32_t rangeIndex = soundEditor.currentMultiRangeIndex;
153 const int32_t numRanges = source.ranges.getNumElements();
155 if (soundEditor.currentSourceIndex != source_id_ || soundEditor.currentMultiRange ==
nullptr || numRanges <= 1
156 || rangeIndex < 0 || rangeIndex >= numRanges || source.oscType != OscType::SAMPLE) {
160 valueBuf.append(
" (");
162 if (rangeIndex == 0) {
163 valueBuf.append(l10n::get(l10n::String::STRING_FOR_BOTTOM));
167 noteCodeToString(source.ranges.getElement(rangeIndex - 1)->topNote + 1, noteName);
168 valueBuf.append(noteName);
171 valueBuf.append(
"-");
173 if (rangeIndex == numRanges - 1) {
174 valueBuf.append(
"top");
178 noteCodeToString(source.ranges.getElement(rangeIndex)->topNote, noteName);
179 valueBuf.append(noteName);
182 valueBuf.append(
")");