barelymusician/engine/engine_test.cpp
// Tests that single instrument is created and destroyed as expected.
Tests that single instrument is created and destroyed as expected.
Tests that single instrument is created and destroyed as expected .
TEST(EngineTest, CreateDestroySingleInstrument) {
  const Id kId = 1;
  const double kPitch = -1.25;
  const double kIntensity = 0.75;
  Engine engine;
  std::vector<double> buffer(kNumChannels * kNumFrames);
  EXPECT_THAT(engine.GetInstrument(kId), IsNull());
  EXPECT_TRUE(
      engine.CreateInstrument(kId, GetTestInstrumentDefinition(), kFrameRate));
  std::fill(buffer.begin(), buffer.end(), 0.0);
  EXPECT_TRUE(engine.ProcessInstrument(kId, buffer.data(), kNumChannels,
                                       kNumFrames, 0.0));
  for (int frame = 0; frame < kNumFrames; ++frame) {
    for (int channel = 0; channel < kNumChannels; ++channel) {
      EXPECT_DOUBLE_EQ(buffer[kNumChannels * frame + channel], 0.0);
    }
  }
  auto* instrument = engine.GetInstrument(kId);
  EXPECT_THAT(instrument, NotNull());
  double note_on_pitch = 0.0;
  double note_on_intensity = 0.0;
  double note_on_timestamp = 0.0;
  instrument->SetNoteOnCallback(
      [&](double pitch, double intensity, double timestamp) {
        note_on_pitch = pitch;
        note_on_intensity = intensity;
        note_on_timestamp = timestamp;
      });
  EXPECT_NE(note_on_pitch, kPitch);
  EXPECT_NE(note_on_intensity, kIntensity);
  EXPECT_DOUBLE_EQ(note_on_timestamp, 0.0);
  double note_off_pitch = 0.0;
  double note_off_timestamp = 0.0;
  instrument->SetNoteOffCallback([&](double pitch, double timestamp) {
    note_off_pitch = pitch;
    note_off_timestamp = timestamp;
  });
  EXPECT_NE(note_off_pitch, kPitch);
  EXPECT_DOUBLE_EQ(note_off_timestamp, 0.0);
  instrument->StartNote(kPitch, kIntensity, 0.0);
  EXPECT_TRUE(instrument->IsNoteOn(kPitch));
  EXPECT_DOUBLE_EQ(note_on_pitch, kPitch);
  EXPECT_DOUBLE_EQ(note_on_intensity, kIntensity);
  EXPECT_DOUBLE_EQ(note_on_timestamp, 0.0);
  std::fill(buffer.begin(), buffer.end(), 0.0);
  EXPECT_TRUE(engine.ProcessInstrument(kId, buffer.data(), kNumChannels,
                                       kNumFrames, 0.0));
  for (int frame = 0; frame < kNumFrames; ++frame) {
    for (int channel = 0; channel < kNumChannels; ++channel) {
      EXPECT_DOUBLE_EQ(buffer[kNumChannels * frame + channel],
                       kPitch * kIntensity);
    }
  }
  engine.Update(5.0);
  EXPECT_TRUE(engine.DestroyInstrument(kId));
  EXPECT_THAT(engine.GetInstrument(kId), IsNull());
  EXPECT_DOUBLE_EQ(note_off_pitch, kPitch);
  EXPECT_DOUBLE_EQ(note_off_timestamp, 5.0);
  std::fill(buffer.begin(), buffer.end(), 0.0);
  EXPECT_FALSE(engine.ProcessInstrument(kId, buffer.data(), kNumChannels,
                                        kNumFrames, 0.0));
  for (int frame = 0; frame < kNumFrames; ++frame) {
    for (int channel = 0; channel < kNumChannels; ++channel) {
      EXPECT_DOUBLE_EQ(buffer[kNumChannels * frame + channel], 0.0);
    }
  }
}
TEST ( EngineTest , CreateDestroySingleInstrument ) { const Id kId = 1 ; const double kPitch = -1.25 ; const double kIntensity = 0.75 ; Engine engine ; std :: vector < double > buffer ( kNumChannels * kNumFrames ) ; EXPECT_THAT ( engine . GetInstrument ( kId ) , IsNull ( ) ) ; EXPECT_TRUE ( engine . CreateInstrument ( kId , GetTestInstrumentDefinition ( ) , kFrameRate ) ) ; std :: fill ( buffer . begin ( ) , buffer . end ( ) , 0.0 ) ; EXPECT_TRUE ( engine . ProcessInstrument ( kId , buffer . data ( ) , kNumChannels , kNumFrames , 0.0 ) ) ; for ( int frame = 0 ; frame < kNumFrames ; ++ frame ) { for ( int channel = 0 ; channel < kNumChannels ; ++ channel ) { EXPECT_DOUBLE_EQ ( buffer [ kNumChannels * frame + channel ] , 0.0 ) ; } } auto * instrument = engine . GetInstrument ( kId ) ; EXPECT_THAT ( instrument , NotNull ( ) ) ; double note_on_pitch = 0.0 ; double note_on_intensity = 0.0 ; double note_on_timestamp = 0.0 ; instrument -> SetNoteOnCallback ( [ & ] ( double pitch , double intensity , double timestamp ) { note_on_pitch = pitch ; note_on_intensity = intensity ; note_on_timestamp = timestamp ; } ) ; EXPECT_NE ( note_on_pitch , kPitch ) ; EXPECT_NE ( note_on_intensity , kIntensity ) ; EXPECT_DOUBLE_EQ ( note_on_timestamp , 0.0 ) ; double note_off_pitch = 0.0 ; double note_off_timestamp = 0.0 ; instrument -> SetNoteOffCallback ( [ & ] ( double pitch , double timestamp ) { note_off_pitch = pitch ; note_off_timestamp = timestamp ; } ) ; EXPECT_NE ( note_off_pitch , kPitch ) ; EXPECT_DOUBLE_EQ ( note_off_timestamp , 0.0 ) ; instrument -> StartNote ( kPitch , kIntensity , 0.0 ) ; EXPECT_TRUE ( instrument -> IsNoteOn ( kPitch ) ) ; EXPECT_DOUBLE_EQ ( note_on_pitch , kPitch ) ; EXPECT_DOUBLE_EQ ( note_on_intensity , kIntensity ) ; EXPECT_DOUBLE_EQ ( note_on_timestamp , 0.0 ) ; std :: fill ( buffer . begin ( ) , buffer . end ( ) , 0.0 ) ; EXPECT_TRUE ( engine . ProcessInstrument ( kId , buffer . data ( ) , kNumChannels , kNumFrames , 0.0 ) ) ; for ( int frame = 0 ; frame < kNumFrames ; ++ frame ) { for ( int channel = 0 ; channel < kNumChannels ; ++ channel ) { EXPECT_DOUBLE_EQ ( buffer [ kNumChannels * frame + channel ] , kPitch * kIntensity ) ; } } engine . Update ( 5.0 ) ; EXPECT_TRUE ( engine . DestroyInstrument ( kId ) ) ; EXPECT_THAT ( engine . GetInstrument ( kId ) , IsNull ( ) ) ; EXPECT_DOUBLE_EQ ( note_off_pitch , kPitch ) ; EXPECT_DOUBLE_EQ ( note_off_timestamp , 5.0 ) ; std :: fill ( buffer . begin ( ) , buffer . end ( ) , 0.0 ) ; EXPECT_FALSE ( engine . ProcessInstrument ( kId , buffer . data ( ) , kNumChannels , kNumFrames , 0.0 ) ) ; for ( int frame = 0 ; frame < kNumFrames ; ++ frame ) { for ( int channel = 0 ; channel < kNumChannels ; ++ channel ) { EXPECT_DOUBLE_EQ ( buffer [ kNumChannels * frame + channel ] , 0.0 ) ; } } }
Tests that single instrument is created and destroyed as expected.
Tests that single instrument is created and destroyed as expected .
// Create instrument. // Get instrument. // Set note callbacks. // Start note. // Update timestamp. // Destroy instrument, which should also trigger note off callback.