/
Instrument.cpp
95 lines (82 loc) · 2.45 KB
/
Instrument.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
//Peter Miller
//5-19-2016
#include "Instrument.h"
#include "Note.h"
#include <iostream>
using namespace std;
//This defines the main virtual instrument class as well as its derivatives
//Strings
//Violin
violin::violin( int l) : instrument(l){
ID = 41;
voice = 0;
numChannels = 1;
channels[0] = channel(l, 55, 103, 0);
}
//Viola
viola::viola( int l) : instrument(l){
ID = 42;
voice = 1;
numChannels = 1;
channels[0] = channel(l, 48, 91, 0);
}
//Cello
cello::cello( int l) : instrument(l){
ID = 43;
voice = 1;
numChannels = 1;
channels[0] = channel(l, 36, 76, 0);
}
//Bass
stringBass::stringBass( int l) : instrument(l){
ID = 44;
voice = 1;
numChannels = 1;
channels[0] = channel(l, 28, 67, 0);
}
instrument::~instrument(){}; //Destructor
instrument::instrument(int l){
length = l; //Sets the length of the song
}
//Allows the addition of a note to the instruments tracks
void instrument::addNote(int n, int t, int l, int v, int c){
channels[c].addNote(n, t, l, v);
}
//Outputs the instrument's track, which can be put into a file stream
ostream& operator<<(ostream &output, const instrument &ins ){
delay d(ins.minNoteLength); //Delay is used to keep track of location in MIDI file
string temp = ""; //String holds the eventual output
//Set Instrument Voice
for(int i=0; i<ins.numChannels; i++){
//Set at time of zero
temp+=char(0);
//First half-byte is change voice
//Second half-byte is channel number
int s = 0xC0+i;
temp += char(s);
//Sets to correct voice
temp += char(ins.ID);
}
//Populate with notes
//Goes through each moment and lets any notes that need to be sequenced sequence themselves
for(int i=0; i<ins.length; i++){
string looptemp = "";
//Iterates through all the channels
for(int j=0; j<ins.numChannels; j++){
//Sequences all notes
temp += ins.channels[j].Sequence(i, &d);
}
++d; //Incriments delay
if(looptemp == ""){ //Checks if empty time slot (No notes change)
++d; //If so, increments delay to account for it
}
temp += looptemp; //Adds the current sequence to the full output
}
//Get length of track
int channelLength = temp.size() + 0x4; //Finds the length of the track
//Output Track
output << "MTrk" << toString(channelLength, 4) //Track Header (Includes length)
<< temp //content
<< char(0x00) << char(0xFF) << char(0x2F) << char(0x00); //End of track
return output;
}