#include "Server.h" void Server::start(){ std::cout << "Initialising TCP sever" << std::endl; server.setup(port); osc_sender.setup(OSC_HOST, OSC_PORT); is_active = true; previous_embedding = embedding; last_change_time = std::chrono::steady_clock::now(); lastUpdateTime = std::chrono::steady_clock::now(); /* allocate pixels in vector */ esp_pixels.resize(4); for(auto& p : esp_pixels){ p.allocate(128, 168, GL_RGB); } /* set initial chosen node */ chosen_node = &nodes[0]; } void Server::update(ofFbo& esp_comp){ /* set all past clients to false, to check connection */ for(auto& c : clients){ c.second.connected = false; } ofPixels fboPixels; esp_comp.readToPixels(fboPixels); vector extractedImages; extractedImages.resize(4); for (int i = 0; i < 4; i++) { ofPixels cropPixels; fboPixels.cropTo(cropPixels, regions[i][0], regions[i][1], regions[i][2], regions[i][3]); extractedImages[i].setFromPixels(cropPixels); } for ( int i = 0; i < server.getLastID(); i++){ if (server.isClientConnected(i)) { const int buffer_size = 8; char buffer[buffer_size]; int bytes_recieved = server.receiveRawBytes(i, buffer, buffer_size); if (bytes_recieved == buffer_size){ float value; int id; memcpy(&value, buffer, sizeof(float)); memcpy(&id, buffer + sizeof(float), sizeof(int)); std::string ip_address = server.getClientIP(i); addOrUpdateClient(id, value, ip_address, true); //std::cout << ip_address << " : " << id << std::endl; } } } sendImagesToClients(extractedImages); updateEmbedding(); /* check if inactive -> query vptree -> move camera */ checkActivity(); //sendOSCMessage(); } void Server::disconnectAllClients(){ server.disconnectAllClients(); } void Server::addOrUpdateClient(int client_id, float value, const std::string& ip_address, bool _connected){ ClientInfo client; client.ip_address = ip_address; client.value = value; client.connected = _connected; clients[client_id] = client; } void Server::updateEmbedding() { std::vector emotionNames = { "happy", "sad", "angry", "neutral" }; for (const auto& c : clients) { const ClientInfo& info = c.second; float val = std::round(info.value * 100.0f) / 100.0f; if (c.first >= 0 && c.first < emotionNames.size()) { embedding.emotions[emotionNames[c.first]] = val; } } } void Server::printClients(){ for( const auto& c : clients){ int id = c.first; const ClientInfo& info = c.second; std::cout << "id: " << id << ", value: " << info.value << ", IP: " << info.ip_address << std::endl; } std::cout << is_active << std::endl; } void Server::print(){ const std::vector emotionNames = { "happy", "sad", "angry", "neutral" }; std::ostringstream ss; ss << "Connected Clients: " << num_of_clients << endl; ss << "Embedding ["; for (size_t i = 0; i < emotionNames.size(); ++i) { if (i > 0) ss << ", "; ss << std::fixed << std::setprecision(2) << embedding.emotions[emotionNames[i]]; } ss << "]" << endl; ofSetColor(255, 255, 255); ofDrawBitmapString(ss.str(), (ofGetWindowWidth() / 2) + 20 , 20); } /* check if the controllers are in use */ void Server::checkActivity(){ if (previous_embedding.emotions != embedding.emotions) { // Check if embedding has changed last_change_time = std::chrono::steady_clock::now(); // Reset the timer if there is a change previous_embedding = embedding; // Update the previous embedding to the current one is_active = true; /* send a query to search the closest embedding in the vp-tree */ vector> vp_queries; vp_queries.push_back(embedding.to_vector()); vector ids = tree.query(vp_queries, 1); chosen_node = &nodes[ids[0]]; ofLogNotice() << chosen_node->tsne_position; } else { // Calculate the time since the last change auto now = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast(now - last_change_time).count(); if (duration >= 2) { is_active = false; //ofLogNotice() << "Inactive"; } } } /* send osc msg, check if audio file exists and it is different to the past audiofile */ void Server::sendOSCMessage(){ std::vector messages; ofxOscMessage me_0; ofxOscMessage me_1; ofxOscMessage me_2; ofxOscMessage me_3; ofxOscMessage me_file; std::string audio_file = vp_resp.folder; // Check if file exists in a given dir ofFile file("/home/cailean/Desktop/rave/all_wav_files/" + audio_file + ".wav"); if(!is_active && (audio_file != past_audio_file) && file.exists()){ me_file.setAddress("/emote/filename"); me_file.addStringArg(audio_file + ".wav"); messages.push_back(me_file); past_audio_file = audio_file; } me_0.setAddress("/emote/0"); me_0.addFloatArg(embedding.emotions["neutral"]); messages.push_back(me_0); me_1.setAddress("/emote/1"); me_1.addFloatArg(embedding.emotions["neutral"]); messages.push_back(me_1); me_2.setAddress("/emote/2"); me_2.addFloatArg(embedding.emotions["neutral"]); messages.push_back(me_2); me_3.setAddress("/emote/3"); me_3.addFloatArg(embedding.emotions["neutral"]); messages.push_back(me_3); for (auto& msg : messages){ osc_sender.sendMessage(msg, false); } } /* sends request to http server if is_active = true */ void Server::sendHttpRequest(){ vp_resp = http.query(embedding); } std::vector> Server::generateRandomVectors(int count, int dimension){ return tree.generateRandomVectors(count, dimension); } void Server::sendImagesToClients(vector& imgs){ /* convert to pixels */ int c = 0; for(const auto& f :imgs){ esp_pixels[c] = f.getPixels(); c++; } int num_images = imgs.size(); if (num_images != 4) { // No images to send, return early return; } ofSetLogLevel(OF_LOG_FATAL_ERROR); for (int i = 0; i < server.getLastID(); i++) { if (server.isClientConnected(i)) { // Send RGB pixels as raw bytes & check if the ip addresses align -> get id for(const auto& c_pair : clients){ //std::cout << c_pair.first << std::endl; if(c_pair.second.ip_address == server.getClientIP(i)){ unsigned char* image_data = esp_pixels[c_pair.first].getData(); server.sendRawBytes(i, (char*)image_data, esp_pixels[c_pair.first].size()); } } } } ofSetLogLevel(OF_LOG_NOTICE); } Node& Server::getChosenNode(){ return *chosen_node; } void Server::close(){ server.close(); }