-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathPlayer.cpp
122 lines (110 loc) · 4.16 KB
/
Player.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "Player.h"
#include "IStepMemory.h"
#define SUBSTEPS_PER_STEP 4
Player::Player(IStepMemory * memory,
PlayerSettings * settings,
StepSynchronizer * synchronizer,
void (*instrumentEventCallback)(unsigned char instrumentID, DrumStep::DrumVelocityType velocityType, bool isOn)
) : memory_(memory),
settings_(settings),
synchronizer_(synchronizer),
isStopped_(true),
inLoop_(false),
loopedStep_(6),
instrumentEventCallback_(instrumentEventCallback),
noteOffDisabledInstruments_(0)
{
for (unsigned char i = 0; i < INSTRUMENTS; i++) {
currentSteps_[i] = 0;
}
for (unsigned char i = 0 ; i < ALL_INSTRUMENTS_IN_BYTES; i++) {
playingInstruments[i] = 0;
}
}
void Player::stepFourth()
{
stepDrumInstruments();
}
void Player::update(unsigned int elapsedTimeUnits) {
if (isStopped_ && (elapsedTimeUnits - lastDummyPlayInstrumentTimeUnits_) > 20) {
resetAllInstruments();
}
lastElapsedTimeUnits_ = elapsedTimeUnits;
}
void Player::playNote(unsigned char instrumentID, DrumStep::DrumVelocityType velocityType, bool sendNoteOffBefore) {
if (sendNoteOffBefore)
sendNoteOffIfPlaying(instrumentID);
if (isStopped_) {
instrumentEventCallback_(instrumentID, velocityType, true);
setInstrumentPlaying(instrumentID, true);
lastDummyPlayInstrumentTimeUnits_ = lastElapsedTimeUnits_;
} else {
if (instrumentEventCallback_) {
instrumentEventCallback_(instrumentID, velocityType, true);
}
setInstrumentPlaying(instrumentID, true);
}
}
void Player::sendNoteOffIfPlaying(unsigned char instrumentID) {
if (isInstrumentPlaying(instrumentID) && !getBit(noteOffDisabledInstruments_, instrumentID)) {
if (instrumentEventCallback_) {
instrumentEventCallback_(instrumentID, DrumStep::OFF , false);
}
setInstrumentPlaying(instrumentID, false);
}
}
void Player::stepDrumInstruments()
{
for (unsigned char i = 0; i < 6; i++) {
DrumStep nextStep;
unsigned char nextSubStepIndex = (currentSteps_[i] + 1) % 256;
if (isStopped_ ) {
nextSubStepIndex = currentSteps_[i];
}
bool nextStepExists = true;
// when in the substep sequence dont ask for the next step otherwise ask for newxt available
if (nextSubStepIndex % 4 != 0) {
unsigned char nextStepIndex = nextSubStepIndex / 4;
//printf("calling currentStep on for %i index is %i \n", i, nextStepIndex);
nextStep = memory_->getDrumStep(i, nextStepIndex);
} else {
if (inLoop_) {
nextStep = memory_->getDrumStep(i, loopedStep_);
nextSubStepIndex = 4 * loopedStep_;
} else {
unsigned char currentStepIndex = nextSubStepIndex / 4;
//printf("calling nextStep on for %i index is %i \n", i, currentStepIndex);
nextStepExists = memory_->getNextActiveDrumStep(i, currentStepIndex, nextStep);
//if (nextStepExists) printf("NextStepExists index %i\n", currentStepIndex);
nextSubStepIndex = 4 * currentStepIndex;
}
}
bool nextStepIsOn = nextStepExists && !nextStep.isMuted() && (nextStep.getSubStep(nextSubStepIndex % 4) != DrumStep::OFF);
// In case this next step is on we do not have to send offs since we have hw
// trigger buffer and it will take care of things
if (nextStepIsOn) {
playNote(i, DrumStep::NORMAL, false);
} else {
sendNoteOffIfPlaying(i);
}
if (nextStepExists) {
currentSteps_[i] = nextSubStepIndex;
}
}
isStopped_ = false;
}
void Player::changeActivesForCurrentStep(unsigned char instrumentID, unsigned char numberOfActiveSteps) {
setCurrentInstrumentStep(instrumentID, (synchronizer_->getCurrentStepNumber() / 4) % numberOfActiveSteps);
}
void Player::changeActivesForCurrentStepInAllInstrunents(unsigned char numberOfActiveSteps) {
for (unsigned char instrument = 0; instrument < 6; instrument++) {
changeActivesForCurrentStep(instrument, numberOfActiveSteps);
}
}
void Player::resetAllInstruments() {
for (unsigned char i = 0; i < 6; i++) {
sendNoteOffIfPlaying(i);
currentSteps_[i] = 0;
}
isStopped_ = true;
}