Skip to content

Commit

Permalink
use looping thread
Browse files Browse the repository at this point in the history
  • Loading branch information
caillonantoine committed Jun 21, 2023
1 parent eab72a1 commit 53e2fff
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/frontend/maxmsp/nn_tilde/CMakeLists.txt
Expand Up @@ -6,7 +6,7 @@ cmake_minimum_required(VERSION 3.0)
set(C74_MIN_API_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../min-api)
include(${C74_MIN_API_DIR}/script/min-pretarget.cmake)


set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0")
#############################################################
# MAX EXTERNAL
#############################################################
Expand Down
68 changes: 52 additions & 16 deletions src/frontend/maxmsp/nn_tilde/nn_tilde.cpp
@@ -1,6 +1,8 @@
#include "../../../backend/backend.h"
#include "../shared/circular_buffer.h"
#include "c74_min.h"
#include <chrono>
#include <semaphore>
#include <string>
#include <thread>
#include <vector>
Expand Down Expand Up @@ -50,8 +52,10 @@ class nn : public object<nn>, public vector_operator<> {
std::vector<std::unique_ptr<float[]>> m_in_model, m_out_model;

// AUDIO PERFORM
bool m_use_thread;
bool m_use_thread, m_should_stop_perform_thread;
std::unique_ptr<std::thread> m_compute_thread;
std::binary_semaphore m_data_available_lock, m_result_available_lock;

void operator()(audio_bundle input, audio_bundle output);
void perform(audio_bundle input, audio_bundle output);

Expand Down Expand Up @@ -151,14 +155,36 @@ void model_perform(nn *nn_instance) {
in_model.push_back(nn_instance->m_in_model[c].get());
for (int c(0); c < nn_instance->m_out_dim; c++)
out_model.push_back(nn_instance->m_out_model[c].get());

nn_instance->m_model->perform(in_model, out_model, nn_instance->m_buffer_size,
nn_instance->m_method, 1);
}

void model_perform_loop(nn *nn_instance) {
std::vector<float *> in_model, out_model;

for (auto &ptr : nn_instance->m_in_model)
in_model.push_back(ptr.get());

for (auto &ptr : nn_instance->m_out_model)
out_model.push_back(ptr.get());

while (!nn_instance->m_should_stop_perform_thread) {
if (nn_instance->m_data_available_lock.try_acquire_for(
std::chrono::milliseconds(200))) {
nn_instance->m_model->perform(in_model, out_model,
nn_instance->m_buffer_size,
nn_instance->m_method, 1);
nn_instance->m_result_available_lock.release();
}
}
}

nn::nn(const atoms &args)
: m_compute_thread(nullptr), m_in_dim(1), m_in_ratio(1), m_out_dim(1),
m_out_ratio(1), m_buffer_size(4096), m_method("forward"),
m_use_thread(true) {
m_use_thread(true), m_data_available_lock(0), m_result_available_lock(1),
m_should_stop_perform_thread(false) {

m_model = std::make_unique<Backend>();
m_is_backend_init = true;
Expand Down Expand Up @@ -261,9 +287,13 @@ nn::nn(const atoms &args)
m_out_buffer[i].initialize(m_buffer_size);
m_out_model.push_back(std::make_unique<float[]>(m_buffer_size));
}

if (m_use_thread)
m_compute_thread = std::make_unique<std::thread>(model_perform_loop, this);
}

nn::~nn() {
m_should_stop_perform_thread = true;
if (m_compute_thread)
m_compute_thread->join();
}
Expand Down Expand Up @@ -318,24 +348,30 @@ void nn::perform(audio_bundle input, audio_bundle output) {
}

if (m_in_buffer[0].full()) { // BUFFER IS FULL
// IF USE THREAD, CHECK THAT COMPUTATION IS OVER
if (m_compute_thread && m_use_thread) {
m_compute_thread->join();
}
if (!m_use_thread) {
// TRANSFER MEMORY BETWEEN INPUT CIRCULAR BUFFER AND MODEL BUFFER
for (int c(0); c < m_in_dim; c++)
m_in_buffer[c].get(m_in_model[c].get(), m_buffer_size);

// TRANSFER MEMORY BETWEEN INPUT CIRCULAR BUFFER AND MODEL BUFFER
for (int c(0); c < m_in_dim; c++)
m_in_buffer[c].get(m_in_model[c].get(), m_buffer_size);

if (!m_use_thread) // PROCESS DATA RIGHT NOW
// CALL MODEL PERFORM IN CURRENT THREAD
model_perform(this);

// TRANSFER MEMORY BETWEEN OUTPUT CIRCULAR BUFFER AND MODEL BUFFER
for (int c(0); c < m_out_dim; c++)
m_out_buffer[c].put(m_out_model[c].get(), m_buffer_size);
// TRANSFER MEMORY BETWEEN OUTPUT CIRCULAR BUFFER AND MODEL BUFFER
for (int c(0); c < m_out_dim; c++)
m_out_buffer[c].put(m_out_model[c].get(), m_buffer_size);

} else if (m_result_available_lock.try_acquire()) {
// TRANSFER MEMORY BETWEEN INPUT CIRCULAR BUFFER AND MODEL BUFFER
for (int c(0); c < m_in_dim; c++)
m_in_buffer[c].get(m_in_model[c].get(), m_buffer_size);

if (m_use_thread) // PROCESS DATA LATER
m_compute_thread = std::make_unique<std::thread>(model_perform, this);
// TRANSFER MEMORY BETWEEN OUTPUT CIRCULAR BUFFER AND MODEL BUFFER
for (int c(0); c < m_out_dim; c++)
m_out_buffer[c].put(m_out_model[c].get(), m_buffer_size);

// SIGNAL PERFORM THREAD THAT DATA IS AVAILABLE
m_data_available_lock.release();
}
}

// COPY CIRCULAR BUFFER TO OUTPUT
Expand Down

0 comments on commit 53e2fff

Please sign in to comment.