TEST( BaseAudioEvent, MixBufferLoopeableEvent ) { BaseAudioEvent* audioEvent = new BaseAudioEvent(); int sourceSize = 16; AudioBuffer* sourceBuffer = new AudioBuffer( 1, sourceSize ); SAMPLE_TYPE* rawBuffer = sourceBuffer->getBufferForChannel( 0 ); fillAudioBuffer( sourceBuffer ); audioEvent->setBuffer( sourceBuffer, false ); audioEvent->setLoopeable( true ); audioEvent->setSampleLength( 16 * 4 ); // thus will loop 4 times audioEvent->positionEvent ( 0, 16, 0 ); // create an output buffer at a size smaller than the source buffer length int outputSize = ( int )(( double ) sourceSize * .4 ); AudioBuffer* targetBuffer = new AudioBuffer( sourceBuffer->amountOfChannels, outputSize ); int minBufferPos = audioEvent->getSampleStart(); int bufferPos = minBufferPos; int maxBufferPos = audioEvent->getSampleEnd(); // test the seamless mixing over multiple iterations for ( ; bufferPos < maxBufferPos; bufferPos += outputSize ) { // mix buffer contents targetBuffer->silenceBuffers(); bool loopStarted = bufferPos + ( outputSize - 1 ) > maxBufferPos; int loopOffset = ( maxBufferPos - bufferPos ) + 1; audioEvent->mixBuffer( targetBuffer, bufferPos, minBufferPos, maxBufferPos, loopStarted, loopOffset, false ); // assert results SAMPLE_TYPE* mixedBuffer = targetBuffer->getBufferForChannel( 0 ); for ( int i = 0; i < outputSize; ++i ) { int compareOffset = ( bufferPos + i ) % sourceSize; EXPECT_EQ( rawBuffer[ compareOffset ], mixedBuffer[ i ] ) << "expected mixed buffer contents to equal the source contents at mixed offset " << i << " for source offset " << compareOffset; } } delete targetBuffer; delete sourceBuffer; delete audioEvent; }
TEST( BaseAudioEvent, PositionEvent ) { BaseAudioEvent* audioEvent = new BaseAudioEvent(); AudioEngine::samples_per_bar = randomInt( 11025, 88200 ); int sampleLength = randomInt( 24, 8192 ); audioEvent->setSampleLength( sampleLength ); int startMeasure = randomInt( 0, 15 ); int subdivisions = randomInt( 4, 128 ); int offset = randomInt( 0, 64 ); audioEvent->positionEvent( startMeasure, subdivisions, offset ); int expectedSampleStart = ( startMeasure * AudioEngine::samples_per_bar ) + ( offset * AudioEngine::samples_per_bar / subdivisions ); int expectedSampleEnd = expectedSampleStart + sampleLength - 1; EXPECT_EQ( expectedSampleStart, audioEvent->getSampleStart() ); EXPECT_EQ( expectedSampleEnd, audioEvent->getSampleEnd() ); deleteAudioEvent( audioEvent ); }
TEST( AudioEngine, Output ) { AudioEngine::test_program = 2; // help mocked OpenSL IO identify which test is running AudioEngine::test_successful = false; // prepare engine environment SequencerController* controller = new SequencerController(); controller->prepare( 16, 48000, 130.0f, 4, 4 ); // 130 BPM in 4/4 time at 48 kHz sample rate w/buffer size of 16 samples controller->setTempoNow( 130.0f, 4, 4 ); controller->rewind(); AudioEngine::volume = 1; // QQQ : later on we test mix volume ;) // create an AudioEvent that holds a simple waveform // the resulting 16 sample mono buffer contains the following samples: // // -1,-1,-1,-1,0,0,0,0,1,1,1,1,0,0,0,0 // // the event will last for an entire measure in duration BaseInstrument* instrument = new BaseInstrument(); BaseAudioEvent* event = new BaseAudioEvent( instrument ); AudioBuffer* buffer = new AudioBuffer( 1, 16 ); SAMPLE_TYPE* rawBuffer = buffer->getBufferForChannel( 0 ); for ( int i = 0; i < 4; ++i ) rawBuffer[ i ] = ( SAMPLE_TYPE ) -MAX_PHASE; for ( int i = 4; i < 8; ++i ) rawBuffer[ i ] = ( SAMPLE_TYPE ) 0; for ( int i = 8; i < 12; ++i ) rawBuffer[ i ] = ( SAMPLE_TYPE ) MAX_PHASE; for ( int i = 12; i < 16; ++i ) rawBuffer[ i ] = ( SAMPLE_TYPE ) 0; event->setBuffer( buffer, false ); event->setLoopeable( true ); event->setSampleLength( AudioEngine::samples_per_bar ); event->positionEvent( 0, 16, 0 ); event->addToSequencer(); // start the engine controller->setPlaying( true ); AudioEngine::start(); // evaluate results (assertions are made in mock_opensl_io.cpp) ASSERT_TRUE( AudioEngine::test_successful ) << "expected test to be successful"; EXPECT_EQ( 3, AudioEngine::test_program ) << "expected test program to have incremented"; // clean up controller->setPlaying( false ); AudioEngine::render_iterations = 0; delete controller; delete instrument; delete event; delete buffer; }