diff --git a/examples/demo/sequencer_demo.cpp b/examples/demo/sequencer_demo.cpp index 38db39b8..e04e027c 100644 --- a/examples/demo/sequencer_demo.cpp +++ b/examples/demo/sequencer_demo.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -55,44 +56,56 @@ int main(int /*argc*/, char* /*argv*/[]) { Musician musician; musician.SetTempo(kInitialTempo); + // Create the instrument. auto instrument = musician.CreateInstrument(kFrameRate); instrument.SetControl(SynthInstrument::Control::kGain, kGain); instrument.SetControl(SynthInstrument::Control::kOscillatorType, kOscillatorType); instrument.SetControl(SynthInstrument::Control::kAttack, kAttack); instrument.SetControl(SynthInstrument::Control::kRelease, kRelease); + instrument.SetNoteOnEvent([](double pitch, double /*intensity*/) { - ConsoleLog() << "Note{" << barely::MidiNumberFromPitch(pitch) << "}"; + ConsoleLog() << "Playing {" << barely::MidiNumberFromPitch(pitch) << "}"; }); + // Create the performer. auto performer = musician.CreatePerformer(); performer.SetLooping(true); performer.SetLoopBeginPosition(3.0); performer.SetLoopLength(5.0); - const auto play_note_fn = [&](double duration, double pitch) { - return [&instrument, &performer, pitch, duration]() { - instrument.SetNoteOn(pitch); - performer.ScheduleOneOffTask([&instrument, pitch]() { instrument.SetNoteOff(pitch); }, - performer.GetPosition() + duration); - }; + // Build the score. + struct Note { + Task task; + bool is_muted = false; + }; + std::vector notes; + + ConsoleLog() << "Notes:"; + const auto create_note_fn = [&](double position, double duration, double pitch) { + const int index = static_cast(notes.size()); + ConsoleLog() << std::setprecision(2) << "[" << index << "] (" << position << ", " << duration + << ")\t{" << barely::MidiNumberFromPitch(pitch) << "}"; + + return performer.CreateTask( + [&instrument, &performer, ¬es, duration, pitch, index]() { + if (!notes[index].is_muted) { + instrument.SetNoteOn(pitch); + performer.ScheduleOneOffTask([&instrument, pitch]() { instrument.SetNoteOff(pitch); }, + performer.GetPosition() + duration); + } + }, + position); }; - std::vector> score; - score.emplace_back(0.0, play_note_fn(1.0, barely::kPitchC4)); - score.emplace_back(1.0, play_note_fn(1.0, barely::kPitchD4)); - score.emplace_back(2.0, play_note_fn(1.0, barely::kPitchE4)); - score.emplace_back(3.0, play_note_fn(1.0, barely::kPitchF4)); - score.emplace_back(4.0, play_note_fn(1.0, barely::kPitchG4)); - score.emplace_back(5.0, play_note_fn(1.0 / 3.0, barely::kPitchG4)); - score.emplace_back(5 + 1.0 / 3.0, play_note_fn(1.0 / 3.0, barely::kPitchA4)); - score.emplace_back(5 + 2.0 / 3.0, play_note_fn(1.0 / 3.0, barely::kPitchB4)); - score.emplace_back(6.0, play_note_fn(2.0, barely::kPitchC5)); - - std::unordered_map tasks; - int index = 0; - for (const auto& [position, callback] : score) { - tasks.emplace(index++, performer.CreateTask(callback, position)); - } + notes.emplace_back(create_note_fn(0.0, 1.0, barely::kPitchC4)); + notes.emplace_back(create_note_fn(1.0, 1.0, barely::kPitchD4)); + notes.emplace_back(create_note_fn(2.0, 1.0, barely::kPitchE4)); + notes.emplace_back(create_note_fn(3.0, 1.0, barely::kPitchF4)); + notes.emplace_back(create_note_fn(4.0, 1.0, barely::kPitchG4)); + notes.emplace_back(create_note_fn(5.0, 1.0 / 3.0, barely::kPitchG4)); + notes.emplace_back(create_note_fn(5 + 1.0 / 3.0, 1.0 / 3.0, barely::kPitchA4)); + notes.emplace_back(create_note_fn(5 + 2.0 / 3.0, 1.0 / 3.0, barely::kPitchB4)); + notes.emplace_back(create_note_fn(6.0, 2.0, barely::kPitchC5)); // Audio process callback. const auto process_callback = [&](double* output) { @@ -110,15 +123,9 @@ int main(int /*argc*/, char* /*argv*/[]) { return; } if (const int index = static_cast(key - '0'); index > 0 && index < 10) { - // Toggle score. - if (const auto it = tasks.find(index - 1); it != tasks.end()) { - tasks.erase(it); - ConsoleLog() << "Removed note " << index; - } else { - const auto& [position, callback] = score[index - 1]; - tasks.emplace(index - 1, performer.CreateTask(callback, position)); - ConsoleLog() << "Added note " << index; - } + // Toggle note. + notes[index].is_muted = !notes[index].is_muted; + ConsoleLog() << (notes[index].is_muted ? "Muted" : "Unmuted") << " [" << index << "]"; return; } // Adjust tempo.