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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
#include "ofMain.h"
#include "ofxCsv.h"
#include "vectortext.h"
class ScriptLine{
public:
ScriptLine(SVGFont &font,string audiofile,string cols,string message){
vector<string> colours=ofSplitString(cols,",");
for (auto c: colours){
palette.push_back(ofColor::fromHex(ofHexToInt(c)));
}
clear();
vector<string> m=ofSplitString(message," ");
for (auto& word: m){
glyphWord w;
int pos=0;
for (auto& c: word){
string uniglyph = ofUTF8Substring(word, pos, 1);
if (c<0){
//ofLog()<<"got unicode glyph, "<<uniglyph;
}
w.glyphs.push_back(font.getGlyph(uniglyph,
palette.size()?
palette[ofRandom(palette.size())]:
//112->231 hue sat 0->255 brightness 255
ofColor::fromHsb(ofRandom(119)+112,ofRandom(255),255)
));
pos++;
}
words.push_back(w);
}
if (audio.load(audiofile)){
//requires https://github.com/arturoc/openFrameworks/tree/feature-soundPlayerDuration
duration = ((float)audio.getDurationMS())/1000.0f;
avgWordDuration = duration / words.size();
ofLog()<<"Line "<<audiofile<<", duration "<<duration<<"s, "<<words.size()<<" words avg "<<avgWordDuration<<"s";
}
else duration=0.0f;
}
void clear(){
words.clear();
}
vector<ofColor> palette;
vector<glyphWord> words;
ofSoundPlayer audio;
float duration;
float avgWordDuration;
};
class Show{
public:
bool loadFont(filesystem::path fontpath){
return font.load(fontpath);
}
Show(){
isPlaying=false;
}
Show(filesystem::path fontpath){
font.load(fontpath);
Show();
}
bool load(string file){
if (!font.isLoaded()){
ofLogError()<<"cannot load show without a font";
return false;
}
// Load a CSV File.
if(csv.load(file,"|")) {
for (auto row:csv){
if (row.size()<2){
ofLog()<<"Error, found row with "<<row.size()<<" elements";
}
else script.push_back(ScriptLine(font,row[0],row[1],row[2]));
}
ofLog()<<"Loaded show, "<<csv.getNumRows()<<" lines";
playline=script.begin();
return true;
}
playline=script.end();
return false;
}
void play(){
if (playline==script.end()) return;
if (playline->audio.isLoaded()){
playline->audio.play();
startTime=ofGetElapsedTimef();
isPlaying=true;
ofLog()<<"Line playing "<<playline->duration;
}
}
void stop(){
if (isPlaying){
playline->audio.stop();
isPlaying=false;
ofLog()<<"Line stopped";
}
}
void update(){
if (isPlaying){
if (ofGetElapsedTimef()-startTime>playline->duration){
playline->audio.stop();
isPlaying=false;
ofLog()<<"Line finished! "<<playline->duration;;
playline++;
if (playline==script.end()){
ofLog()<<"Show finished!";
}
}
}
}
ofxCsv csv;
vector<ScriptLine> script;
vector<ScriptLine>::iterator playline;
float startTime;
bool isPlaying;
SVGFont font;
};
|