#include "libremediaserver-audio.h" olaThread::olaThread(QObject *parent, int layers) : m_counter(0) , m_layers(layers) { this->setParent(parent); gettimeofday(&m_last_data, NULL); for (int i=0; i < MAX_LAYERS; i++) { for (int j=0; j < LAYER_CHANNELS; j++) { m_dmx[i][j] = 0; } } init(); } olaThread::~olaThread() { stop(); } void olaThread::init() { m_clientWrapper = new ola::client::OlaClientWrapper; Q_CHECK_PTR(m_clientWrapper); if (ola::InitLogging(ola::OLA_LOG_INFO , ola::OLA_LOG_STDERR)) { qDebug() << "ola logging debug working"; } else { qWarning() << "Can not init ola logging"; } if (!m_clientWrapper->Setup()) { qCritical("olaThread::olaStart| Failed Setup() in Client Wrapper"); exit(EXIT_FAILURE); } m_client = m_clientWrapper->GetClient(); m_client->SetDMXCallback(ola::NewCallback(this, &olaThread::NewDmx)); m_clientWrapper->GetSelectServer()->RegisterRepeatingTimeout(4000, ola::NewCallback(this, &olaThread::CheckDataLoss)); m_client->SetCloseHandler(ola::NewSingleCallback(this, &olaThread::socketClosed)); m_dmxSettings = Settings::getInstance()->getDmxSettings(); } void olaThread::run() { m_clientWrapper->GetSelectServer()->Run(); } void olaThread::stop() { if (m_clientWrapper != NULL) { QSet temp = Settings::getInstance()->getUniverses(); foreach (const int &i, temp) { m_client->RegisterUniverse(i, ola::client::UNREGISTER, ola::NewSingleCallback(this, &olaThread::RegisterComplete)); } m_clientWrapper->GetSelectServer()->Terminate(); m_clientWrapper = NULL; m_client = NULL; } } void olaThread::NewDmx(const ola::client::DMXMetadata &data, const ola::DmxBuffer &buffer) { foreach (const dmxSetting &i, m_dmxSettings) { if(i.universe == data.universe && i.address > -1) { bool volSent = false; bool entrySent = false; bool fileSent = false; int aux; for (int j = 0; j < LAYER_CHANNELS; j++){ int value = buffer.Get((i.address) + j); if (m_dmx[i.layer][j] != value) { m_dmx[i.layer][j] = value; switch (j) { case DMX_FOLDER: aux = buffer.Get(i.address + DMX_FILE); qobject_cast(parent())->loadMedia(i.layer, value, aux); m_dmx[i.layer][DMX_FILE] = aux; fileSent = true; break; case DMX_FILE: if (fileSent) break; aux = buffer.Get(i.address + DMX_FOLDER); qobject_cast(parent())->loadMedia(i.layer, aux, value); m_dmx[i.layer][DMX_FOLDER] = aux; fileSent = true; break; case VOLUME_FINE: aux = buffer.Get(i.address + VOLUME_COARSE); value += (aux * 0x100); qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][VOLUME_COARSE] = aux; volSent = true; break; case VOLUME_COARSE: if (volSent) break; value = (value * 0x100) + buffer.Get(i.address + VOLUME_FINE); qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][VOLUME_FINE] = buffer.Get(i.address + VOLUME_FINE); volSent = true; break; case PLAYBACK: qobject_cast(parent())->dmxInput(i.layer, j, value); break; case ENTRY_POINT_FINE: value = (buffer.Get(i.address + ENTRY_POINT_COARSE) * 0x100) + value; qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][ENTRY_POINT_COARSE] = buffer.Get(i.address + ENTRY_POINT_COARSE); entrySent = true; break; case ENTRY_POINT_COARSE: if (entrySent) break; value = (value * 0x100) + buffer.Get(i.address + ENTRY_POINT_FINE); qobject_cast(parent())->dmxInput(i.layer, j, value); m_dmx[i.layer][ENTRY_POINT_FINE] = buffer.Get(i.address + ENTRY_POINT_FINE); entrySent = true; break; default: qobject_cast(parent())->dmxInput(i.layer, j, value); break; } } } } } m_counter++; gettimeofday(&m_last_data, NULL); emit universeReceived(data.universe); } /** * Check for data loss each 4 seconds. */ bool olaThread::CheckDataLoss() { struct timeval now, diff; if (timerisset(&m_last_data)) { gettimeofday(&now, NULL); timersub(&now, &m_last_data, &diff); if (diff.tv_sec > 4 || (diff.tv_sec == 4 && diff.tv_usec > 4000000)) { qInfo()<< "olaThread| Can not read one or several universes"; } } return true; } void olaThread::socketClosed() { qWarning("ola daemon closed connection, reopening it... "); m_clientWrapper->GetSelectServer()->Terminate(); m_client = NULL; m_clientWrapper = NULL; init(); registerUniverse(); run(); }