diff --git a/examples/demo/sequencer_demo.cpp b/examples/demo/sequencer_demo.cpp index 38db39b8..bdc772b8 100644 --- a/examples/demo/sequencer_demo.cpp +++ b/examples/demo/sequencer_demo.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -55,43 +56,59 @@ 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 Note{" << 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 { + double position; + double duration; + double pitch; + Task task; + bool is_muted = false; + }; + std::vector notes; + notes.emplace_back(0.0, 1.0, barely::kPitchC4); + notes.emplace_back(1.0, 1.0, barely::kPitchD4); + notes.emplace_back(2.0, 1.0, barely::kPitchE4); + notes.emplace_back(3.0, 1.0, barely::kPitchF4); + notes.emplace_back(4.0, 1.0, barely::kPitchG4); + notes.emplace_back(5.0, 1.0 / 3.0, barely::kPitchG4); + notes.emplace_back(5 + 1.0 / 3.0, 1.0 / 3.0, barely::kPitchA4); + notes.emplace_back(5 + 2.0 / 3.0, 1.0 / 3.0, barely::kPitchB4); + notes.emplace_back(6.0, 2.0, barely::kPitchC5); + + const auto play_note_fn = [&](const Note& note) { + return [&instrument, &performer, ¬e]() { + if (!note.is_muted) { + instrument.SetNoteOn(note.pitch); + performer.ScheduleOneOffTask([&instrument, ¬e]() { instrument.SetNoteOff(note.pitch); }, + performer.GetPosition() + note.duration); + } }; }; - 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)); + ConsoleLog() << "Score:"; + for (int i = 0; i < static_cast(notes.size()); ++i) { + auto& note = notes[i]; + note.task = performer.CreateTask(play_note_fn(note), note.position); + ConsoleLog() << std::setprecision(2) << "[" << i << "]\tNote{" + << barely::MidiNumberFromPitch(note.pitch) << "} at position " << note.position + << " for " << note.duration << " beats"; } // Audio process callback. @@ -110,15 +127,10 @@ 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") << " score index [" << index + << "]"; return; } // Adjust tempo.