[DEV] start work with Block request processing
This commit is contained in:
parent
411ee20918
commit
020a599f17
250
eaudiofx/Thread.cpp
Normal file
250
eaudiofx/Thread.cpp
Normal file
@ -0,0 +1,250 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD v3 (see license file)
|
||||
*/
|
||||
|
||||
#include <eaudiofx/debug.h>
|
||||
#include <eaudiofx/Thread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static const char* threadGetCharState(enum eaudiofx::status state) {
|
||||
const char* ret = (const char*)"";
|
||||
switch (state) {
|
||||
case eaudiofx::statusNotStarted:
|
||||
ret = (const char*)"NOT_STARTED";
|
||||
break;
|
||||
case eaudiofx::statusCreating:
|
||||
ret = (const char*)"CREATING";
|
||||
break;
|
||||
case eaudiofx::statusStart:
|
||||
ret = (const char*)"START";
|
||||
break;
|
||||
case eaudiofx::statusRun:
|
||||
ret = (const char*)"RUN";
|
||||
break;
|
||||
case eaudiofx::statusStop:
|
||||
ret = (const char*)"STOP";
|
||||
break;
|
||||
case eaudiofx::statusDie:
|
||||
ret = (const char*)"DIE";
|
||||
break;
|
||||
default:
|
||||
ret = (const char*)"???";
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief change the current state of the thread.
|
||||
* @param[in] _newState The new state for the thread.
|
||||
*/
|
||||
void eaudiofx::Thread::threadChangeState(enum eaudiofx::status _newState) {
|
||||
int ret;
|
||||
std::unique_lock<std::mutex> lock(m_interfaceMutex);
|
||||
// debug display :
|
||||
EAUDIOFX_DEBUG("[" << m_id << "] '" << m_name << "' Change state : " << threadGetCharState(m_state) << " ==> " << threadGetCharState(_newState));
|
||||
// set the New state
|
||||
m_state = _newState;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
eaudiofx::Thread::Thread(const std::string& _chainName) {
|
||||
if (_chainName != "") {
|
||||
m_name = _chainName;
|
||||
} else {
|
||||
m_name = "No-name";
|
||||
EAUDIOFX_WARNING("the thread has no name");
|
||||
}
|
||||
static int32_t threadIDBasic = 100;
|
||||
m_id = threadIDBasic++;
|
||||
EAUDIOFX_INFO("THREAD : Allocate [" << m_id << "] name='" << m_name << "'");
|
||||
m_state = eaudiofx::statusNotStarted;
|
||||
}
|
||||
|
||||
|
||||
eaudiofx::Thread::~Thread() {
|
||||
EAUDIOFX_INFO("THREAD : Destroy [" << m_id << "] name='" << m_name << "'");
|
||||
stop();
|
||||
m_thread->join();
|
||||
m_thread.reset();
|
||||
}
|
||||
|
||||
|
||||
int32_t eaudiofx::Thread::start() {
|
||||
int ret;
|
||||
if (eaudiofx::statusDie == m_state) {
|
||||
EAUDIOFX_INFO("Thread [" << m_id << "] name='" << m_name << "' ==> state die ... ==> delete it ...");
|
||||
stopAtEnd();
|
||||
}
|
||||
if (eaudiofx::statusNotStarted != m_state) {
|
||||
EAUDIOFX_ERROR("Failed to create [" << m_id << "] name='" << m_name << "' ==> the thread is not stopped ...");
|
||||
return eaudiofx::ERR_FAIL;
|
||||
}
|
||||
m_state = eaudiofx::statusCreating;
|
||||
m_thread = std::make_shared<std::thread>(eaudiofx::Thread::genericThreadCall, reinterpret_cast<void*>(this));
|
||||
// no else ==> the thread is started corectly... (we think)
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Thread::stop() {
|
||||
EAUDIOFX_INFO(" Stop [" << m_id << "] name='" << m_name << "'");
|
||||
// Set the stop flag for the thread :
|
||||
std::unique_lock<std::mutex> lock(m_interfaceMutex);
|
||||
m_flags |= 1;
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
|
||||
int32_t eaudiofx::Thread::stopAtEnd() {
|
||||
int systemRet;
|
||||
int32_t ret = eaudiofx::ERR_NONE;
|
||||
|
||||
EAUDIOFX_INFO(" Delete [" << m_id << "] name='" << m_name << "' (StopAtEnd)");
|
||||
|
||||
// Request the thread stop:
|
||||
ret = stop();
|
||||
if (eaudiofx::ERR_NONE != ret) {
|
||||
EAUDIOFX_ERROR("The thread have a problem to stop");
|
||||
return ret;
|
||||
}
|
||||
if (eaudiofx::statusNotStarted != m_state) {
|
||||
m_thread.reset();
|
||||
}
|
||||
std::unique_lock<std::mutex> lock(m_interfaceMutex);
|
||||
m_flags = 0;
|
||||
|
||||
m_state = eaudiofx::statusNotStarted;
|
||||
return ret;
|
||||
}
|
||||
|
||||
// function that might be writen for every thread
|
||||
bool eaudiofx::Thread::stateStart() {
|
||||
EAUDIOFX_DEBUG("Not overwrited in the herited classes: StateStart");
|
||||
// virtual function ...
|
||||
return false;
|
||||
}
|
||||
|
||||
bool eaudiofx::Thread::stateRun() {
|
||||
EAUDIOFX_DEBUG("Not overwrited in the herited classes: StateRun");
|
||||
// virtual function ...
|
||||
usleep(100000);
|
||||
// Force the stop if this function is not overwritte
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool eaudiofx::Thread::stateStop() {
|
||||
EAUDIOFX_DEBUG("Not overwrited in the herited classes: StateStop");
|
||||
// virtual function ...
|
||||
return false;
|
||||
}
|
||||
|
||||
void eaudiofx::Thread::genericThreadCall(void* _data) {
|
||||
eaudiofx::Thread * self = reinterpret_cast<eaudiofx::Thread*>(_data);
|
||||
if (self != nullptr) {
|
||||
self->threadCall();
|
||||
} else {
|
||||
EAUDIOFX_ERROR("can not start th ethraead ...");
|
||||
}
|
||||
}
|
||||
|
||||
void eaudiofx::Thread::threadCall() {
|
||||
bool autoKill = false;
|
||||
// Endless loop.
|
||||
while(eaudiofx::statusDie != m_state) {
|
||||
int32_t flags = 0;
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_interfaceMutex);
|
||||
flags = m_flags;
|
||||
m_flags = 0;
|
||||
}
|
||||
if (flags == 1 ) {
|
||||
EAUDIOFX_DEBUG("Detect stop request by user...");
|
||||
// action depend on the current state :
|
||||
switch (m_state) {
|
||||
case eaudiofx::statusCreating:
|
||||
threadChangeState(eaudiofx::statusDie);
|
||||
break;
|
||||
case eaudiofx::statusStart:
|
||||
threadChangeState(eaudiofx::statusStop);
|
||||
break;
|
||||
case eaudiofx::statusRun:
|
||||
threadChangeState(eaudiofx::statusStop);
|
||||
break;
|
||||
case eaudiofx::statusStop:
|
||||
// nothing to do ...
|
||||
break;
|
||||
case eaudiofx::statusDie:
|
||||
// impossible state
|
||||
break;
|
||||
default:
|
||||
// Should not happen
|
||||
EAUDIOFX_CRITICAL("Base: [" << m_id << "] '" << m_name << "' state failure ...");
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Retrieve current action.
|
||||
switch (m_state) {
|
||||
case eaudiofx::statusCreating:
|
||||
EAUDIOFX_DEBUG("eaudiofx::statusCreating");
|
||||
// change state :
|
||||
threadChangeState(eaudiofx::statusStart);
|
||||
break;
|
||||
case eaudiofx::statusStart:
|
||||
EAUDIOFX_DEBUG("eaudiofx::statusStart");
|
||||
// call function
|
||||
autoKill = stateStart();
|
||||
// a problem occured to the function
|
||||
if (true == autoKill) {
|
||||
// error in start ==> direct end
|
||||
threadChangeState(eaudiofx::statusDie);
|
||||
} else {
|
||||
// change state :
|
||||
threadChangeState(eaudiofx::statusRun);
|
||||
}
|
||||
break;
|
||||
case eaudiofx::statusRun:
|
||||
EAUDIOFX_DEBUG("eaudiofx::statusRun");
|
||||
// call function
|
||||
autoKill = stateRun();
|
||||
if (true == autoKill) {
|
||||
EAUDIOFX_DEBUG("Request AutoKill");
|
||||
// error in start ==> direct end
|
||||
threadChangeState(eaudiofx::statusStop);
|
||||
}
|
||||
// no else
|
||||
break;
|
||||
case eaudiofx::statusStop:
|
||||
EAUDIOFX_DEBUG("eaudiofx::statusStop");
|
||||
// call function
|
||||
autoKill = stateStop();
|
||||
// a problem occured to the function
|
||||
if (true == autoKill) {
|
||||
// error in stop ==> direct end
|
||||
threadChangeState(eaudiofx::statusDie);
|
||||
} else {
|
||||
// change state :
|
||||
threadChangeState(eaudiofx::statusDie);
|
||||
}
|
||||
break;
|
||||
case eaudiofx::statusDie:
|
||||
EAUDIOFX_DEBUG("eaudiofx::statusDie");
|
||||
break;
|
||||
default:
|
||||
// Should not happen
|
||||
EAUDIOFX_CRITICAL("Base: state failure: [" << m_id << "] name='" << m_name << "'");
|
||||
return;
|
||||
}
|
||||
}
|
||||
// exit the thread...
|
||||
EAUDIOFX_INFO("Base: THEAD (END): [" << m_id << "] name='" << m_name << "'");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
76
eaudiofx/Thread.h
Normal file
76
eaudiofx/Thread.h
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @author Edouard DUPIN
|
||||
*
|
||||
* @copyright 2014, Edouard DUPIN, all right reserved
|
||||
*
|
||||
* @license BSD v3 (see license file)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __EAUDIO_FX_THREAD_H__
|
||||
#define __EAUDIO_FX_THREAD_H__
|
||||
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <etk/os/Fifo.h>
|
||||
#include <eaudiofx/core/audio.h>
|
||||
|
||||
/**
|
||||
* @brief Tanho thread system (parent class)
|
||||
*/
|
||||
namespace eaudiofx {
|
||||
enum status {
|
||||
statusNotStarted, //!< The thread is creating itself
|
||||
statusCreating, //!< The thread is creating itself
|
||||
statusStart, //!< The element is starting
|
||||
statusRun, //!< The thread is running
|
||||
statusStop, //!< The thread is stoping
|
||||
statusDie, //!< the thread is diing or dead
|
||||
};
|
||||
class Thread {
|
||||
private:
|
||||
static void genericThreadCall(void * data);
|
||||
protected:
|
||||
std::shared_ptr<std::thread> m_thread;
|
||||
std::mutex m_interfaceMutex;
|
||||
int32_t m_flags;
|
||||
public:
|
||||
Thread(const std::string& _name="not-set-name");
|
||||
~Thread();
|
||||
int32_t start(); //!< start the thread
|
||||
int32_t stop(); //!< stop this current thread (request the stop of the process) ==> a-synchronous request
|
||||
int32_t stopAtEnd(); //!< stop when the process is ended (when possible) ==> stop and wait hte real end of the thread
|
||||
void setRepeating(int32_t delayBetweenRestart, int32_t maxTimeRestart); //!< configure repeating
|
||||
void setNoRepeating(); //!< cancel SetRepeating
|
||||
protected:
|
||||
void threadCall(); //!< internal call of sup thread system (call from GenericThreadCall)
|
||||
private:
|
||||
void threadChangeState(enum status _newState); //!< information about state change
|
||||
protected:
|
||||
std::string m_name; //!< curent thread name
|
||||
private:
|
||||
uint32_t m_id; //!< Thread Id it will be Unique
|
||||
enum status m_state; //!< Thread current state
|
||||
protected:
|
||||
enum status getState() {
|
||||
return m_state;
|
||||
};
|
||||
/**
|
||||
* @brief Thread state "Start" process
|
||||
* @return true if an error occured ==> this kill the thread.
|
||||
*/
|
||||
virtual bool stateStart();
|
||||
/**
|
||||
* @brief Thread state "Run" process
|
||||
* @return true if an error occured or a kill is requested by a block
|
||||
*/
|
||||
virtual bool stateRun();
|
||||
/**
|
||||
* @brief Thread state "Stop" process
|
||||
* @return true if an error occured
|
||||
*/
|
||||
virtual bool stateStop();
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
@ -33,7 +33,7 @@ eaudiofx::GeneratorSignal::GeneratorSignal() :
|
||||
|
||||
|
||||
int32_t eaudiofx::GeneratorSignal::algoProcess(int64_t _currentTime, int64_t _processTimeSlot) {
|
||||
|
||||
EAUDIOFX_INFO("Process: " << _currentTime << " chunkTime=" << _processTimeSlot);
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
#if 0
|
||||
|
@ -33,49 +33,27 @@ int eaudiofx::ReceiverRtAudio::rtAudioCallBack(void *_outputBuffer,
|
||||
|
||||
return classPointer->needData((float*)_outputBuffer, _nBufferFrames, _streamTime, _status);
|
||||
}
|
||||
#if 0
|
||||
int32_t eaudiofx::ReceiverRtAudio::needData(float* _outputBuffer,
|
||||
int32_t eaudiofx::ReceiverRtAudio::needData(void* _outputBuffer,
|
||||
size_t _nBufferFrames,
|
||||
double _streamTime,
|
||||
airtaudio::streamStatus _status) {
|
||||
EAUDIOFX_INFO("NEED DATA : " << _nBufferFrames);
|
||||
if (m_processStarted == false) {
|
||||
for (int32_t iii=0; iii<_nBufferFrames*2; ++iii) {
|
||||
_outputBuffer[iii] = 0;
|
||||
((int8_t*)_outputBuffer)[iii] = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
// Request block input:
|
||||
int32_t ret = eaudiofx::Block::pull(_streamTime, _nBufferFrames, (float)_nBufferFrames/48000.0f);
|
||||
if (ret != eaudiofx::ERR_NONE) {
|
||||
EAUDIOFX_ERROR("can not get data ...");
|
||||
return -1;
|
||||
}
|
||||
auto it = m_io.find("in");
|
||||
if (it == m_io.end()) {
|
||||
EAUDIOFX_WARNING("Request an un-existing IO");
|
||||
return 0;
|
||||
}
|
||||
eaudiofx::BufferAudioRaw* buffer = dynamic_cast<eaudiofx::BufferAudioRaw*>(it->second.m_buffer);
|
||||
if (buffer == NULL) {
|
||||
EAUDIOFX_WARNING("no IO plugged");
|
||||
return 0;
|
||||
}
|
||||
float* data = buffer->getData();
|
||||
for (int32_t iii=0; iii<_nBufferFrames*2; ++iii) {
|
||||
_outputBuffer[iii] = data[iii]*0.5f;
|
||||
int32_t nbData = std::min(m_buffer.size()/2, _nBufferFrames*2);
|
||||
for (int32_t iii=0; iii<nbData*2; ++iii) {
|
||||
((int8_t*)_outputBuffer)[iii] = m_buffer[iii];
|
||||
//EAUDIOFX_ERROR("write : " << data[iii]);
|
||||
}
|
||||
/*
|
||||
FILE* plopppp = fopen("plopout.raw", "a");
|
||||
fwrite(_outputBuffer, sizeof(float), _nBufferFrames, plopppp);
|
||||
fflush(plopppp);
|
||||
fclose(plopppp);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
int32_t eaudiofx::GeneratorSignal::algoProcess(int64_t _currentTime, int64_t _processTimeSlot) {
|
||||
|
||||
|
||||
int32_t eaudiofx::ReceiverRtAudio::algoProcess(int64_t _currentTime, int64_t _processTimeSlot) {
|
||||
EAUDIOFX_INFO("Process: " << _currentTime << " chunkTime=" << _processTimeSlot);
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
@ -116,7 +94,8 @@ int32_t eaudiofx::ReceiverRtAudio::algoInit() {
|
||||
unsigned int bufferFrames = 256;
|
||||
EAUDIOFX_DEBUG("init Stream ...");
|
||||
// TODO : Check return error
|
||||
m_dac.openStream(&m_parameters, NULL, airtaudio::FLOAT32, 48000, &bufferFrames, &rtAudioCallBack, (void *)this);
|
||||
//m_dac.openStream(&m_parameters, NULL, airtaudio::FLOAT32, 48000, &bufferFrames, &rtAudioCallBack, (void *)this);
|
||||
m_dac.openStream(&m_parameters, NULL, airtaudio::SINT16, 48000, &bufferFrames, &rtAudioCallBack, (void *)this);
|
||||
// TODO : Check return error
|
||||
m_dac.startStream();
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace eaudiofx {
|
||||
airtaudio::streamStatus _status,
|
||||
void* _userData);
|
||||
// class callback
|
||||
int32_t needData(float* _outputBuffer,
|
||||
int32_t needData(void* _outputBuffer,
|
||||
size_t _nBufferFrames,
|
||||
double _streamTime,
|
||||
airtaudio::streamStatus _status);
|
||||
@ -43,10 +43,9 @@ namespace eaudiofx {
|
||||
protected:
|
||||
airtaudio::Interface m_dac;
|
||||
airtaudio::StreamParameters m_parameters;
|
||||
std::vector<int8_t> m_buffer;
|
||||
public:
|
||||
int32_t algoProcess(int64_t _currentTime, int64_t _processTimeSlot) {
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
int32_t algoProcess(int64_t _currentTime, int64_t _processTimeSlot);
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -13,138 +13,12 @@
|
||||
|
||||
|
||||
|
||||
eaudiofx::Block::Block() :
|
||||
m_uid(0),
|
||||
m_type(),
|
||||
m_parent(NULL) {
|
||||
static size_t id=0;
|
||||
m_uid = id;
|
||||
id++;
|
||||
eaudiofx::Block::Block() {
|
||||
|
||||
}
|
||||
|
||||
eaudiofx::Block::~Block() {
|
||||
for (auto &it : m_io) {
|
||||
if (it.second.m_buffer == NULL) {
|
||||
continue;
|
||||
}
|
||||
if (it.second.m_internal != true) {
|
||||
continue;
|
||||
}
|
||||
// just remove pointer from reference system.
|
||||
eaudiofx::Buffer* tmp = it.second.m_buffer;
|
||||
it.second.m_buffer = NULL;
|
||||
// Notify all element that a buffer is removed.
|
||||
subRemoveBuffer(tmp);
|
||||
delete(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Block::pull(double _currentTime, int32_t _request, float _timeout) {
|
||||
int32_t ret = eaudiofx::ERR_NONE;
|
||||
//EAUDIOFX_DEBUG("Pull request for " << m_io.size() << " IO(s)");
|
||||
for (auto &it : m_io) {
|
||||
if (it.second.m_buffer == NULL) {
|
||||
EAUDIOFX_DEBUG(" ==> null buffer");
|
||||
continue;
|
||||
}
|
||||
if ( it.second.m_type != eaudiofx::Block::ioInput
|
||||
&& it.second.m_type != eaudiofx::Block::ioParameter) {
|
||||
continue;
|
||||
}
|
||||
if (it.second.m_buffer->pull(_currentTime, _request, _timeout) != eaudiofx::ERR_NONE) {
|
||||
ret = eaudiofx::ERR_FAIL;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
|
||||
|
||||
void eaudiofx::Block::subRemoveBuffer(const eaudiofx::Buffer* _buffer) {
|
||||
if (_buffer == NULL) {
|
||||
return;
|
||||
}
|
||||
if (m_parent == NULL) {
|
||||
onRemoveBuffer(_buffer);
|
||||
} else {
|
||||
m_parent->subRemoveBuffer(_buffer);
|
||||
}
|
||||
}
|
||||
|
||||
void eaudiofx::Block::onRemoveBuffer(const eaudiofx::Buffer* _buffer) {
|
||||
unLinkBuffer(_buffer);
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Block::linkBuffer(eaudiofx::Buffer* _buffer, const std::string& _name) {
|
||||
if ( _buffer == NULL
|
||||
|| _name.size() == 0) {
|
||||
return eaudiofx::ERR_INPUT_NULL;
|
||||
}
|
||||
for (auto &it : m_io) {
|
||||
if (it.first == _name) {
|
||||
if (it.second.m_type == ioOutput) {
|
||||
EAUDIOFX_ERROR("[" << getUID() << "Can not overwrite output buffer...");
|
||||
return eaudiofx::ERR_FORBIDEN;
|
||||
}
|
||||
it.second.m_buffer = _buffer;
|
||||
// TODO : Negiciate ???
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
}
|
||||
return eaudiofx::ERR_NO_IO;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int32_t eaudiofx::Block::unLinkBuffer(const eaudiofx::Buffer* _buffer) {
|
||||
if (_buffer == NULL) {
|
||||
return eaudiofx::ERR_INPUT_NULL;
|
||||
}
|
||||
// For every buffer, remove internal reference...
|
||||
for (auto &it : m_io) {
|
||||
if (it.second.m_buffer == _buffer) {
|
||||
it.second.m_buffer = NULL;
|
||||
}
|
||||
}
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Block::unLinkBuffer(const std::string& _name) {
|
||||
if (_name.size() == 0) {
|
||||
return eaudiofx::ERR_INPUT_NULL;
|
||||
}
|
||||
for (auto &it : m_io) {
|
||||
if (it.first == _name) {
|
||||
if (it.second.m_type == ioOutput) {
|
||||
EAUDIOFX_ERROR("[" << getUID() << "Can not overwrite output buffer...");
|
||||
return eaudiofx::ERR_FORBIDEN;
|
||||
}
|
||||
it.second.m_buffer = NULL;
|
||||
if (it.second.m_type == ioParameter) {
|
||||
// TODO : Re-create the basic input buffer ... (Or duplicate the last one???
|
||||
}
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
}
|
||||
return eaudiofx::ERR_NO_IO;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Block::getBuffer(eaudiofx::Buffer*& _buffer, const std::string& _name) {
|
||||
if (_name.size() == 0) {
|
||||
return eaudiofx::ERR_INPUT_NULL;
|
||||
}
|
||||
for (auto &it : m_io) {
|
||||
if (it.first == _name) {
|
||||
if (it.second.m_type == ioInput) {
|
||||
EAUDIOFX_ERROR("[" << getUID() << "Can not Request Input buffer...");
|
||||
return eaudiofx::ERR_FORBIDEN;
|
||||
}
|
||||
if (it.second.m_type == ioParameter) {
|
||||
EAUDIOFX_ERROR("[" << getUID() << "Can not Request Parameter buffer...");
|
||||
return eaudiofx::ERR_FORBIDEN;
|
||||
}
|
||||
_buffer = it.second.m_buffer;
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
}
|
||||
return eaudiofx::ERR_NO_IO;
|
||||
}
|
||||
|
||||
|
@ -18,44 +18,43 @@ eaudiofx::BlockMeta::BlockMeta() {
|
||||
eaudiofx::BlockMeta::~BlockMeta() {
|
||||
// TODO : Unlink all ...
|
||||
for (auto &it : m_list) {
|
||||
if (it == NULL) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
eaudiofx::Block* tmp = it;
|
||||
it = NULL;
|
||||
delete(tmp);
|
||||
std::shared_ptr<eaudiofx::Block> tmp = it;
|
||||
it.reset();
|
||||
}
|
||||
m_list.clear();
|
||||
}
|
||||
|
||||
eaudiofx::Block* eaudiofx::BlockMeta::getBlock(const std::string& _name) {
|
||||
std::shared_ptr<eaudiofx::Block> eaudiofx::BlockMeta::getBlock(const std::string& _name) {
|
||||
if (_name.size() == 0) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
for (auto &it : m_list) {
|
||||
if (it == NULL) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->getName() == _name) {
|
||||
return it;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::BlockMeta::addBlock(eaudiofx::Block* _block) {
|
||||
if (_block == NULL) {
|
||||
EAUDIOFX_ERROR("[" << getUID() << "] Add NULL block");
|
||||
int32_t eaudiofx::BlockMeta::addBlock(const std::shared_ptr<eaudiofx::Block>& _block) {
|
||||
if (_block == nullptr) {
|
||||
EAUDIOFX_ERROR("[" << getId() << "] Add nullptr block");
|
||||
return eaudiofx::ERR_INPUT_NULL;
|
||||
}
|
||||
if (_block->getName().size() > 0 ) {
|
||||
// Check if name exist :
|
||||
for (auto &it : m_list) {
|
||||
if (it == NULL) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->getName() == _block->getName()) {
|
||||
EAUDIOFX_ERROR("[" << getUID() << "] Add block name '" << _block->getName() << "' already exist");
|
||||
EAUDIOFX_ERROR("[" << getId() << "] Add block name '" << _block->getName() << "' already exist");
|
||||
return eaudiofx::ERR_ALREADY_EXIST;
|
||||
}
|
||||
}
|
||||
@ -74,29 +73,26 @@ int32_t eaudiofx::BlockMeta::removeBlock(const std::string& _name) {
|
||||
return eaudiofx::ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::BlockMeta::replaceFilter(const std::string& _nameUnLink, const std::string& _nameLink) {
|
||||
EAUDIOFX_ERROR("NOT IMPLEMENTED");
|
||||
return eaudiofx::ERR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::BlockMeta::linkBlock(const std::string& _generatorBlockName,
|
||||
const std::string& _generatorIoName,
|
||||
const std::string& _receiverBlockName,
|
||||
const std::string& _receiverIoName) {
|
||||
/*
|
||||
eaudiofx::Block* itGenerator = getBlock(_generatorBlockName);
|
||||
eaudiofx::Block* itReceiver = getBlock(_receiverBlockName);
|
||||
if ( itGenerator == NULL
|
||||
|| itReceiver == NULL) {
|
||||
if ( itGenerator == nullptr
|
||||
|| itReceiver == nullptr) {
|
||||
EAUDIOFX_ERROR("Can not link : '" << _generatorBlockName << "' and '" << _receiverBlockName << "' one element does not exist ...");
|
||||
return eaudiofx::ERR_FAIL;
|
||||
}
|
||||
eaudiofx::Buffer* outputBuffer = NULL;
|
||||
eaudiofx::Buffer* outputBuffer = nullptr;
|
||||
if (itGenerator->getBuffer(outputBuffer, _generatorIoName) != eaudiofx::ERR_NONE) {
|
||||
EAUDIOFX_ERROR("Can not get buffer : '" << _generatorBlockName << "':'" << _generatorIoName << "'");
|
||||
return eaudiofx::ERR_FAIL;
|
||||
}
|
||||
if (outputBuffer == NULL) {
|
||||
EAUDIOFX_ERROR("Get NULL buffer : '" << _generatorBlockName << "':'" << _generatorIoName << "'");
|
||||
if (outputBuffer == nullptr) {
|
||||
EAUDIOFX_ERROR("Get nullptr buffer : '" << _generatorBlockName << "':'" << _generatorIoName << "'");
|
||||
return eaudiofx::ERR_FAIL;
|
||||
}
|
||||
if (itReceiver->linkBuffer(outputBuffer, _receiverIoName) != eaudiofx::ERR_NONE) {
|
||||
@ -104,6 +100,7 @@ int32_t eaudiofx::BlockMeta::linkBlock(const std::string& _generatorBlockName,
|
||||
return eaudiofx::ERR_FAIL;
|
||||
}
|
||||
EAUDIOFX_INFO("Link : " << _generatorBlockName << ":" << _generatorIoName << " and " << _receiverBlockName << ":" << _receiverIoName);
|
||||
*/
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
@ -118,14 +115,14 @@ int32_t eaudiofx::BlockMeta::openStream(const std::string& _stream) {
|
||||
}
|
||||
|
||||
|
||||
int32_t eaudiofx::BlockMeta::init() {
|
||||
EAUDIOFX_INFO("[" << getUID() << "]Init Meta block : '" << getName() << "'");
|
||||
int32_t eaudiofx::BlockMeta::algoInit() {
|
||||
EAUDIOFX_INFO("[" << getId() << "]Init Meta block : '" << getName() << "'");
|
||||
int32_t ret = eaudiofx::ERR_NONE;
|
||||
for (auto &it : m_list) {
|
||||
if (it == NULL) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->init() != eaudiofx::ERR_NONE) {
|
||||
if (it->algoInit() != eaudiofx::ERR_NONE) {
|
||||
ret = eaudiofx::ERR_FAIL;
|
||||
}
|
||||
}
|
||||
@ -135,13 +132,13 @@ int32_t eaudiofx::BlockMeta::init() {
|
||||
return ret;
|
||||
};
|
||||
|
||||
int32_t eaudiofx::BlockMeta::unInit() {
|
||||
int32_t eaudiofx::BlockMeta::algoUnInit() {
|
||||
int32_t ret = eaudiofx::ERR_NONE;
|
||||
for (auto &it : m_list) {
|
||||
if (it == NULL) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->unInit() != eaudiofx::ERR_NONE) {
|
||||
if (it->algoUnInit() != eaudiofx::ERR_NONE) {
|
||||
ret = eaudiofx::ERR_FAIL;
|
||||
}
|
||||
}
|
||||
@ -152,14 +149,14 @@ int32_t eaudiofx::BlockMeta::unInit() {
|
||||
};
|
||||
|
||||
|
||||
int32_t eaudiofx::BlockMeta::start() {
|
||||
EAUDIOFX_INFO("[" << getUID() << "] Start Meta block : '" << getName() << "'");
|
||||
int32_t eaudiofx::BlockMeta::algoStart() {
|
||||
EAUDIOFX_INFO("[" << getId() << "] Start Meta block : '" << getName() << "'");
|
||||
int32_t ret = eaudiofx::ERR_NONE;
|
||||
for (auto &it : m_list) {
|
||||
if (it == NULL) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->start() != eaudiofx::ERR_NONE) {
|
||||
if (it->algoStart() != eaudiofx::ERR_NONE) {
|
||||
ret = eaudiofx::ERR_FAIL;
|
||||
}
|
||||
}
|
||||
@ -169,14 +166,14 @@ int32_t eaudiofx::BlockMeta::start() {
|
||||
return ret;
|
||||
};
|
||||
|
||||
int32_t eaudiofx::BlockMeta::stop() {
|
||||
EAUDIOFX_INFO("[" << getUID() << "] Stop Meta block : '" << getName() << "'");
|
||||
int32_t eaudiofx::BlockMeta::algoStop() {
|
||||
EAUDIOFX_INFO("[" << getId() << "] Stop Meta block : '" << getName() << "'");
|
||||
int32_t ret = eaudiofx::ERR_NONE;
|
||||
for (auto &it : m_list) {
|
||||
if (it == NULL) {
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->stop() != eaudiofx::ERR_NONE) {
|
||||
if (it->algoStop() != eaudiofx::ERR_NONE) {
|
||||
ret = eaudiofx::ERR_FAIL;
|
||||
}
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ namespace eaudiofx {
|
||||
protected:
|
||||
BlockMeta();
|
||||
void init() {
|
||||
eaudiofx::Block();
|
||||
eaudiofx::Block::init();
|
||||
}
|
||||
public:
|
||||
DECLARE_FACTORY(BlockMeta);
|
||||
@ -37,7 +37,7 @@ namespace eaudiofx {
|
||||
* @param[in] _block Pointer on the block (do not free yourself)
|
||||
* @return generic error
|
||||
*/
|
||||
int32_t addBlock(std::shared_ptr<eaudiofx::Block> _block);
|
||||
int32_t addBlock(const std::shared_ptr<eaudiofx::Block>& _block);
|
||||
/**
|
||||
* @brief Add a block in the Meta-block.
|
||||
* @param[in] _blockType Name of the type of block to add.
|
||||
|
@ -13,16 +13,8 @@
|
||||
eaudiofx::Buffer::Buffer(eaudiofx::Block& _parent) :
|
||||
m_parent(_parent),
|
||||
m_timestamp(0),
|
||||
m_time(0),
|
||||
m_negociated(false) {
|
||||
m_timeSize(0) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
int32_t eaudiofx::Buffer::pull(double _currentTime, int32_t _request, float _timeout) {
|
||||
if (_currentTime > m_timestamp) {
|
||||
return m_parent.pull(_currentTime, _request, _timeout);
|
||||
}
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
|
@ -9,47 +9,64 @@
|
||||
#include <eaudiofx/core/BufferAudio.h>
|
||||
#include <eaudiofx/debug.h>
|
||||
|
||||
eaudiofx::BufferAudio::BufferAudio(eaudiofx::Block& _parent) :
|
||||
eaudiofx::BufferAudio::BufferAudio(eaudiofx::Block& _parent, const std::string& _description) :
|
||||
eaudiofx::Buffer(_parent),
|
||||
m_frequency(0),
|
||||
m_nbChannel(0),
|
||||
m_data(NULL),
|
||||
m_allocated(0) {
|
||||
memset(m_channelType, 0, sizeof(m_channelType));
|
||||
m_frequency(48000),
|
||||
m_channelMap({audioChannelFrontLeft,audioChannelFrontRight}),
|
||||
m_format(audioFormatInt16),
|
||||
m_data(),
|
||||
m_sampleSize(2),
|
||||
m_chunkSize(4) {
|
||||
resize(32);
|
||||
}
|
||||
|
||||
eaudiofx::BufferAudio::BufferAudio(eaudiofx::Block& _parent, int32_t _frequency, int32_t _nbChannel) :
|
||||
eaudiofx::BufferAudio::BufferAudio(eaudiofx::Block& _parent,
|
||||
int32_t _frequency,
|
||||
const std::vector<enum audioChannel>& _map,
|
||||
enum audioFormat _format) :
|
||||
eaudiofx::Buffer(_parent),
|
||||
m_frequency(_frequency),
|
||||
m_nbChannel(_nbChannel),
|
||||
m_data(NULL),
|
||||
m_allocated(0) {
|
||||
memset(m_channelType, 0, sizeof(m_channelType));
|
||||
m_channelMap(_map),
|
||||
m_format(_format),
|
||||
m_data(),
|
||||
m_sampleSize(1),
|
||||
m_chunkSize(1) {
|
||||
switch(_format) {
|
||||
case audioFormatInt8:
|
||||
m_sampleSize = 1;
|
||||
break;
|
||||
case audioFormatInt16:
|
||||
m_sampleSize = 2;
|
||||
break;
|
||||
case audioFormatInt24:
|
||||
case audioFormatInt32:
|
||||
case audioFormatIntFloat:
|
||||
case audioFormatInt16OverInt32:
|
||||
m_sampleSize = 4;
|
||||
break;
|
||||
case audioFormatIntDouble:
|
||||
m_sampleSize = 8;
|
||||
break;
|
||||
}
|
||||
m_chunkSize = m_sampleSize*m_channelMap.size();
|
||||
resize(32);
|
||||
}
|
||||
|
||||
eaudiofx::BufferAudio::~BufferAudio() {
|
||||
if (m_data != NULL) {
|
||||
delete[] m_data;
|
||||
m_data = NULL;
|
||||
m_allocated = 0;
|
||||
|
||||
}
|
||||
|
||||
void eaudiofx::BufferAudio::clear() {
|
||||
for (auto &it : m_data) {
|
||||
it = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void eaudiofx::BufferAudio::resize(size_t _newSize) {
|
||||
if (m_allocated >= _newSize) {
|
||||
// nothing to do, enought data ...
|
||||
return;
|
||||
}
|
||||
if (m_data != NULL) {
|
||||
delete[] m_data;
|
||||
m_data = NULL;
|
||||
m_allocated = 0;
|
||||
}
|
||||
EAUDIOFX_ERROR("Request allocate of " << _newSize << " samples");
|
||||
m_data = new float[_newSize];
|
||||
if (m_data == NULL) {
|
||||
EAUDIOFX_ERROR("Can not allocate Buffer Audio");
|
||||
} else {
|
||||
m_allocated = _newSize;
|
||||
}
|
||||
}
|
||||
void eaudiofx::BufferAudio::resize(size_t _nbChunks) {
|
||||
m_data.resize(m_chunkSize*_nbChunks, 0);
|
||||
}
|
||||
|
||||
size_t eaudiofx::BufferAudio::size() {
|
||||
return m_data.size() / m_chunkSize;
|
||||
}
|
||||
|
||||
|
@ -35,7 +35,6 @@ namespace eaudiofx {
|
||||
};
|
||||
class BufferAudio : public eaudiofx::Buffer {
|
||||
public:
|
||||
BufferAudio(eaudiofx::Block& _parent);
|
||||
BufferAudio(eaudiofx::Block& _parent,
|
||||
int32_t _frequency=48000,
|
||||
const std::vector<enum audioChannel>& _map={audioChannelFrontLeft,audioChannelFrontRight},
|
||||
@ -48,18 +47,31 @@ namespace eaudiofx {
|
||||
std::vector<enum audioChannel> m_channelMap;
|
||||
enum audioFormat m_format;
|
||||
protected:
|
||||
int8_t* m_data; //!< pointer on the data.
|
||||
std::vector<int8_t> m_data; //!< pointer on the data.
|
||||
int8_t m_sampleSize; //!< Size of one sample
|
||||
int8_t m_chunkSize; //!< Size of one chunk Size
|
||||
size_t m_allocated; //!< number of sample allocated
|
||||
public:
|
||||
/**
|
||||
* @brief Get the buffer casted in float*
|
||||
* @return Pointer on the buffer with correct cast.
|
||||
*/
|
||||
template<typename T> T* getData() {
|
||||
return static_cast<T*>(m_data);
|
||||
return static_cast<T*>(&m_data[0]);
|
||||
}
|
||||
/**
|
||||
* @breif Clean all sample in the buffer
|
||||
*/
|
||||
void clear();
|
||||
/**
|
||||
* @brief Resize the buffer at a new size.
|
||||
* @param[in] _nbChunks Number of chunk requested.
|
||||
*/
|
||||
void resize(size_t _nbChunks);
|
||||
/**
|
||||
* @brief Get number of chunk in the buffer.
|
||||
* @return Number of chunk in the buffer.
|
||||
*/
|
||||
size_t size();
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include <eaudiofx/debug.h>
|
||||
#include <eaudiofx/core/Processing.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
int32_t eaudiofx::Processing::process() {
|
||||
@ -16,24 +17,44 @@ int32_t eaudiofx::Processing::process() {
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Processing::start() {
|
||||
EAUDIOFX_INFO("Start Processing : '" << getName() << "'");
|
||||
int32_t ret = init();
|
||||
if (ret != eaudiofx::ERR_NONE) {
|
||||
return ret;
|
||||
}
|
||||
return eaudiofx::BlockMeta::start();
|
||||
eaudiofx::Thread::start();
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Processing::stop() {
|
||||
EAUDIOFX_INFO("Stop Processing : '" << getName() << "'");
|
||||
int32_t ret = eaudiofx::BlockMeta::stop();
|
||||
if (ret != eaudiofx::ERR_NONE) {
|
||||
return ret;
|
||||
}
|
||||
return unInit();
|
||||
eaudiofx::Thread::stop();
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
|
||||
int32_t eaudiofx::Processing::waitEndOfProcess() {
|
||||
EAUDIOFX_INFO("wait end of Processing : '" << getName() << "'");
|
||||
return eaudiofx::ERR_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool eaudiofx::Processing::stateStart() {
|
||||
EAUDIOFX_INFO("Start Processing : '" << getName() << "'");
|
||||
int32_t ret = algoInit();
|
||||
if (ret != eaudiofx::ERR_NONE) {
|
||||
return ret;
|
||||
}
|
||||
eaudiofx::BlockMeta::algoStart();
|
||||
return false;
|
||||
}
|
||||
|
||||
bool eaudiofx::Processing::stateRun() {
|
||||
EAUDIOFX_INFO("Process : '" << getName() << "'");
|
||||
usleep(10000);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool eaudiofx::Processing::stateStop() {
|
||||
EAUDIOFX_INFO("Stop Processing : '" << getName() << "'");
|
||||
int32_t ret = eaudiofx::BlockMeta::algoStop();
|
||||
if (ret != eaudiofx::ERR_NONE) {
|
||||
return ret;
|
||||
}
|
||||
algoUnInit();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -13,10 +13,11 @@
|
||||
#include <eaudiofx/core/Buffer.h>
|
||||
#include <eaudiofx/core/Block.h>
|
||||
#include <eaudiofx/core/BlockMeta.h>
|
||||
#include <eaudiofx/Thread.h>
|
||||
#include <vector>
|
||||
|
||||
namespace eaudiofx {
|
||||
class Processing : public eaudiofx::BlockMeta {
|
||||
class Processing : public eaudiofx::BlockMeta, eaudiofx::Thread {
|
||||
protected:
|
||||
Processing() {};
|
||||
void init() {
|
||||
@ -31,6 +32,10 @@ namespace eaudiofx {
|
||||
int32_t stop();
|
||||
int32_t waitEndOfProcess();
|
||||
|
||||
// Thread interface :
|
||||
virtual bool stateStart();
|
||||
virtual bool stateRun();
|
||||
virtual bool stateStop();
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -12,6 +12,7 @@ def create(target):
|
||||
# System core
|
||||
myModule.add_src_file([
|
||||
'eaudiofx/debug.cpp',
|
||||
'eaudiofx/Thread.cpp',
|
||||
'eaudiofx/core/audio.cpp',
|
||||
'eaudiofx/core/Processing.cpp',
|
||||
'eaudiofx/core/Block.cpp',
|
||||
|
@ -53,8 +53,8 @@ void appl::Windows::init() {
|
||||
return;
|
||||
}
|
||||
setSubWidget(m_composer);
|
||||
composerBind(ewol::widget::Button, "bt-play1", signalPressed, shared_from_this(), &appl::Windows::onCallbackPlay);
|
||||
composerBind(ewol::widget::Button, "bt-play2", signalPressed, shared_from_this(), &appl::Windows::onCallbackStop);
|
||||
subBind(ewol::widget::Button, "bt-play1", signalPressed, shared_from_this(), &appl::Windows::onCallbackPlay);
|
||||
subBind(ewol::widget::Button, "bt-play2", signalPressed, shared_from_this(), &appl::Windows::onCallbackStop);
|
||||
}
|
||||
|
||||
std::shared_ptr<eaudiofx::Processing> process = NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user