...
  View open merge request
Commits (10)
......@@ -51,10 +51,13 @@ test:
- build-test
script:
- ninja -C buildDir test
- ninja -C buildDir coverage
- gcovr -b -e buildDir/loopp@exe/catch.hpp -e buildDir/loopp@exe/test_ <&1 | tee buildDir/coverage.txt
artifacts:
paths:
- buildDir/coverage.txt
- buildDir/meson-logs/coveragereport
- buildDir/meson-logs/coverage.txt
reports:
junit: buildDir/junit.xml
coverage: '/^TOTAL.*\s+(\d+\%)$/'
......
......@@ -18,6 +18,10 @@ cpp = meson.get_compiler('cpp')
loopp_src = []
subdir('src')
if get_option('unitTests')
message('Create build config for unit tests')
subdir('tests')
endif
dep_names = [
'ntk',
......
......@@ -26,9 +26,9 @@
#include "../config.hxx"
#include "../looper.hxx"
#include "../looper/looper.hxx"
#include "../gridlogic.hxx"
#include "../audiobuffer.hxx"
#include "../looper/audiobuffer.hxx"
#include "../eventhandler.hxx"
using namespace std;
......
......@@ -22,8 +22,8 @@
#include <string>
#include "../jack.hxx"
#include "../looper.hxx"
#include "../looperclip.hxx"
#include "../looper/looper.hxx"
#include "../looper/looperclip.hxx"
NonSeq::NonSeq() :
Controller(),
......
......@@ -28,7 +28,7 @@
#include "config.hxx"
#include "gui.hxx"
#include "event.hxx"
#include "audiobuffer.hxx"
#include "looper/audiobuffer.hxx"
#include "eventhandler.hxx"
#include "gmastertrack.hxx"
......
......@@ -28,7 +28,7 @@
This file provides declarations for each type of event that the engine uses.
*/
#include "looper.hxx"
#include "looper/looper.hxx"
#include "gridlogic.hxx"
#include "transport.hxx"
......
......@@ -28,7 +28,7 @@
// Internal
#include "gui.hxx"
#include "event.hxx"
#include "audiobuffer.hxx"
#include "looper/audiobuffer.hxx"
#include "eventhandler.hxx"
#include "controller/controller.hxx"
......
......@@ -25,7 +25,7 @@
#include "gui.hxx"
extern Gui* gui;
#include "audiobuffer.hxx"
#include "looper/audiobuffer.hxx"
#include "avtk/waveform.h"
#include "avtk/avtk_button.h"
......
......@@ -38,7 +38,7 @@
#include "avtk/clipselector.hxx"
#include "config.hxx"
#include "audiobuffer.hxx"
#include "looper/audiobuffer.hxx"
#include "eventhandler.hxx"
using namespace std;
......
......@@ -29,7 +29,7 @@
#include "jack.hxx"
extern Jack* jack;
#include "audiobuffer.hxx"
#include "looper/audiobuffer.hxx"
#include "controller/nonseq.hxx"
#include "controller/genericmidi.hxx"
......
......@@ -27,7 +27,7 @@
#include "gui.hxx"
#include "logic.hxx"
#include "config.hxx"
#include "looper.hxx"
#include "looper/looper.hxx"
#include "metronome.hxx"
#include "gridlogic.hxx"
#include "trackoutput.hxx"
......@@ -37,7 +37,8 @@
#include "dsp/dsp_reverb.hxx"
#include "dsp/dsp_dbmeter.hxx"
#include "audiobuffer.hxx"
#include "looper/audiobuffer.hxx"
#include "looper/looperfactory.hxx"
#include "eventhandler.hxx"
#include "controller/genericmidi.hxx"
#include "controller/guicontroller.hxx"
......@@ -235,7 +236,7 @@ Jack::Jack( std::string name ) :
* or the track's Looper instance.
* This is an option in loopp.prfs
**/
loopers.push_back( new Looper(track) );
loopers.push_back( LooperFactory::buildLooper(track) );
tracksendreturns.push_back(new JackSendReturn(track,loopers.back(),client));
trackOutputs.push_back( new TrackOutput(track, tracksendreturns.back() ) );
......
......@@ -17,7 +17,7 @@
*/
#include "audiobuffer.hxx"
#include "config.hxx"
#include "../config.hxx"
#include <stdio.h>
......
......@@ -19,7 +19,7 @@
#include "looper.hxx"
#include "config.hxx"
#include "../config.hxx"
#include <cmath>
......@@ -27,15 +27,15 @@
#include <iomanip>
#endif
#include "jack.hxx"
#include "../jack.hxx"
#include "audiobuffer.hxx"
#include "eventhandler.hxx"
#include "controllerupdater.hxx"
#include "timemanager.hxx"
#include "../eventhandler.hxx"
#include "../controllerupdater.hxx"
#include "../timemanager.hxx"
extern Jack* jack;
Looper::Looper(int t) :
Looper::Looper(int t, LooperClip **c) :
AudioProcessor(),
TimeObserver(),
track(t)
......@@ -48,7 +48,7 @@ Looper::Looper(int t) :
//memset( tmpRecordBuffer, 0, sizeof(float) * MAX_BUFFER_SIZE );
for(int i = 0; i < NSCENES; i++ ) {
clips[i] = new LooperClip(track, i);
clips[i] = c[i];
}
tmpBuffer.resize( MAX_BUFFER_SIZE );
......
......@@ -22,12 +22,12 @@
#include <vector>
#include <iostream>
#include "buffers.hxx"
#include "../buffers.hxx"
#include "audioprocessor.hxx"
#include "../audioprocessor.hxx"
#include "looperclip.hxx"
#include "observer/time.hxx"
#include "../observer/time.hxx"
using namespace std;
......@@ -38,7 +38,7 @@ using namespace std;
class Looper : public AudioProcessor, public TimeObserver
{
public:
Looper(int t);
Looper ( int t, LooperClip **c );
/// *sets* the new audiobuffer, but the content gets copied to the new buffer.
/// Used for infinite lenght recording
......
......@@ -19,26 +19,24 @@
#include "looperclip.hxx"
#include <stdio.h>
#include "config.hxx"
#include "jack.hxx"
#include "event.hxx"
#include "eventhandler.hxx"
#include "../config.hxx"
#include "../jack.hxx"
#include "../event.hxx"
#include "../eventhandler.hxx"
#include "audiobuffer.hxx"
#include "controllerupdater.hxx"
#include "timemanager.hxx"
#include "../controllerupdater.hxx"
#include "../timemanager.hxx"
#include <math.h>
extern Jack* jack;
LooperClip::LooperClip(int t, int s) :
LooperClip::LooperClip(int t, int s, AudioBuffer *b, Jack *j) :
Stately(),
track(t),
scene(s),
TimeObserver()
TimeObserver(),
_jack(j)
{
_buffer = new AudioBuffer(LOOPER_SAMPLES_UPDATE_SIZE);
_buffer = b;
init();
#ifdef DEBUG_BUFFER
......@@ -69,8 +67,8 @@ void LooperClip::init()
resetPlayHead();
jack->getControllerUpdater()->setSceneState(track, scene, getState());
jack->getControllerUpdater()->setTrackSceneProgress(
_jack->getControllerUpdater()->setSceneState(track, scene, getState());
_jack->getControllerUpdater()->setTrackSceneProgress(
track, scene, getProgress());
}
......@@ -182,7 +180,7 @@ void LooperClip::resetPlayHead()
_playbackSpeedChange = false;
}
jack->getControllerUpdater()->setTrackSceneProgress(
_jack->getControllerUpdater()->setTrackSceneProgress(
track, scene, getProgress());
}
}
......@@ -219,8 +217,8 @@ void LooperClip::record(int count, float* L, float* R)
}
_loaded = true;
if(!jack->getFreeRecMode()) {
_recFpb = jack->getTimeManager()->getFpb();
if(!_jack->getFreeRecMode()) {
_recFpb = _jack->getTimeManager()->getFpb();
}
}
......@@ -273,7 +271,7 @@ LooperClip::bar()
if(_playing) {
_barsPlayed++;
}
if(_recording && !jack->getFreeRecMode()) {
if(_recording && !_jack->getFreeRecMode()) {
_barsRecorded++;
}
......@@ -285,15 +283,15 @@ LooperClip::bar()
setRecording();
}
if(_recording && jack->getClipLength() > 0 &&
_barsRecorded == jack->getClipLength() - 1) {
if(_recording && _jack->getClipLength() > 0 &&
_barsRecorded == _jack->getClipLength() - 1) {
queuePlay();
}
if(_recording && !jack->getFreeRecMode()) {
if(_recording && !_jack->getFreeRecMode()) {
// FIXME: assumes 4 beats in a bar
_buffer->setBeats(_buffer->getBeats() + 4);
_buffer->setAudioFrames(
jack->getTimeManager()->getFpb() * _buffer->getBeats());
_jack->getTimeManager()->getFpb() * _buffer->getBeats());
}
}
......@@ -331,7 +329,7 @@ void LooperClip::queuePlay()
_queueStop = false;
_queueRecord = false;
}
jack->getControllerUpdater()->setSceneState(track, scene, getState());
_jack->getControllerUpdater()->setSceneState(track, scene, getState());
}
void LooperClip::queueStop()
......@@ -342,7 +340,7 @@ void LooperClip::queueStop()
_queueStop = true;
_queueRecord = false;
}
jack->getControllerUpdater()->setSceneState(track, scene, getState());
_jack->getControllerUpdater()->setSceneState(track, scene, getState());
}
void LooperClip::queueRecord()
......@@ -353,7 +351,7 @@ void LooperClip::queueRecord()
_queueStop = false;
_queueRecord = true;
}
jack->getControllerUpdater()->setSceneState(track, scene, getState());
_jack->getControllerUpdater()->setSceneState(track, scene, getState());
}
void LooperClip::setRecording()
......@@ -370,7 +368,7 @@ void LooperClip::setRecording()
_buffer->setBeats( 0 );
}
jack->getControllerUpdater()->setSceneState(track, scene, getState());
_jack->getControllerUpdater()->setSceneState(track, scene, getState());
}
void LooperClip::setPlaying()
......@@ -385,7 +383,7 @@ void LooperClip::setPlaying()
} else {
resetQueues();
}
jack->getControllerUpdater()->setSceneState(track, scene, getState());
_jack->getControllerUpdater()->setSceneState(track, scene, getState());
}
void LooperClip::setStopped()
......@@ -399,7 +397,7 @@ void LooperClip::setStopped()
resetPlayHead();
// set "progress" to zero, as we're stopped!
jack->getControllerUpdater()->setSceneState(
_jack->getControllerUpdater()->setSceneState(
track, scene, getState());
}
......@@ -505,7 +503,7 @@ float LooperClip::getPlayhead()
void LooperClip::processFreeRec() {
setStopped();
int max_beats =
(MAX_TEMPO * _recordhead) / (jack->getSamplerate() * 60);
(MAX_TEMPO * _recordhead) / (_jack->getSamplerate() * 60);
// calculate lower multiple of 4
int beats = (int)(max_beats/4)*4; // TODO 4 beats/bar
if (beats < 1)
......@@ -515,11 +513,11 @@ void LooperClip::processFreeRec() {
_recordhead);
_barsRecorded = beats / 4; // TODO 4 beats/bar
_recFpb = _recordhead / beats;
jack->getTimeManager()->setFpb(_recFpb);
jack->getTimeManager()->setTransportState(TRANSPORT_ROLLING);
_jack->getTimeManager()->setFpb(_recFpb);
_jack->getTimeManager()->setTransportState(TRANSPORT_ROLLING);
queuePlay();
jack->setFreeRecMode(false);
_jack->setFreeRecMode(false);
}
#ifdef BUILD_TESTS
......
......@@ -20,9 +20,10 @@
#define LOOPP_LOOPER_CLIP_H
#include <stdio.h>
#include "state/stately.hxx"
#include "config.hxx"
#include "gridlogic.hxx"
#include "../state/stately.hxx"
#include "../config.hxx"
#include "../gridlogic.hxx"
#include "../jack.hxx"
class AudioBuffer;
......@@ -47,7 +48,7 @@ class AudioBuffer;
class LooperClip : public Stately, public TimeObserver
{
public:
LooperClip(int track, int scene);
LooperClip(int track, int scene, AudioBuffer *b, Jack *j);
/// Set everything up
void init();
......@@ -138,6 +139,8 @@ public:
private:
int track, scene;
Jack *_jack;
/** Loopp needs more than the current state of the clip to accuratly handle
* it. The current state of the grid is kept up-to-date by GridLogic
* abstracting detail away, sending GridLogic::State to Controllers.
......
#include "looperfactory.hxx"
#include "looper.hxx"
#include "looperclip.hxx"
#include "audiobuffer.hxx"
#include "../jack.hxx"
extern Jack* jack;
Looper *LooperFactory::buildLooper ( int t) {
LooperClip *clips[NSCENES];
for ( int i = 0; i < NSCENES; i++ ) {
clips[i] = LooperFactory::buildLooperClip(t, i);
}
return new Looper ( t, clips );
}
LooperClip *LooperFactory::buildLooperClip ( int t, int s ) {
AudioBuffer *buffer = new AudioBuffer ( LOOPER_SAMPLES_UPDATE_SIZE );
return new LooperClip ( t, s, buffer, jack );
}
\ No newline at end of file
#include "looper.hxx"
class LooperFactory {
public:
static Looper *buildLooper ( int t );
static LooperClip *buildLooperClip ( int t, int s );
};
\ No newline at end of file
if not get_option('unitTests')
message('Create build config for publishing')
loopp_src += files(
'audiobuffer.cxx',
'looperclip.cxx',
'looper.cxx',
'looperfactory.cxx'
)
if get_option('tests')
message('Built with Diskwriter Tests')
subdir('tests')
endif
endif
if get_option('unitTests')
message('Create build config for unit tests')
subdir('unitTests')
endif
\ No newline at end of file
......@@ -7,7 +7,6 @@ version_hxx = vcs_tag(
if not get_option('unitTests')
message('Create build config for publishing')
loopp_src = files(
'audiobuffer.cxx',
'controllerupdater.cxx',
'debug.cxx',
'diskreader.cxx',
......@@ -24,14 +23,13 @@ if not get_option('unitTests')
'jack.cxx',
'jacksendreturn.cxx',
'logic.cxx',
'looperclip.cxx',
'looper.cxx',
'main.cxx',
'metronome.cxx',
'timemanager.cxx',
'trackoutput.cxx'
)
subdir('looper')
subdir('cjson')
subdir('dsp')
subdir('controller')
......@@ -43,9 +41,4 @@ if not get_option('unitTests')
message('Built with Diskwriter Tests')
subdir('tests')
endif
endif
if get_option('unitTests')
message('Create build config for unit tests')
subdir('unitTests')
endif
\ No newline at end of file
loopp_src = files(
'test_audiobuffer.cxx',
'test_entrypoint.cxx',
'test_debug.cxx',
'../audiobuffer.cxx')
#include "catch.hpp"
#include "test_debug.hxx"
#include "../audiobuffer.hxx"
extern OUTPUT output;
int AudioBuffer::privateID = 0;
TEST_CASE("AudioBuffer Tests")
{
AudioBuffer *ab_sizeless = new AudioBuffer();
AudioBuffer *ab_size = new AudioBuffer(1000);
SECTION("Test correct initial state")
{
REQUIRE(ab_size->getBeats() == 0);
REQUIRE(ab_size->getAudioFrames() == 0);
REQUIRE(ab_size->getSize() == 1000);
REQUIRE(ab_sizeless->getBeats() == 0);
REQUIRE(ab_sizeless->getAudioFrames() == 0);
REQUIRE(ab_sizeless->getSize() == 0);
}
SECTION("Test ID changes")
{
ab_size->setID(500);
REQUIRE(ab_size->getID() == 500);
ab_sizeless->setID(501);
REQUIRE(ab_sizeless->getID() == 501);
}
SECTION("Test name changes")
{
ab_size->setName("abcdef");
REQUIRE(ab_size->getName() == "abcdef");
ab_size->setName("Lorem ipsum dolor sit amet");
REQUIRE(ab_size->getName() == "Lorem ipsum dolor si");
}
SECTION("Test beat num changes") {
ab_size->setBeats(5);
REQUIRE(ab_size->getBeats() == 5);
}
SECTION("Test audio frames change") {
ab_size->setAudioFrames(900);
REQUIRE(ab_size->getAudioFrames() == 900);
// Set AudioFrames higher than size
REQUIRE(ab_size->setAudioFrames(1500) == false);
REQUIRE(ab_size->getAudioFrames() == 900);
}
SECTION("Test Set Audio Buffer with different Length") {
std::vector<float> tempL;
for(int i = 0; i < 500; i++) {
tempL.push_back(rand());
}
std::vector<float> tempR;
for(int i = 0; i < 900; i++) {
tempR.push_back(rand());
}
std::vector<float> argL = tempL;
std::vector<float> argR = tempR;
ab_size->nonRtSetSample(argL, argR);
REQUIRE(ab_size->getSize() == 500);
REQUIRE(strcmp(output.format,
"left and right channels of audio buffer have different size: %i vs %i") == 0);
REQUIRE(output.warnLevel == 1);
REQUIRE(ab_size->getDataL() == tempL);
REQUIRE(ab_size->getDataR() == tempR);
output.reset();
}
}
\ No newline at end of file
#include "../catch.hpp"
#include "../test_debug.hxx"
#include "../../src/looper/audiobuffer.hxx"
extern OUTPUT output;
int AudioBuffer::privateID = 0;
TEST_CASE ( "AudioBuffer Tests" ) {
AudioBuffer *ab_sizeless = new AudioBuffer ();
AudioBuffer *ab_size = new AudioBuffer ( 1000 );
SECTION ( "Test memory allocation error" ) {
REQUIRE_THROWS_AS(AudioBuffer ( 1000000000000 ), std::bad_alloc);
}
SECTION ( "Test correct initial state" ) {
REQUIRE ( ab_size->getBeats () == 0 );
REQUIRE ( ab_size->getAudioFrames () == 0 );
REQUIRE ( ab_size->getSize () == 1000 );
REQUIRE ( ab_sizeless->getBeats () == 0 );
REQUIRE ( ab_sizeless->getAudioFrames () == 0 );
REQUIRE ( ab_sizeless->getSize () == 0 );
}
SECTION ( "Test ID changes" ) {
ab_size->setID ( 500 );
REQUIRE ( ab_size->getID () == 500 );
ab_sizeless->setID ( 501 );
REQUIRE ( ab_sizeless->getID () == 501 );
}
SECTION ( "Test name changes" ) {
ab_size->setName ( "abcdef" );
REQUIRE ( ab_size->getName () == "abcdef" );
ab_size->setName ( "Lorem ipsum dolor sit amet" );
REQUIRE ( ab_size->getName () == "Lorem ipsum dolor si" );
}
SECTION ( "Test beat num changes" ) {
ab_size->setBeats ( 5 );
REQUIRE ( ab_size->getBeats () == 5 );
}
SECTION ( "Test audio frames change" ) {
ab_size->setAudioFrames ( 900 );
REQUIRE ( ab_size->getAudioFrames () == 900 );
// Set AudioFrames higher than size
REQUIRE ( ab_size->setAudioFrames ( 1500 ) == false );
REQUIRE ( ab_size->getAudioFrames () == 900 );
}
SECTION ( "Test Set Audio Buffer with different Length" ) {
std::vector<float> tempL;
for ( int i = 0; i < 500; i++ ) {
tempL.push_back ( rand () );
}
std::vector<float> tempR;
for ( int i = 0; i < 900; i++ ) {
tempR.push_back ( rand () );
}
std::vector<float> argL = tempL;
std::vector<float> argR = tempR;
ab_size->nonRtSetSample ( argL, argR );
REQUIRE ( ab_size->getSize () == 500 );
REQUIRE (
strcmp ( output.format,
"left and right channels of audio buffer have different size: %i vs %i" ) ==
0 );
REQUIRE ( output.warnLevel == 1 );
REQUIRE ( ab_size->getDataL () == tempL );
REQUIRE ( ab_size->getDataR () == tempR );
output.reset ();
}
}
\ No newline at end of file
#include "../catch.hpp"
#include "../test_debug.hxx"
#include "../../src/looper/audiobuffer.hxx"
#include "../../src/looper/looperclip.hxx"
#include "../../src/jack.hxx"
extern OUTPUT output;
Jack* jack = nullptr;
TEST_CASE("Looperclip State Tests")
{
// AudioBuffer *ab_sizeless = new AudioBuffer ();
AudioBuffer *ab = new AudioBuffer(1000);
LooperClip *lc = new LooperClip(0, 0, ab);
SECTION("Test Looperclip initialisation")
{
// REQUIRE_THROWS_AS(AudioBuffer ( 1000000000000 ), std::bad_alloc);
REQUIRE(lc->playing() == false);
REQUIRE(lc->getLoaded() == false);
REQUIRE(lc->recording() == false);
REQUIRE(lc->getQueuePlay() == false);
REQUIRE(lc->getQueueStop() == false);
REQUIRE(lc->getState() == GridLogic::State::STATE_EMPTY);
}
// SECTION ( "Test correct initial state" ) {
// REQUIRE ( ab_size->getBeats () == 0 );
// REQUIRE ( ab_size->getAudioFrames () == 0 );
// REQUIRE ( ab_size->getSize () == 1000 );
// REQUIRE ( ab_sizeless->getBeats () == 0 );
// REQUIRE ( ab_sizeless->getAudioFrames () == 0 );
// REQUIRE ( ab_sizeless->getSize () == 0 );
// }
// SECTION ( "Test ID changes" ) {
// ab_size->setID ( 500 );
// REQUIRE ( ab_size->getID () == 500 );
// ab_sizeless->setID ( 501 );
// REQUIRE ( ab_sizeless->getID () == 501 );
// }
// SECTION ( "Test name changes" ) {
// ab_size->setName ( "abcdef" );
// REQUIRE ( ab_size->getName () == "abcdef" );
// ab_size->setName ( "Lorem ipsum dolor sit amet" );
// REQUIRE ( ab_size->getName () == "Lorem ipsum dolor si" );
// }
// SECTION ( "Test beat num changes" ) {
// ab_size->setBeats ( 5 );
// REQUIRE ( ab_size->getBeats () == 5 );
// }
// SECTION ( "Test audio frames change" ) {
// ab_size->setAudioFrames ( 900 );
// REQUIRE ( ab_size->getAudioFrames () == 900 );
// // Set AudioFrames higher than size
// REQUIRE ( ab_size->setAudioFrames ( 1500 ) == false );
// REQUIRE ( ab_size->getAudioFrames () == 900 );
// }
// SECTION ( "Test Set Audio Buffer with different Length" ) {
// std::vector<float> tempL;
// for ( int i = 0; i < 500; i++ ) {
// tempL.push_back ( rand () );
// }
// std::vector<float> tempR;
// for ( int i = 0; i < 900; i++ ) {
// tempR.push_back ( rand () );
// }
// std::vector<float> argL = tempL;
// std::vector<float> argR = tempR;
// ab_size->nonRtSetSample ( argL, argR );
// REQUIRE ( ab_size->getSize () == 500 );
// REQUIRE (
// strcmp ( output.format,
// "left and right channels of audio buffer have different size: %i vs %i" ) ==
// 0 );
// REQUIRE ( output.warnLevel == 1 );
// REQUIRE ( ab_size->getDataL () == tempL );
// REQUIRE ( ab_size->getDataR () == tempR );
// output.reset ();
// }
}
\ No newline at end of file
loopp_src = files(
'looper/test_audiobuffer.cxx',
'test_entrypoint.cxx',
'test_debug.cxx',
'../src/looper/audiobuffer.cxx',
'looper/test_looperclip.cxx',
'../src/looper/looperclip.cxx',
'../src/state/stately.cxx',
'../src/observer/time.cxx',
'../src/jack.cxx',
'../src/controllerupdater.cxx')