Skip to content
Browse files

Added duophonic mode

  • Loading branch information...
1 parent 48bb5ae commit 7aff2ec1f64d6a5fb1983cc5202ebd3428568680 @pichenettes committed Apr 4, 2012
View
5 RELEASES
@@ -18,11 +18,16 @@ trigger effects (such as a pitch change or LFO speed boost) from a keyboard or
an external MIDI sequencer.
- 2 new modulation destinations, "env 1" and "env 2" allow the envelopes to be
triggered whenever a modulation source crosses a threshold.
+- A new mixing mode, "duo", allows the synth to be used in a pseudo-duophonic
+mode. The least recently played note is played on osc 2, and the most recently
+played note is played on osc 1.
- 3 new mixing modes, "2 steps", "4 steps" and "8 steps" allows the oscillators
(or oscillators, sub-oscillator and noise source) to be triggered rythmically
at each note.
- A new mixing mode, "stepmix" allows the oscillators/sub/noise sources to be
rythmically disabled according to the pattern input in the step sequencer.
+- The attack time modulation destination now accepts both positive (faster
+attack) and negative (slower attack) modulations.
FILTER BOARD HANDLING
View
1 shruthi/patch.h
@@ -370,6 +370,7 @@ enum Operator {
OP_CRUSH_8,
OP_FOLD,
OP_BITS,
+ OP_DUO,
OP_PING_PONG_2,
OP_PING_PONG_4,
OP_PING_PONG_8,
View
2 shruthi/resources.cc
@@ -289,6 +289,7 @@ static const prog_char str_res_gg4[] PROGMEM = ">>4";
static const prog_char str_res_gg8[] PROGMEM = ">>8";
static const prog_char str_res_fold[] PROGMEM = "fold";
static const prog_char str_res_bits[] PROGMEM = "bits";
+static const prog_char str_res_duo[] PROGMEM = "duo";
static const prog_char str_res_2steps[] PROGMEM = "2steps";
static const prog_char str_res_4steps[] PROGMEM = "4steps";
static const prog_char str_res_8steps[] PROGMEM = "8steps";
@@ -714,6 +715,7 @@ PROGMEM const prog_char* string_table[] = {
str_res_gg8,
str_res_fold,
str_res_bits,
+ str_res_duo,
str_res_2steps,
str_res_4steps,
str_res_8steps,
View
305 shruthi/resources.h
@@ -399,158 +399,159 @@ extern const prog_uint8_t chr_res_special_characters[] PROGMEM;
#define STR_RES_GG8 281 // >>8
#define STR_RES_FOLD 282 // fold
#define STR_RES_BITS 283 // bits
-#define STR_RES_2STEPS 284 // 2steps
-#define STR_RES_4STEPS 285 // 4steps
-#define STR_RES_8STEPS 286 // 8steps
-#define STR_RES_SEQMIX 287 // seqmix
-#define STR_RES_STP 288 // stp
-#define STR_RES___ARP 289 // arp
-#define STR_RES_ARPSLT 290 // arp+lt
-#define STR_RES__SEQ 291 // seq
-#define STR_RES_SEQSLT 292 // seq+lt
-#define STR_RES_REC 293 // rec
-#define STR_RES_IMPRO 294 // impro
-#define STR_RES_FREE 295 // free
-#define STR_RES_SLAVE 296 // slave
-#define STR_RES_MASTER 297 // master
-#define STR_RES_T 298 // ~
-#define STR_RES__ 299 // 
-#define STR_RES_T_ 300 // ~-
-#define STR_RES__T_ 301 // ~
-#define STR_RES_GLASS 302 // glass
-#define STR_RES_KRAMA 303 // krama
-#define STR_RES_JATA 304 // jata
-#define STR_RES_SIKHA 305 // sikha
-#define STR_RES_GHANA 306 // ghana
-#define STR_RES_2GLASS 307 // 2glass
-#define STR_RES_2KRAMA 308 // 2krama
-#define STR_RES_2JATA 309 // 2jata
-#define STR_RES_2SIKHA 310 // 2sikha
-#define STR_RES_2GHANA 311 // 2ghana
-#define STR_RES_4GLASS 312 // 4glass
-#define STR_RES_4KRAMA 313 // 4krama
-#define STR_RES_4JATA 314 // 4jata
-#define STR_RES_4SIKHA 315 // 4sikha
-#define STR_RES_4GHANA 316 // 4ghana
-#define STR_RES_SWING 317 // swing
-#define STR_RES_SHUFFLE 318 // shuffle
-#define STR_RES_PUSH 319 // push
-#define STR_RES__LAG 320 // lag
-#define STR_RES_HUMAN 321 // human
-#define STR_RES_MONKEY 322 // monkey
-#define STR_RES__OFF 323 // off
-#define STR_RES_THRU 324 // thru
-#define STR_RES___SEQ 325 // seq
-#define STR_RES_CTRL 326 // ctrl
-#define STR_RES__SPLIT 327 // split
-#define STR_RES_FULL 328 // full
-#define STR_RES_1TV 329 // 1~|
-#define STR_RES_2T1 330 // 2~1
-#define STR_RES_3T2 331 // 3~2
-#define STR_RES_4T3 332 // 4~3
-#define STR_RES_5T4 333 // 5~4
-#define STR_RES_6T5 334 // 6~5
-#define STR_RES_7T6 335 // 7~6
-#define STR_RES_8T7 336 // 8~7
-#define STR_RES_TRI 337 // tri
-#define STR_RES_SQR 338 // sqr
-#define STR_RES_S_H 339 // s&h
-#define STR_RES_RAMP 340 // ramp
-#define STR_RES_STEP 341 // step
-#define STR_RES_3 342 // 
-#define STR_RES_4 343 // 
-#define STR_RES_34 344 // 
-#define STR_RES___ 345 // ?
-#define STR_RES_OFF 346 // off
-#define STR_RES_ON 347 // on
-#define STR_RES_SQ1 348 // sq1
-#define STR_RES__TR1 349 // tr1
-#define STR_RES_PL1 350 // pl1
-#define STR_RES_SQ2 351 // sq2
-#define STR_RES__TR2 352 // tr2
-#define STR_RES_PL2 353 // pl2
-#define STR_RES_CLICK 354 // click
-#define STR_RES_GLITCH 355 // glitch
-#define STR_RES_BLOW 356 // blow
-#define STR_RES_METAL 357 // metal
-#define STR_RES_POP 358 // pop
-#define STR_RES_NONE 359 // none
-#define STR_RES_SAW 360 // saw
-#define STR_RES_SQUARE 361 // square
-#define STR_RES_TRIANG 362 // triang
-#define STR_RES_ZSAW 363 // zsaw
-#define STR_RES_ZRESO 364 // zreso
-#define STR_RES_ZTRI 365 // ztri
-#define STR_RES_ZPULSE 366 // zpulse
-#define STR_RES_ZSYNC 367 // zsync
-#define STR_RES_PAD 368 // pad
-#define STR_RES_FM 369 // fm
-#define STR_RES_WAVES 370 // waves
-#define STR_RES_TAMPUR 371 // tampur
-#define STR_RES_DIGITL 372 // digitl
-#define STR_RES_METALL 373 // metall
-#define STR_RES_BOWED 374 // bowed
-#define STR_RES_SLAP 375 // slap
-#define STR_RES_ORGAN 376 // organ
-#define STR_RES_MALE 377 // male
-#define STR_RES_USER 378 // user
-#define STR_RES_8BITS 379 // 8bits
-#define STR_RES_CRUSH 380 // crush
-#define STR_RES_PWM 381 // pwm
-#define STR_RES___NOISE 382 // noise
-#define STR_RES_VOWEL 383 // vowel
-#define STR_RES_BELISH 384 // belish
-#define STR_RES_POLATD 385 // polatd
-#define STR_RES_CELLO 386 // cello
-#define STR_RES_CLPSWP 387 // clpswp
-#define STR_RES_FEMALE 388 // female
-#define STR_RES_FMTVOC 389 // fmtvoc
-#define STR_RES_FRMNT2 390 // frmnt2
-#define STR_RES_RES3HP 391 // res3hp
-#define STR_RES_ELECTP 392 // electp
-#define STR_RES_VIBES 393 // vibes
-#define STR_RES__LPF 394 // lpf
-#define STR_RES_SSM 395 // ssm
-#define STR_RES_SVF 396 // svf
-#define STR_RES_DSP 397 // dsp
-#define STR_RES_PVK 398 // pvk
-#define STR_RES_4PM 399 // 4pm
-#define STR_RES_4CV_IN 400 // 4cv in
-#define STR_RES_PRGM 401 // prgm
-#define STR_RES_PEDALS 402 // pedals
-#define STR_RES_EQUAL 403 // equal
-#define STR_RES_JUST 404 // just
-#define STR_RES_PYTHAG 405 // pythag
-#define STR_RES_1_4_EB 406 // 1/4 eb
-#define STR_RES_1_4_E 407 // 1/4 e
-#define STR_RES_1_4_EA 408 // 1/4 ea
-#define STR_RES_BHAIRA 409 // bhaira
-#define STR_RES_GUNAKR 410 // gunakr
-#define STR_RES_MARWA 411 // marwa
-#define STR_RES_SHREE 412 // shree
-#define STR_RES_PURVI 413 // purvi
-#define STR_RES_BILAWA 414 // bilawa
-#define STR_RES_YAMAN 415 // yaman
-#define STR_RES_KAFI 416 // kafi
-#define STR_RES_BHIMPA 417 // bhimpa
-#define STR_RES_DARBAR 418 // darbar
-#define STR_RES_BAGESH 419 // bagesh
-#define STR_RES_RAGESH 420 // ragesh
-#define STR_RES_KHAMAJ 421 // khamaj
-#define STR_RES_MIMAL 422 // mi'mal
-#define STR_RES_PARAME 423 // parame
-#define STR_RES_RANGES 424 // ranges
-#define STR_RES_GANGES 425 // ganges
-#define STR_RES_KAMESH 426 // kamesh
-#define STR_RES_PALAS_ 427 // palas
-#define STR_RES_NATBHA 428 // natbha
-#define STR_RES_M_KAUN 429 // m.kaun
-#define STR_RES_BAIRAG 430 // bairag
-#define STR_RES_B_TODI 431 // b.todi
-#define STR_RES_CHANDR 432 // chandr
-#define STR_RES_KAUSHI 433 // kaushi
-#define STR_RES_JOGESH 434 // jogesh
-#define STR_RES_RASIA 435 // rasia
+#define STR_RES_DUO 284 // duo
+#define STR_RES_2STEPS 285 // 2steps
+#define STR_RES_4STEPS 286 // 4steps
+#define STR_RES_8STEPS 287 // 8steps
+#define STR_RES_SEQMIX 288 // seqmix
+#define STR_RES_STP 289 // stp
+#define STR_RES___ARP 290 // arp
+#define STR_RES_ARPSLT 291 // arp+lt
+#define STR_RES__SEQ 292 // seq
+#define STR_RES_SEQSLT 293 // seq+lt
+#define STR_RES_REC 294 // rec
+#define STR_RES_IMPRO 295 // impro
+#define STR_RES_FREE 296 // free
+#define STR_RES_SLAVE 297 // slave
+#define STR_RES_MASTER 298 // master
+#define STR_RES_T 299 // ~
+#define STR_RES__ 300 // 
+#define STR_RES_T_ 301 // ~-
+#define STR_RES__T_ 302 // ~
+#define STR_RES_GLASS 303 // glass
+#define STR_RES_KRAMA 304 // krama
+#define STR_RES_JATA 305 // jata
+#define STR_RES_SIKHA 306 // sikha
+#define STR_RES_GHANA 307 // ghana
+#define STR_RES_2GLASS 308 // 2glass
+#define STR_RES_2KRAMA 309 // 2krama
+#define STR_RES_2JATA 310 // 2jata
+#define STR_RES_2SIKHA 311 // 2sikha
+#define STR_RES_2GHANA 312 // 2ghana
+#define STR_RES_4GLASS 313 // 4glass
+#define STR_RES_4KRAMA 314 // 4krama
+#define STR_RES_4JATA 315 // 4jata
+#define STR_RES_4SIKHA 316 // 4sikha
+#define STR_RES_4GHANA 317 // 4ghana
+#define STR_RES_SWING 318 // swing
+#define STR_RES_SHUFFLE 319 // shuffle
+#define STR_RES_PUSH 320 // push
+#define STR_RES__LAG 321 // lag
+#define STR_RES_HUMAN 322 // human
+#define STR_RES_MONKEY 323 // monkey
+#define STR_RES__OFF 324 // off
+#define STR_RES_THRU 325 // thru
+#define STR_RES___SEQ 326 // seq
+#define STR_RES_CTRL 327 // ctrl
+#define STR_RES__SPLIT 328 // split
+#define STR_RES_FULL 329 // full
+#define STR_RES_1TV 330 // 1~|
+#define STR_RES_2T1 331 // 2~1
+#define STR_RES_3T2 332 // 3~2
+#define STR_RES_4T3 333 // 4~3
+#define STR_RES_5T4 334 // 5~4
+#define STR_RES_6T5 335 // 6~5
+#define STR_RES_7T6 336 // 7~6
+#define STR_RES_8T7 337 // 8~7
+#define STR_RES_TRI 338 // tri
+#define STR_RES_SQR 339 // sqr
+#define STR_RES_S_H 340 // s&h
+#define STR_RES_RAMP 341 // ramp
+#define STR_RES_STEP 342 // step
+#define STR_RES_3 343 // 
+#define STR_RES_4 344 // 
+#define STR_RES_34 345 // 
+#define STR_RES___ 346 // ?
+#define STR_RES_OFF 347 // off
+#define STR_RES_ON 348 // on
+#define STR_RES_SQ1 349 // sq1
+#define STR_RES__TR1 350 // tr1
+#define STR_RES_PL1 351 // pl1
+#define STR_RES_SQ2 352 // sq2
+#define STR_RES__TR2 353 // tr2
+#define STR_RES_PL2 354 // pl2
+#define STR_RES_CLICK 355 // click
+#define STR_RES_GLITCH 356 // glitch
+#define STR_RES_BLOW 357 // blow
+#define STR_RES_METAL 358 // metal
+#define STR_RES_POP 359 // pop
+#define STR_RES_NONE 360 // none
+#define STR_RES_SAW 361 // saw
+#define STR_RES_SQUARE 362 // square
+#define STR_RES_TRIANG 363 // triang
+#define STR_RES_ZSAW 364 // zsaw
+#define STR_RES_ZRESO 365 // zreso
+#define STR_RES_ZTRI 366 // ztri
+#define STR_RES_ZPULSE 367 // zpulse
+#define STR_RES_ZSYNC 368 // zsync
+#define STR_RES_PAD 369 // pad
+#define STR_RES_FM 370 // fm
+#define STR_RES_WAVES 371 // waves
+#define STR_RES_TAMPUR 372 // tampur
+#define STR_RES_DIGITL 373 // digitl
+#define STR_RES_METALL 374 // metall
+#define STR_RES_BOWED 375 // bowed
+#define STR_RES_SLAP 376 // slap
+#define STR_RES_ORGAN 377 // organ
+#define STR_RES_MALE 378 // male
+#define STR_RES_USER 379 // user
+#define STR_RES_8BITS 380 // 8bits
+#define STR_RES_CRUSH 381 // crush
+#define STR_RES_PWM 382 // pwm
+#define STR_RES___NOISE 383 // noise
+#define STR_RES_VOWEL 384 // vowel
+#define STR_RES_BELISH 385 // belish
+#define STR_RES_POLATD 386 // polatd
+#define STR_RES_CELLO 387 // cello
+#define STR_RES_CLPSWP 388 // clpswp
+#define STR_RES_FEMALE 389 // female
+#define STR_RES_FMTVOC 390 // fmtvoc
+#define STR_RES_FRMNT2 391 // frmnt2
+#define STR_RES_RES3HP 392 // res3hp
+#define STR_RES_ELECTP 393 // electp
+#define STR_RES_VIBES 394 // vibes
+#define STR_RES__LPF 395 // lpf
+#define STR_RES_SSM 396 // ssm
+#define STR_RES_SVF 397 // svf
+#define STR_RES_DSP 398 // dsp
+#define STR_RES_PVK 399 // pvk
+#define STR_RES_4PM 400 // 4pm
+#define STR_RES_4CV_IN 401 // 4cv in
+#define STR_RES_PRGM 402 // prgm
+#define STR_RES_PEDALS 403 // pedals
+#define STR_RES_EQUAL 404 // equal
+#define STR_RES_JUST 405 // just
+#define STR_RES_PYTHAG 406 // pythag
+#define STR_RES_1_4_EB 407 // 1/4 eb
+#define STR_RES_1_4_E 408 // 1/4 e
+#define STR_RES_1_4_EA 409 // 1/4 ea
+#define STR_RES_BHAIRA 410 // bhaira
+#define STR_RES_GUNAKR 411 // gunakr
+#define STR_RES_MARWA 412 // marwa
+#define STR_RES_SHREE 413 // shree
+#define STR_RES_PURVI 414 // purvi
+#define STR_RES_BILAWA 415 // bilawa
+#define STR_RES_YAMAN 416 // yaman
+#define STR_RES_KAFI 417 // kafi
+#define STR_RES_BHIMPA 418 // bhimpa
+#define STR_RES_DARBAR 419 // darbar
+#define STR_RES_BAGESH 420 // bagesh
+#define STR_RES_RAGESH 421 // ragesh
+#define STR_RES_KHAMAJ 422 // khamaj
+#define STR_RES_MIMAL 423 // mi'mal
+#define STR_RES_PARAME 424 // parame
+#define STR_RES_RANGES 425 // ranges
+#define STR_RES_GANGES 426 // ganges
+#define STR_RES_KAMESH 427 // kamesh
+#define STR_RES_PALAS_ 428 // palas
+#define STR_RES_NATBHA 429 // natbha
+#define STR_RES_M_KAUN 430 // m.kaun
+#define STR_RES_BAIRAG 431 // bairag
+#define STR_RES_B_TODI 432 // b.todi
+#define STR_RES_CHANDR 433 // chandr
+#define STR_RES_KAUSHI 434 // kaushi
+#define STR_RES_JOGESH 435 // jogesh
+#define STR_RES_RASIA 436 // rasia
#define LUT_RES_LFO_INCREMENTS 0
#define LUT_RES_LFO_INCREMENTS_SIZE 128
#define LUT_RES_ENV_PORTAMENTO_INCREMENTS 1
View
1 shruthi/resources/strings.py
@@ -316,6 +316,7 @@
>>8
fold
bits
+duo
2steps
4steps
8steps
View
74 shruthi/synthesis_engine.cc
@@ -641,6 +641,7 @@ uint8_t Voice::gate_;
int16_t Voice::pitch_increment_;
int16_t Voice::pitch_target_;
int16_t Voice::pitch_value_;
+int16_t Voice::aux_pitch_;
uint8_t Voice::modulation_sources_[kNumModulationSources];
uint8_t Voice::unregistered_modulation_sources_[1];
int8_t Voice::modulation_destinations_[kNumModulationDestinations];
@@ -682,29 +683,55 @@ void Voice::TriggerEnvelope(uint8_t index, uint8_t stage) {
}
/* static */
-void Voice::Trigger(uint8_t note, uint8_t velocity, uint8_t legato) {
+uint16_t Voice::NoteToPitch(uint8_t note) {
if (engine.system_settings_.raga) {
int16_t pitch_shift = ResourcesManager::Lookup<int16_t, uint8_t>(
ResourceId(LUT_RES_SCALE_JUST + engine.system_settings_.raga - 1),
note % 12);
if (pitch_shift != 32767) {
// Some scales/raga settings might have muted notes. Do not trigger
// anything in this case!
- pitch_target_ = (static_cast<uint16_t>(note) * 128) + pitch_shift;
+ return U8U8Mul(note, 128) + pitch_shift;
} else {
- if (legato) {
- legato = 255;
- }
+ return 0;
}
} else {
- pitch_target_ = U8U8Mul(note, 128);
+ return U8U8Mul(note, 128);
+ }
+}
+
+/* static */
+void Voice::TriggerSecondNote(uint8_t note) {
+ aux_pitch_ = NoteToPitch(note);
+ if (aux_pitch_ == pitch_target_) {
+ aux_pitch_ = 0;
+ }
+}
+
+/* static */
+void Voice::Trigger(uint8_t note, uint8_t velocity, uint8_t legato) {
+ if (!velocity && engine.patch_.osc[0].option == OP_DUO) {
+ // In duophonic mode, ignore the stack retriggering.
+ return;
+ }
+ aux_pitch_ = pitch_target_;
+ uint16_t pitch = NoteToPitch(note);
+ if (pitch == 0) {
+ if (legato) {
+ legato = 255;
+ }
+ } else {
+ pitch_target_ = pitch;
}
if (!legato || (!engine.system_settings_.legato && legato != 255)) {
for (uint8_t i = 0; i < kNumEnvelopes; ++i) {
if (!disable_envelope_auto_retriggering_[i]) {
envelope_[i].Trigger(ATTACK);
}
}
+ if (engine.voice_controller().notes().size() == 1 && !legato) {
+ aux_pitch_ = 0;
+ }
++trigger_count_;
gate_ = 255;
// The LFOs are shared by all voices, so if there are other voices still
@@ -900,10 +927,12 @@ inline void Voice::UpdateDestinations() {
// transistors are thermically coupled. You can disable tracking by applying
// a negative modulation from NOTE to CUTOFF.
uint16_t cutoff = dst_[MOD_DST_FILTER_CUTOFF];
- if (engine.system_settings().expansion_filter_board == FILTER_BOARD_PVK) {
- cutoff = S16ClipU14(cutoff + pitch_value_ - 8192 + (16 << 7));
- } else {
- cutoff = S16ClipU14(cutoff + pitch_value_ - 8192);
+ if (engine.patch_.osc[0].option != OP_DUO) {
+ if (engine.system_settings().expansion_filter_board == FILTER_BOARD_PVK) {
+ cutoff = S16ClipU14(cutoff + pitch_value_ - 8192 + (16 << 7));
+ } else {
+ cutoff = S16ClipU14(cutoff + pitch_value_ - 8192);
+ }
}
cutoff = S16ClipU14(cutoff + S8U8Mul(engine.patch_.filter_env,
modulation_sources_[MOD_SRC_ENV_1]));
@@ -977,9 +1006,21 @@ inline void Voice::RenderOscillators() {
// -1 / +1 semitones by master tuning.
base_pitch += engine.system_settings_.master_tuning;
+ const NoteStack& stack = engine.voice_controller().notes();
+ const NoteEntry& top_note = stack.most_recent_note();
+ const NoteEntry& next_note = stack.note(top_note.next_ptr);
+
// Update the oscillator parameters.
for (uint8_t i = 0; i < kNumOscillators; ++i) {
int16_t pitch = base_pitch;
+
+ // This is where we look up the list of most recently pressed notes for
+ // the duophonic mode.
+ if (engine.patch_.osc[0].option == OP_DUO && i == 1) {
+ pitch -= pitch_value_;
+ pitch += aux_pitch_;
+ }
+
// -24 / +24 semitones by the range controller.
int8_t range = 0;
if (engine.patch_.osc[i].shape != WAVEFORM_FM) {
@@ -1031,8 +1072,19 @@ inline void Voice::RenderOscillators() {
sync_state_,
buffer_);
} else {
+ uint8_t shape = engine.patch_.osc[1].shape;
+ // The sub always plays the lowest note.
+ if (engine.patch_.osc[0].option == OP_DUO) {
+ if (aux_pitch_ > 0) {
+ if (aux_pitch_ < pitch_target_) {
+ sub_osc.set_increment(U24ShiftRight(increment));
+ }
+ } else {
+ shape = 0;
+ }
+ }
osc_2.Render(
- engine.patch_.osc[1].shape,
+ shape,
midi_note,
increment,
engine.patch_.osc[0].option == OP_SYNC ? sync_state_ : no_sync_,
View
5 shruthi/synthesis_engine.h
@@ -67,6 +67,7 @@ class Voice {
// Called whenever a new note is played, manually or through the arpeggiator.
static void Trigger(uint8_t note, uint8_t velocity, uint8_t legato);
+ static void TriggerSecondNote(uint8_t note);
// Move this voice to the release stage.
static void Release();
@@ -118,6 +119,8 @@ class Voice {
static inline void ProcessModulationMatrix() __attribute__((always_inline));
static inline void UpdateDestinations() __attribute__((always_inline));
static inline void RenderOscillators() __attribute__((always_inline));
+
+ static uint16_t NoteToPitch(uint8_t note);
// Envelope generators.
static Envelope envelope_[kNumEnvelopes];
@@ -131,6 +134,7 @@ class Voice {
static int16_t pitch_increment_;
static int16_t pitch_target_;
static int16_t pitch_value_;
+ static int16_t aux_pitch_;
// The voice-specific modulation sources are from MOD_SRC_ENV_1 to
// MOD_SRC_GATE.
@@ -327,6 +331,7 @@ class SynthesisEngine : public midi::MidiDevice {
static Voice voice_;
static VoiceController controller_;
static VoiceAllocator polychaining_allocator_;
+ static VoiceAllocator duophonic_allocator_;
static uint8_t nrpn_parameter_number_;
static uint8_t nrpn_parameter_number_msb_;
static uint8_t data_entry_msb_;
View
3 shruthi/voice_controller.cc
@@ -287,6 +287,7 @@ void VoiceController::NoteOnHandlerArpStep(uint8_t note, uint8_t velocity) {
// Trigger the note.
if (sequencer_settings_->seq_mode == SEQUENCER_MODE_STEP) {
voices_[0].Trigger(note, velocity, notes_.size() > 1);
+ voices_[0].TriggerSecondNote(notes_.least_recent_note().note);
}
}
@@ -379,7 +380,7 @@ void VoiceController::NoteOffHandlerDefault(uint8_t note) {
// the one currently played.
if (sequencer_settings_->seq_mode == SEQUENCER_MODE_STEP) {
if (top_note == note) {
- voices_[0].Trigger(notes_.most_recent_note().note, 0, true);
+ voices_[0].Trigger(notes_.most_recent_note().note, 0, 1);
}
}
}
View
2 shruthi/voice_controller.h
@@ -87,6 +87,8 @@ class VoiceController {
Reset();
active_ = 1;
}
+
+ static const NoteStack& notes() { return notes_; }
private:
static void ArpeggioStep(int8_t delta);
View
2 shruthi1.size
@@ -1,2 +1,2 @@
text data bss dec hex filename
- 61194 544 3366 65104 fe50 build/shruthi1/shruthi1.elf
+ 61540 544 3368 65452 ffac build/shruthi1/shruthi1.elf

0 comments on commit 7aff2ec

Please sign in to comment.
Something went wrong with that request. Please try again.