[DEV] start work with Block request processing

This commit is contained in:
Edouard DUPIN 2015-01-07 21:44:54 +01:00
parent 411ee20918
commit 020a599f17
15 changed files with 490 additions and 267 deletions

250
eaudiofx/Thread.cpp Normal file
View 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
View 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

View File

@ -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

View File

@ -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();

View File

@ -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);
};
};

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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();
};
};

View File

@ -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;
}

View File

@ -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();
};
};

View File

@ -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',

View File

@ -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;