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
|
#include "rotor.h"
using namespace Rotor;
string soname="qm-vamp-plugins";
string id="qm-tempotracker";
string myname="";
string output="";
int outputNo=0;
void Render_context::runTask() {
while (!isCancelled()) {
int cmd=0;
mutex.lock();
if (work_queue.size()){
cmd=work_queue[0];
work_queue.pop_front();
}
mutex.unlock();
if (cmd==ANALYSE_AUDIO) {
state=ANALYSING_AUDIO;
audio_analyser.process(audio_filename);
//vampHost::runPlugin("","qm-vamp-plugins","qm-tempotracker", "",0, audio_filename, cerr,true);
state=AUDIO_READY;
}
sleep(100);
}
printf("Rotor: stopping thread\n");
}
void Render_context::add_queue(int item) {
mutex.lock();
work_queue.push_back(item);
mutex.unlock();
}
Command_response Render_context::session_command(const std::vector<std::string>& command){
//method,id,command1,{command2,}{body}
//here we allow the controlling server to communicate with running tasks
Command_response response;
if (command[2]=="audio") {
if (command[0]=="PUT") { //get audio file location and initiate analysis
if (command.size()>2) {
if (state==IDLE) {
//check file exists
Poco::File f=Poco::File(command[3]);
if (f.exists()) {
//pass to worker thread ??if engine is ready?? ??what if engine has finished but results aren't read??
audio_filename=command[3]; //for now, store session variables in memory
add_queue(ANALYSE_AUDIO);
response.description="<status context='"+command[1]+"'>Starting audio analysis: "+command[3]+"</status>\n";
}
else {
response.status=HTTPResponse::HTTP_NOT_FOUND;
response.description="<status context='"+command[1]+"'>File "+command[3]+" not found</status>\n";
}
}
else {
response.status=HTTPResponse::HTTP_BAD_REQUEST;
response.description="<status context='"+command[1]+"'>Rotor: session busy</status>\n";
}
}
}
if (command[0]=="GET") {
if (state==ANALYSING_AUDIO) {
response.description="<status context='"+command[1]+"'>Rotor: analysing audio</status>\n";
char c[20];
sprintf(c,"%02f",audio_analyser.get_progress());
response.description+="<progress>"+string(c)+"</progress>\n";
}
if (state==AUDIO_READY) {
//not sure about this-- should this state be retained?
//can the data only be read once?
//for now
response.description="<status context='"+command[1]+"'>Rotor: audio ready</status>\n";
response.description+="<beats>";
for (auto& i: audio_analyser.beats) { //is actually giving no data?
char c[20];
sprintf(c,"%02f",i);
response.description+="<beat>"+string(c)+"</beat>";
}
response.description+="\n</beats>";
state=IDLE;
}
}
}
if (command[2]=="graph") {
if (command[0]=="PUT") { //get new graph from file
if (command.size()>2) {
//should interrupt whatever is happening?
//before begining to load from xml
if (state==IDLE) { //eventually not like this
Poco::File f=Poco::File(command[3]);
if (f.exists()) {
string graph_filename=command[3];
if (load_graph(graph_filename)) {
response.description="<status context='"+command[1]+"'>Rotor: loaded graph "+command[3]+"</status>\n";
}
else {
response.status=HTTPResponse::HTTP_INTERNAL_SERVER_ERROR; //~/sources/poco-1.4.6-all/Net/include/Poco/Net/HTTPResponse.h
response.description="<status context='"+command[1]+"'>Rotor: could not load graph "+command[3]+"</status>\n";
}
}
else {
response.status=HTTPResponse::HTTP_NOT_FOUND;
response.description="<status context='"+command[1]+"'>File "+command[3]+" not found</status>\n";
}
}
}
}
}
return response;
}
bool Render_context::load_graph(string graph_filename){
return true;
}
|