barelymusician/engine/sequence_test.cpp
// Tests that sequence processes a single note as expected.
Tests that sequence processes a single note as expected.
Tests that sequence processes a single note as expected .
TEST(SequenceTest, ProcessSingleNote) {
  const Id kId = 1;
  const Note::Definition kDefinition = {
      1.0, Note::PitchDefinition::AbsolutePitch(10.0)};
  const double kPosition = 5.0;
  Conductor conductor;
  Transport transport;
  transport.SetTempo(60.0);
  Sequence sequence(conductor, transport);
  EXPECT_THAT(sequence.GetInstrument(), IsNull());
  EXPECT_THAT(sequence.GetNoteDefinition(kId), IsNull());
  EXPECT_THAT(sequence.GetNotePosition(kId), IsNull());
  std::vector<double> note_on_timestamps;
  std::vector<double> note_off_timestamps;
  Instrument instrument(Instrument::Definition({}), 1);
  instrument.SetNoteOnCallback(
      [&](double pitch, double intensity, double timestamp) {
        EXPECT_DOUBLE_EQ(pitch, kDefinition.pitch.absolute_pitch);
        EXPECT_DOUBLE_EQ(intensity, kDefinition.intensity);
        note_on_timestamps.push_back(timestamp);
      });
  instrument.SetNoteOffCallback([&](double pitch, double timestamp) {
    EXPECT_DOUBLE_EQ(pitch, kDefinition.pitch.absolute_pitch);
    note_off_timestamps.push_back(timestamp);
  });
  sequence.SetInstrument(&instrument);
  EXPECT_THAT(sequence.GetInstrument(), &instrument);
  EXPECT_TRUE(sequence.CreateNote(kId, kDefinition, kPosition));
  EXPECT_THAT(
      sequence.GetNoteDefinition(kId),
      AllOf(NotNull(),
            Pointee(AllOf(
                Field(&Note::Definition::duration, 1.0),
                Field(&Note::Definition::pitch,
                      Field(&Note::PitchDefinition::absolute_pitch, 10.0)),
                Field(&Note::Definition::intensity, 1.0)))));
  EXPECT_THAT(sequence.GetNotePosition(kId),
              AllOf(NotNull(), Pointee(kPosition)));
  sequence.Process(0.0, 1.0);
  EXPECT_TRUE(note_on_timestamps.empty());
  EXPECT_TRUE(note_off_timestamps.empty());
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.Process(4.0, 5.0);
  EXPECT_TRUE(note_on_timestamps.empty());
  EXPECT_TRUE(note_off_timestamps.empty());
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.Process(5.0, 6.0);
  EXPECT_THAT(note_on_timestamps, ElementsAre(5.0));
  EXPECT_TRUE(note_off_timestamps.empty());
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.Process(4.75, 5.5);
  EXPECT_THAT(note_on_timestamps, ElementsAre(5.0));
  EXPECT_THAT(note_off_timestamps, ElementsAre(4.75));
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.Process(6.0, 7.0);
  EXPECT_TRUE(note_on_timestamps.empty());
  EXPECT_THAT(note_off_timestamps, ElementsAre(6.0));
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.SetBeginPosition(1.5);
  EXPECT_DOUBLE_EQ(sequence.GetBeginPosition(), 1.5);
  sequence.Process(6.0, 7.0);
  EXPECT_THAT(note_on_timestamps, ElementsAre(6.5));
  EXPECT_TRUE(note_off_timestamps.empty());
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.SetBeginOffset(4.0);
  EXPECT_DOUBLE_EQ(sequence.GetBeginOffset(), 4.0);
  sequence.Process(2.0, 3.0);
  EXPECT_THAT(note_on_timestamps, ElementsAre(2.5));
  EXPECT_THAT(note_off_timestamps, ElementsAre(2.0));
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.SetLooping(true);
  EXPECT_TRUE(sequence.IsLooping());
  sequence.Process(1.0, 11.0);
  EXPECT_TRUE(note_on_timestamps.empty());
  EXPECT_THAT(note_off_timestamps, ElementsAre(1.0));
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  sequence.SetLoopBeginOffset(2.0);
  EXPECT_DOUBLE_EQ(sequence.GetLoopBeginOffset(), 2.0);
  sequence.SetLoopLength(4.0);
  EXPECT_DOUBLE_EQ(sequence.GetLoopLength(), 4.0);
  sequence.SetEndPosition(11.0);
  EXPECT_DOUBLE_EQ(sequence.GetEndPosition(), 11.0);
  sequence.Process(1.5, 11.5);
  EXPECT_THAT(note_on_timestamps, ElementsAre(2.5, 6.5, 10.5));
  EXPECT_THAT(note_off_timestamps, ElementsAre(3.5, 7.5, 11.0));
  note_on_timestamps.clear();
  note_off_timestamps.clear();
  EXPECT_TRUE(sequence.DestroyNote(kId));
  EXPECT_THAT(sequence.GetNoteDefinition(kId), IsNull());
  EXPECT_THAT(sequence.GetNotePosition(kId), IsNull());
  sequence.Process(1.0, 11.0);
  EXPECT_TRUE(note_on_timestamps.empty());
  EXPECT_TRUE(note_off_timestamps.empty());
}
TEST ( SequenceTest , ProcessSingleNote ) { const Id kId = 1 ; const Note :: Definition kDefinition = { 1.0 , Note :: PitchDefinition :: AbsolutePitch ( 10.0 ) } ; const double kPosition = 5.0 ; Conductor conductor ; Transport transport ; transport . SetTempo ( 60.0 ) ; Sequence sequence ( conductor , transport ) ; EXPECT_THAT ( sequence . GetInstrument ( ) , IsNull ( ) ) ; EXPECT_THAT ( sequence . GetNoteDefinition ( kId ) , IsNull ( ) ) ; EXPECT_THAT ( sequence . GetNotePosition ( kId ) , IsNull ( ) ) ; std :: vector < double > note_on_timestamps ; std :: vector < double > note_off_timestamps ; Instrument instrument ( Instrument :: Definition ( { } ) , 1 ) ; instrument . SetNoteOnCallback ( [ & ] ( double pitch , double intensity , double timestamp ) { EXPECT_DOUBLE_EQ ( pitch , kDefinition . pitch . absolute_pitch ) ; EXPECT_DOUBLE_EQ ( intensity , kDefinition . intensity ) ; note_on_timestamps . push_back ( timestamp ) ; } ) ; instrument . SetNoteOffCallback ( [ & ] ( double pitch , double timestamp ) { EXPECT_DOUBLE_EQ ( pitch , kDefinition . pitch . absolute_pitch ) ; note_off_timestamps . push_back ( timestamp ) ; } ) ; sequence . SetInstrument ( & instrument ) ; EXPECT_THAT ( sequence . GetInstrument ( ) , & instrument ) ; EXPECT_TRUE ( sequence . CreateNote ( kId , kDefinition , kPosition ) ) ; EXPECT_THAT ( sequence . GetNoteDefinition ( kId ) , AllOf ( NotNull ( ) , Pointee ( AllOf ( Field ( & Note :: Definition :: duration , 1.0 ) , Field ( & Note :: Definition :: pitch , Field ( & Note :: PitchDefinition :: absolute_pitch , 10.0 ) ) , Field ( & Note :: Definition :: intensity , 1.0 ) ) ) ) ) ; EXPECT_THAT ( sequence . GetNotePosition ( kId ) , AllOf ( NotNull ( ) , Pointee ( kPosition ) ) ) ; sequence . Process ( 0.0 , 1.0 ) ; EXPECT_TRUE ( note_on_timestamps . empty ( ) ) ; EXPECT_TRUE ( note_off_timestamps . empty ( ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . Process ( 4.0 , 5.0 ) ; EXPECT_TRUE ( note_on_timestamps . empty ( ) ) ; EXPECT_TRUE ( note_off_timestamps . empty ( ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . Process ( 5.0 , 6.0 ) ; EXPECT_THAT ( note_on_timestamps , ElementsAre ( 5.0 ) ) ; EXPECT_TRUE ( note_off_timestamps . empty ( ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . Process ( 4.75 , 5.5 ) ; EXPECT_THAT ( note_on_timestamps , ElementsAre ( 5.0 ) ) ; EXPECT_THAT ( note_off_timestamps , ElementsAre ( 4.75 ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . Process ( 6.0 , 7.0 ) ; EXPECT_TRUE ( note_on_timestamps . empty ( ) ) ; EXPECT_THAT ( note_off_timestamps , ElementsAre ( 6.0 ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . SetBeginPosition ( 1.5 ) ; EXPECT_DOUBLE_EQ ( sequence . GetBeginPosition ( ) , 1.5 ) ; sequence . Process ( 6.0 , 7.0 ) ; EXPECT_THAT ( note_on_timestamps , ElementsAre ( 6.5 ) ) ; EXPECT_TRUE ( note_off_timestamps . empty ( ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . SetBeginOffset ( 4.0 ) ; EXPECT_DOUBLE_EQ ( sequence . GetBeginOffset ( ) , 4.0 ) ; sequence . Process ( 2.0 , 3.0 ) ; EXPECT_THAT ( note_on_timestamps , ElementsAre ( 2.5 ) ) ; EXPECT_THAT ( note_off_timestamps , ElementsAre ( 2.0 ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . SetLooping ( true ) ; EXPECT_TRUE ( sequence . IsLooping ( ) ) ; sequence . Process ( 1.0 , 11.0 ) ; EXPECT_TRUE ( note_on_timestamps . empty ( ) ) ; EXPECT_THAT ( note_off_timestamps , ElementsAre ( 1.0 ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; sequence . SetLoopBeginOffset ( 2.0 ) ; EXPECT_DOUBLE_EQ ( sequence . GetLoopBeginOffset ( ) , 2.0 ) ; sequence . SetLoopLength ( 4.0 ) ; EXPECT_DOUBLE_EQ ( sequence . GetLoopLength ( ) , 4.0 ) ; sequence . SetEndPosition ( 11.0 ) ; EXPECT_DOUBLE_EQ ( sequence . GetEndPosition ( ) , 11.0 ) ; sequence . Process ( 1.5 , 11.5 ) ; EXPECT_THAT ( note_on_timestamps , ElementsAre ( 2.5 , 6.5 , 10.5 ) ) ; EXPECT_THAT ( note_off_timestamps , ElementsAre ( 3.5 , 7.5 , 11.0 ) ) ; note_on_timestamps . clear ( ) ; note_off_timestamps . clear ( ) ; EXPECT_TRUE ( sequence . DestroyNote ( kId ) ) ; EXPECT_THAT ( sequence . GetNoteDefinition ( kId ) , IsNull ( ) ) ; EXPECT_THAT ( sequence . GetNotePosition ( kId ) , IsNull ( ) ) ; sequence . Process ( 1.0 , 11.0 ) ; EXPECT_TRUE ( note_on_timestamps . empty ( ) ) ; EXPECT_TRUE ( note_off_timestamps . empty ( ) ) ; }
Tests that sequence processes a single note as expected.
Tests that sequence processes a single note as expected .
// Set instrument. // Create note. // Process before the note position. // Process just before the note position. // Process starting with the note position. // Process overlapping the note position. // Process just after the note position. // Process after the note position, but with a begin position to compensate. // Set begin offset. // Set looping. // Set loop begin offset and length with an end position. // Destroy note.