[DEV] basic decode stream

This commit is contained in:
Edouard DUPIN 2014-03-09 15:08:31 +01:00
parent f60aa1be66
commit d274d793ba
29 changed files with 687 additions and 59 deletions

View File

@ -6,6 +6,75 @@
* @license BSD v3 (see license file)
*/
#include <eaudiofx/debug.h>
#include <eaudiofx/base/GeneratorSignal.h>
#include <eaudiofx/core/BufferStream.h>
#include <eaudiofx/base/GeneratorFile.h>
eaudiofx::GeneratorFile::GeneratorFile(void) :
m_file(NULL) {
// set output :
m_io.insert(
std::pair<std::string, eaudiofx::Block::IOProperty>(
"out",
eaudiofx::Block::IOProperty(
eaudiofx::Block::ioOutput,
"{ type:'bitstream', format:'file' }",
new eaudiofx::BufferStream(*this)
) ) );
}
int32_t eaudiofx::GeneratorFile::pull(double _currentTime, int32_t _request, float _timeout) {
auto it = m_io.find("out");
if (it == m_io.end()) {
EAUDIOFX_WARNING("request to pull data with no output !!!");
return eaudiofx::ERR_FAIL;
}
eaudiofx::BufferStream* buffer = dynamic_cast<eaudiofx::BufferStream*>(it->second.m_buffer);
//EAUDIOFX_ERROR("Generate data, request : " << _request << " at time : " << _currentTime);
if (buffer == NULL) {
// !! impossible case => a buffer can not be removed ...
EAUDIOFX_ERROR("Buffer has been removed... OR change type ...");
return eaudiofx::ERR_FAIL;
}
//request outpuffer needed size :
buffer->setProperty(_request);
uint8_t* data = buffer->getData();
if (m_file == NULL) {
return eaudiofx::ERR_FAIL;
}
int64_t nbRead = m_file->fileRead(data, sizeof(uint8_t), _request);
buffer->setAvaillableSize(nbRead);
return eaudiofx::ERR_NONE;
}
int32_t eaudiofx::GeneratorFile::init(void) {
m_file = new etk::FSNode("./menu.wav");
if (m_file == NULL) {
EAUDIOFX_ERROR("Can not allocate the input file ...");
return eaudiofx::ERR_FAIL;
}
if (m_file->fileOpenRead() == false) {
EAUDIOFX_ERROR("Can not open the input file ...");
return eaudiofx::ERR_FAIL;
}
}
int32_t eaudiofx::GeneratorFile::unInit(void) {
if (m_file == NULL) {
return eaudiofx::ERR_NONE;
}
if (m_file->fileClose() == false) {
EAUDIOFX_ERROR("Can not close the input file ...");
return eaudiofx::ERR_FAIL;
}
}

View File

@ -10,12 +10,19 @@
#define __EAUDIOFX_GENERATOR_FILE_H__
#include <eaudiofx/core/BlockGenerator.h>
#include <etk/os/FSNode.h>
namespace eaudiofx {
class GeneratorFile : public eaudiofx::BlockGenerator {
public:
GeneratorFile(void) {};
GeneratorFile(void);
virtual ~GeneratorFile(void) {};
protected:
etk::FSNode* m_file;
public: // herieted function :
virtual int32_t pull(double _currentTime, int32_t _request, float _timeout);
virtual int32_t init(void);
virtual int32_t unInit(void);
};
};

View File

@ -11,6 +11,7 @@
#include <rtaudio/RtAudio.h>
eaudiofx::GeneratorRtAudio::GeneratorRtAudio(void) {
setLive(true);
// set output :
m_io.insert(
std::pair<std::string, eaudiofx::Block::IOProperty>(

View File

@ -16,6 +16,8 @@ namespace eaudiofx {
public:
GeneratorRtAudio(void);
virtual ~GeneratorRtAudio(void) {};
public:
int32_t pull(double _currentTime, int32_t _request, float _timeout);
};
};

View File

@ -6,9 +6,10 @@
* @license BSD v3 (see license file)
*/
#include <eaudiofx/debug.h>
#include <eaudiofx/base/GeneratorSignal.h>
#include <eaudiofx/core/BufferAudioRaw.h>
#include <math.h>
eaudiofx::GeneratorSignal::GeneratorSignal(void) :
@ -19,9 +20,43 @@ eaudiofx::GeneratorSignal::GeneratorSignal(void) :
"out",
eaudiofx::Block::IOProperty(
eaudiofx::Block::ioOutput,
"",
"{ type:'audio', compression:'raw', frequency:48000, channel:2, format:'float' }",
new eaudiofx::BufferAudioRaw(*this, 48000, 2)
) ) );
}
int32_t eaudiofx::GeneratorSignal::pull(double _currentTime, int32_t _request, float _timeout) {
auto it = m_io.find("out");
if (it == m_io.end()) {
EAUDIOFX_WARNING("request to pull data with no output !!!");
return eaudiofx::ERR_FAIL;
}
eaudiofx::BufferAudioRaw* buffer = dynamic_cast<eaudiofx::BufferAudioRaw*>(it->second.m_buffer);
//EAUDIOFX_ERROR("Generate data, request : " << _request << " at time : " << _currentTime);
if (buffer == NULL) {
// !! impossible case => a buffer can not be removed ...
EAUDIOFX_ERROR("Buffer has been removed... OR change type ...");
return eaudiofx::ERR_FAIL;
}
//request outpuffer needed size :
buffer->setProperty(48000, 2, _request);
float* data = buffer->getData();
for (int32_t iii=0; iii<_request; ++iii) {
for (int32_t jjj=0; jjj<2; ++jjj) {
*data++ = cos(m_phase)*0.5f;
}
m_phase += 0.1;
if (m_phase > 4.0*M_PI) {
m_phase -= 4.0*M_PI;
}
}
/*
FILE* plopppp = fopen("plop.raw", "a");
fwrite(buffer->getData(), sizeof(float), _request*2, plopppp);
fflush(plopppp);
fclose(plopppp);
*/
return eaudiofx::ERR_NONE;
}

View File

@ -18,6 +18,8 @@ namespace eaudiofx {
public:
GeneratorSignal(void);
virtual ~GeneratorSignal(void) {};
public:
int32_t pull(double _currentTime, int32_t _request, float _timeout);
};
};

View File

@ -38,39 +38,53 @@ int32_t eaudiofx::ReceiverRtAudio::needData(float* _outputBuffer,
size_t _nBufferFrames,
double _streamTime,
RtAudioStreamStatus _status) {
// TODO: reset output:
// Request block input:
int32_t nbSampleOne = _nBufferFrames/2;
int32_t ret = eaudiofx::Block::pull(_streamTime, nbSampleOne, (float)nbSampleOne/48000.0f);
int32_t ret = eaudiofx::Block::pull(_streamTime, _nBufferFrames, (float)_nBufferFrames/48000.0f);
if (ret != eaudiofx::ERR_NONE) {
EAUDIOFX_ERROR("wan 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;
}
// TODO : Do the copy of data ...
float* data = buffer->getData();
for (int32_t iii=0; iii<_nBufferFrames*2; ++iii) {
_outputBuffer[iii] = data[iii]*0.05f;
}
/*
FILE* plopppp = fopen("plopout.raw", "a");
fwrite(_outputBuffer, sizeof(float), _nBufferFrames, plopppp);
fflush(plopppp);
fclose(plopppp);
*/
return 0;
}
eaudiofx::ReceiverRtAudio::ReceiverRtAudio(void) {
setLive(true);
// set output :
m_io.insert(
std::pair<std::string, eaudiofx::Block::IOProperty>(
"in",
eaudiofx::Block::IOProperty(
eaudiofx::Block::ioInput,
"",
new eaudiofx::BufferAudioRaw(*this, 48000, 2)
"{ type:'audio', compression:'raw', frequency:48000, channel:2, format:'float' }",
NULL
) ) );
};
int32_t eaudiofx::ReceiverRtAudio::Init(void) {
int32_t eaudiofx::ReceiverRtAudio::init(void) {
EAUDIOFX_DEBUG("Create RTAudio generator ...");
if ( m_dac.getDeviceCount() < 1 ) {
EAUDIOFX_ERROR("No audio devices found!");
@ -84,7 +98,7 @@ int32_t eaudiofx::ReceiverRtAudio::Init(void) {
unsigned int bufferFrames = 256;
try {
EAUDIOFX_DEBUG("OPEN Stream ...");
m_dac.openStream( &m_parameters, NULL, RTAUDIO_FLOAT32, 48000, &bufferFrames, &rtAudioCallBack, (void *)this );
m_dac.openStream(&m_parameters, NULL, RTAUDIO_FLOAT32, 48000, &bufferFrames, &rtAudioCallBack, (void *)this);
m_dac.startStream();
}catch ( RtError& e ) {
e.printMessage();
@ -93,7 +107,7 @@ int32_t eaudiofx::ReceiverRtAudio::Init(void) {
return eaudiofx::ERR_NONE;
};
int32_t eaudiofx::ReceiverRtAudio::UnInit(void) {
int32_t eaudiofx::ReceiverRtAudio::unInit(void) {
try {
EAUDIOFX_DEBUG("STOP Stream ...");
// Stop the stream

View File

@ -30,9 +30,9 @@ namespace eaudiofx {
ReceiverRtAudio(void);
virtual ~ReceiverRtAudio(void) {};
public: // herieted function :
virtual int32_t Init(void);
virtual int32_t UnInit(void);
private:
virtual int32_t init(void);
virtual int32_t unInit(void);
protected:
RtAudio m_dac;
RtAudio::StreamParameters m_parameters;
};

View File

@ -39,6 +39,24 @@ eaudiofx::Block::~Block(void) {
}
}
int32_t eaudiofx::Block::pull(double _currentTime, int32_t _request, float _timeout) {
int32_t ret = eaudiofx::ERR_NONE;
for (auto &it : m_io) {
if (it.second.m_buffer == NULL) {
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;
@ -51,6 +69,33 @@ void eaudiofx::Block::subRemoveBuffer(const eaudiofx::Buffer* _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) {
@ -59,14 +104,20 @@ void eaudiofx::Block::onRemoveBuffer(const eaudiofx::Buffer* _buffer) {
}
}
int32_t eaudiofx::Block::linkBuffer(eaudiofx::Buffer* _buffer, const std::string& _name) {
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 = _buffer;
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;
}
}
@ -74,6 +125,9 @@ int32_t eaudiofx::Block::linkBuffer(eaudiofx::Buffer* _buffer, const std::string
}
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) {

View File

@ -109,14 +109,14 @@ namespace eaudiofx {
* @brief Init the block with the properties
* @return A generic error.
*/
virtual int32_t Init(void) {
virtual int32_t init(void) {
return eaudiofx::ERR_NONE;
};
/**
* @brief UnInit the block with the properties
* @return A generic error.
*/
virtual int32_t UnInit(void) {
virtual int32_t unInit(void) {
return eaudiofx::ERR_NONE;
};
/**
@ -126,9 +126,7 @@ namespace eaudiofx {
* @param[in] _timeout system time to be obsolet (for realTime streaming) (-1 for no realTime streaming)
* @return generic error
*/
virtual int32_t pull(double _currentTime, int32_t _request, float _timeout) {
return eaudiofx::ERR_NONE;
};
virtual int32_t pull(double _currentTime, int32_t _request, float _timeout);
/**
* @brief Get The total stream size (in byte for streaming byte element, in second for time streaming)
* @param[out] _value Get total streaming time (-1 for unknown)
@ -205,6 +203,7 @@ namespace eaudiofx {
}
};
std::map<std::string, eaudiofx::Block::IOProperty> m_io; //!< All IO in the Block
public:
/**
* @brief Link the provided buffer to the IO name.
* @param[in] _buffer Pointer on the buffer to link.
@ -212,6 +211,15 @@ namespace eaudiofx {
* @return A generic error.
*/
virtual int32_t linkBuffer(eaudiofx::Buffer* _buffer, const std::string& _name);
/**
* @brief Un link a speific buffer to the IO name.
* @param[in] _buffer Pointer on the buffer to unlink.
* @param[in] _name Name of the IO to unlink;
* @return A generic error.
*/
virtual int32_t unLinkBuffer(const eaudiofx::Buffer* _buffer);
//! @previous
virtual int32_t unLinkBuffer(const std::string& _name);
/**
* @brief Request a buffer pointer on the IO named.
* @param[out] _buffer Pointer on the buffer to link.
@ -219,6 +227,13 @@ namespace eaudiofx {
* @return A generic error.
*/
virtual int32_t getBuffer(eaudiofx::Buffer*& _buffer, const std::string& _name);
/**
* @brief Update the IO property
* @return A generic error.
*/
virtual int32_t UpdateIOProperty(void) {
return eaudiofx::ERR_NONE;
};
};
};

View File

@ -6,10 +6,130 @@
* @license BSD v3 (see license file)
*/
#include <eaudiofx/debug.h>
#include <eaudiofx/base/GeneratorSignal.h>
#include <eaudiofx/core/BufferStream.h>
#include <eaudiofx/core/BufferAudioRaw.h>
#include <eaudiofx/core/BlockDecoder.h>
eaudiofx::BlockDecoder::BlockDecoder(void) {
eaudiofx::BlockDecoder::BlockDecoder(void) :
m_nbSampleIn(0) {
setType(eaudiofx::blockTypeDecoder);
// set input :
m_io.insert(
std::pair<std::string, eaudiofx::Block::IOProperty>(
"in",
eaudiofx::Block::IOProperty(
eaudiofx::Block::ioInput,
"{ type:'bitstream', format:'file', extention:['wav','ogg'] }"
) ) );
// set output :
m_io.insert(
std::pair<std::string, eaudiofx::Block::IOProperty>(
"out",
eaudiofx::Block::IOProperty(
eaudiofx::Block::ioOutput,
"{ type:'audio', compression:'raw', frequency:48000, channel:2, format:'float' }",
new eaudiofx::BufferAudioRaw(*this, 48000, 2, 4096)
) ) );
}
int32_t eaudiofx::BlockDecoder::pull(double _currentTime, int32_t _request, float _timeout) {
auto itOut = m_io.find("out");
if (itOut == m_io.end()) {
EAUDIOFX_WARNING("request to pull data with no output !!!");
return eaudiofx::ERR_FAIL;
}
auto itIn = m_io.find("in");
if (itIn == m_io.end()) {
EAUDIOFX_WARNING("request to pull data with no Input !!!");
return eaudiofx::ERR_FAIL;
}
eaudiofx::BufferAudioRaw* bufferOut = dynamic_cast<eaudiofx::BufferAudioRaw*>(itOut->second.m_buffer);
if (bufferOut == NULL) {
// !! impossible case => a buffer can not be removed ...
EAUDIOFX_ERROR("Buffer has been removed... OR change type ...");
return eaudiofx::ERR_FAIL;
}
//request outpuffer needed size :
bufferOut->setProperty(48000, 2, _request);
float* dataOut = bufferOut->getData();
int32_t offset = 0;
EAUDIOFX_DEBUG("Request data : " << (_request*2) );
while (1) {
int32_t nbSampleToCopy = etk_min(m_nbSampleIn, _request*2 - offset);
if (m_nbSampleIn > 0) {
// no pull needed ==> just copy data to output ...
for (int32_t iii=0; iii < nbSampleToCopy; ++iii) {
dataOut[offset + iii] = m_tmpBuffer[iii];
}
offset += nbSampleToCopy;
m_nbSampleIn -= nbSampleToCopy;
if (m_nbSampleIn > 0) {
// some data in the buffer ==> move it ...
for (int32_t iii=0; iii < MAX_DATA_IN_BUFFER-nbSampleToCopy; ++iii) {
m_tmpBuffer[iii] = m_tmpBuffer[nbSampleToCopy+iii];
}
}
if (offset == _request*2) {
FILE* plopppp = fopen("plopDEC.raw", "a");
fwrite(dataOut, sizeof(float), _request*2, plopppp);
fflush(plopppp);
fclose(plopppp);
// putput have enought data
return eaudiofx::ERR_NONE;
}
}
// Request block input:
int32_t ret = eaudiofx::Block::pull(_currentTime, 256, _timeout);
if (ret != eaudiofx::ERR_NONE) {
EAUDIOFX_ERROR("can not get data ...");
return -1;
}
eaudiofx::BufferStream* bufferIn = dynamic_cast<eaudiofx::BufferStream*>(itIn->second.m_buffer);
if (bufferIn == NULL) {
// !! impossible case => a buffer can not be removed ...
EAUDIOFX_ERROR("Buffer has been removed... OR change type ...");
return eaudiofx::ERR_FAIL;
}
if (bufferIn->setAvaillableSize() == 0) {
for (size_t iii=0; iii<64; ++iii) {
m_tmpBuffer[m_nbSampleIn] = 0.0f;
m_nbSampleIn++;
m_tmpBuffer[m_nbSampleIn] = 0.0f;
m_nbSampleIn++;
}
}
if (true == true) {
// wav input :
// TODO : Do it better ...
size_t provideData = bufferIn->setAvaillableSize();
int16_t* inputData = (int16_t*)bufferIn->getData();
for (size_t iii=0; iii<provideData/2; ++iii) {
m_tmpBuffer[m_nbSampleIn] = ((double)inputData[iii]) * 0.000030518; // 1/32768
m_nbSampleIn++;
m_tmpBuffer[m_nbSampleIn] = ((double)inputData[iii]) * 0.000030518; // 1/32768
m_nbSampleIn++;
}
}
EAUDIOFX_DEBUG("internal FIFO : " << m_nbSampleIn );
}
return eaudiofx::ERR_NONE;
}
int32_t eaudiofx::BlockDecoder::init(void) {
}
int32_t eaudiofx::BlockDecoder::unInit(void) {
}

View File

@ -13,9 +13,17 @@
namespace eaudiofx {
class BlockDecoder : public eaudiofx::Block {
#define MAX_DATA_IN_BUFFER (8*1024)
public:
BlockDecoder(void);
virtual ~BlockDecoder(void) {};
public: // herited function
int32_t pull(double _currentTime, int32_t _request, float _timeout);
int32_t init(void);
int32_t unInit(void);
protected:
float m_tmpBuffer[MAX_DATA_IN_BUFFER]; //!< internal buffer with data ...
int32_t m_nbSampleIn; //<! number of sample in the tmpBuffer.
};
};

View File

@ -8,9 +8,8 @@
#include <eaudiofx/core/BlockGenerator.h>
eaudiofx::BlockGenerator::BlockGenerator(void) {
eaudiofx::BlockGenerator::BlockGenerator(void) :
m_isLive(false) {
setType(eaudiofx::blockTypeGenerator);
}

View File

@ -16,6 +16,25 @@ namespace eaudiofx {
public:
BlockGenerator(void);
virtual ~BlockGenerator(void) {};
private:
bool m_isLive; //!< a generator mark as a live element is manage by an external event system like IO interuption
public:
/**
* @brief Get if the genertor is a live stream
* @return true This is a live stream
* @return false This is not a live stream
*/
bool getLive(void) {
return m_isLive;
}
/**
* @brief Set the new status of live stream.
* @param[in] _isLive status requested.
*/
void setLive(bool _isLive=true) {
m_isLive = _isLive;
}
};
};

View File

@ -28,6 +28,21 @@ eaudiofx::BlockMeta::~BlockMeta(void) {
m_list.clear();
}
eaudiofx::Block* eaudiofx::BlockMeta::getBlock(const std::string& _name) {
if (_name.size() == 0) {
return NULL;
}
for (auto &it : m_list) {
if (it == NULL) {
continue;
}
if (it->getName() == _name) {
return it;
}
}
return NULL;
}
int32_t eaudiofx::BlockMeta::addBlock(eaudiofx::Block* _block) {
if (_block == NULL) {
EAUDIOFX_ERROR("[" << getUID() << "] Add NULL block");
@ -68,8 +83,28 @@ int32_t eaudiofx::BlockMeta::linkBlock(const std::string& _generatorBlockName,
const std::string& _generatorIoName,
const std::string& _receiverBlockName,
const std::string& _receiverIoName) {
return eaudiofx::ERR_NOT_IMPLEMENTED;
eaudiofx::Block* itGenerator = getBlock(_generatorBlockName);
eaudiofx::Block* itReceiver = getBlock(_receiverBlockName);
if ( itGenerator == NULL
|| itReceiver == NULL) {
EAUDIOFX_ERROR("Can not link : '" << _generatorBlockName << "' and '" << _receiverBlockName << "' one element does not exist ...");
return eaudiofx::ERR_FAIL;
}
eaudiofx::Buffer* outputBuffer = NULL;
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 << "'");
return eaudiofx::ERR_FAIL;
}
if (itReceiver->linkBuffer(outputBuffer, _receiverIoName) != eaudiofx::ERR_NONE) {
EAUDIOFX_ERROR("Can not Link buffer : '" << _receiverBlockName << "':'" << _receiverIoName << "'");
return eaudiofx::ERR_FAIL;
}
EAUDIOFX_INFO("Link : " << _generatorBlockName << ":" << _generatorIoName << " and " << _receiverBlockName << ":" << _receiverIoName);
return eaudiofx::ERR_NONE;
}
int32_t eaudiofx::BlockMeta::openFile(const std::string& _fileName) {
@ -82,3 +117,37 @@ int32_t eaudiofx::BlockMeta::openStream(const std::string& _stream) {
return eaudiofx::ERR_NOT_IMPLEMENTED;
}
int32_t eaudiofx::BlockMeta::init(void) {
EAUDIOFX_INFO("[" << getUID() << "]Init Meta block : '" << getName() << "'");
int32_t ret = eaudiofx::ERR_NONE;
for (auto &it : m_list) {
if (it == NULL) {
continue;
}
if (it->init() != eaudiofx::ERR_NONE) {
ret = eaudiofx::ERR_FAIL;
}
}
if (ret != eaudiofx::ERR_NONE) {
EAUDIOFX_WARNING("Pb when init the Meta-block '" << getName() << "' ");
}
return ret;
};
int32_t eaudiofx::BlockMeta::unInit(void) {
int32_t ret = eaudiofx::ERR_NONE;
for (auto &it : m_list) {
if (it == NULL) {
continue;
}
if (it->unInit() != eaudiofx::ERR_NONE) {
ret = eaudiofx::ERR_FAIL;
}
}
if (ret != eaudiofx::ERR_NONE) {
EAUDIOFX_WARNING("Pb when un-init the Meta-block '" << getName() << "' ");
}
return ret;
};

View File

@ -19,6 +19,13 @@ namespace eaudiofx {
virtual ~BlockMeta(void);
private:
std::vector<eaudiofx::Block*> m_list; //!< list of all block to process.
protected:
/**
* @brief Get a pointer on a specific block.
* @param[in] _name Name of the block.
* @return generic error
*/
eaudiofx::Block* getBlock(const std::string& _name);
public:
/**
* @brief Add a block in the Meta-block
@ -72,6 +79,9 @@ namespace eaudiofx {
* @return generic error
*/
int32_t openStream(const std::string& _stream);
public: // herited function
virtual int32_t init(void);
virtual int32_t unInit(void);
};
};

View File

@ -8,7 +8,8 @@
#include <eaudiofx/core/BlockReceiver.h>
eaudiofx::BlockReceiver::BlockReceiver(void) {
eaudiofx::BlockReceiver::BlockReceiver(void) :
m_isLive(false) {
setType(eaudiofx::blockTypeReceiver);
}

View File

@ -16,6 +16,24 @@ namespace eaudiofx {
public:
BlockReceiver(void);
virtual ~BlockReceiver(void) {};
private:
bool m_isLive; //!< a generator mark as a live element is manage by an external event system like IO interuption
public:
/**
* @brief Get if the genertor is a live stream
* @return true This is a live stream
* @return false This is not a live stream
*/
bool getLive(void) {
return m_isLive;
}
/**
* @brief Set the new status of live stream.
* @param[in] _isLive status requested.
*/
void setLive(bool _isLive=true) {
m_isLive = _isLive;
}
};
};

View File

@ -13,6 +13,16 @@
eaudiofx::Buffer::Buffer(eaudiofx::Block& _parent) :
m_parent(_parent),
m_timestamp(0),
m_time(0) {
m_time(0),
m_negociated(false) {
}
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

@ -23,6 +23,25 @@ namespace eaudiofx {
protected:
double m_timestamp; //!< current buffer time;
double m_time; //!< current buffer data time size;
public:
int32_t pull(double _currentTime, int32_t _request, float _timeout);
protected:
bool m_negociated; //!< negiciation status.
public:
/**
* @brief Get if the IO buffer status is negociated.
* @return true if buffer is negosiated.
* @return false Not negociated.
*/
bool isNegociated(void) {
return m_negociated;
}
/**
* @brief uset the negociation status of the buffer.
*/
void requestNewNegociation(void) {
m_negociated = false;
}
};
};

View File

@ -31,17 +31,25 @@ eaudiofx::BufferAudio::~BufferAudio(void) {
if (m_data != NULL) {
delete[] m_data;
m_data = NULL;
m_allocated = 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;
}
}

View File

@ -25,3 +25,21 @@ eaudiofx::BufferAudioRaw::BufferAudioRaw(eaudiofx::Block& _parent, int32_t _freq
EAUDIOFX_INFO("Resize the buffer : " << m_frequency << "Hz, " << m_nbChannel << " channel(s), " << m_allocatedSample << " sample(s)");
resize(m_nbChannel*m_allocatedSample);
}
void eaudiofx::BufferAudioRaw::setProperty(int32_t _frequency, int32_t _nbChannel, int32_t _nbSample) {
bool increaseSize = false;
if (_nbSample > m_allocatedSample) {
m_allocatedSample = _nbSample;
increaseSize = true;
}
if (_nbChannel > m_nbChannel) {
increaseSize = true;
}
m_nbChannel = _nbChannel;
m_frequency = _frequency;
if (increaseSize == true) {
EAUDIOFX_INFO("Resize the buffer : " << m_frequency << "Hz, " << m_nbChannel << " channel(s), " << m_allocatedSample << " sample(s)");
resize(m_nbChannel*m_allocatedSample);
}
}

View File

@ -23,6 +23,8 @@ namespace eaudiofx {
size_t m_size; //!< number of sample for each channels provided in this buffer ... (write by the upstream (can be 0))
protected:
size_t m_sizeRequested; //!< in pull mode, number of sample for each channels requested by the next Filter
public:
void setProperty(int32_t _frequency, int32_t _nbChannel, int32_t _nbSample);
};
};

View File

@ -6,12 +6,46 @@
* @license BSD v3 (see license file)
*/
#include <eaudiofx/debug.h>
#include <eaudiofx/core/BufferStream.h>
eaudiofx::BufferStream::BufferStream(eaudiofx::Block& _parent) :
eaudiofx::Buffer(_parent) {
eaudiofx::Buffer(_parent),
m_data(NULL),
m_allocated(0),
m_size(0) {
}
eaudiofx::BufferStream::~BufferStream(void) {
if (m_data != NULL) {
delete[] m_data;
m_data = NULL;
m_allocated = 0;
}
}
void eaudiofx::BufferStream::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 uint8_t[_newSize];
if (m_data == NULL) {
EAUDIOFX_ERROR("Can not allocate Buffer Audio");
} else {
m_allocated = _newSize;
}
}
void eaudiofx::BufferStream::setProperty(int32_t _dataSize) {
if (_dataSize<=0) {
return;
}
resize(_dataSize);
}

View File

@ -17,12 +17,32 @@ namespace eaudiofx {
BufferStream(eaudiofx::Block& _parent);
virtual ~BufferStream(void);
protected:
void* m_data; //!< buffer data
uint8_t* m_data; //!< buffer data
size_t m_allocated; //!< number of byte allocated
protected:
size_t m_size; //!< number of byte provided in this buffer ... (write by the upstream (can be 0))
public:
void setAvaillableSize(size_t _availlableSize) {
m_size = _availlableSize;
}
size_t setAvaillableSize(void) {
return m_size;
}
public:
void setProperty(int32_t _dataSize);
protected:
size_t m_sizeRequested; //!< in pull mode, number of byte requested by the next Filter
/**
* @brief Reallocate the Buffer data.
*/
virtual void resize(size_t _newSize);
public:
/**
* @brief Get the buffer casted in float*
* @return Pointer on the buffer with correct cast.
*/
uint8_t* getData(void) {
return m_data;
}
};
};

View File

@ -6,10 +6,26 @@
* @license BSD v3 (see license file)
*/
#include <eaudiofx/debug.h>
#include <eaudiofx/core/Processing.h>
int32_t eaudiofx::Processing::process(void) {
EAUDIOFX_INFO("Start process : '" << getName() << "'");
return eaudiofx::ERR_NONE;
}
int32_t eaudiofx::Processing::start(void) {
EAUDIOFX_INFO("Start Processing : '" << getName() << "'");
return init();
}
int32_t eaudiofx::Processing::stop(void) {
EAUDIOFX_INFO("Stop Processing : '" << getName() << "'");
return unInit();
}
int32_t eaudiofx::Processing::waitEndOfProcess(void) {
EAUDIOFX_INFO("wait end of Processing : '" << getName() << "'");
return eaudiofx::ERR_NONE;
}

View File

@ -22,6 +22,12 @@ namespace eaudiofx {
virtual ~Processing(void) {};
public:
int32_t process(void);
int32_t start(void);
int32_t stop(void);
int32_t waitEndOfProcess(void);
bool isLiveStream(void) {
return false;
}
};
};

View File

@ -77,6 +77,7 @@ namespace eaudiofx {
enum {
ERR_NONE = 0,
ERR_NOT_IMPLEMENTED,
ERR_FAIL,
ERR_ALREADY_EXIST,
ERR_INPUT_NULL,
ERR_FORBIDEN,

View File

@ -12,6 +12,9 @@
#include <ewol/widget/Label.h>
#include <etk/tool.h>
#include <eaudiofx/eaudiofx.h>
#include <eaudiofx/base/GeneratorFile.h>
#include <eaudiofx/core/BlockDecoder.h>
#include <eaudiofx/base/GeneratorSignal.h>
#include <eaudiofx/base/ReceiverRtAudio.h>
@ -60,36 +63,84 @@ void appl::Windows::onObjectRemove(ewol::Object * _removeObject) {
}
}
eaudiofx::Processing* process = NULL;
void appl::Windows::onReceiveMessage(const ewol::object::Message& _msg) {
if (_msg.getMessage() == g_eventPlay1) {
APPL_ERROR("Play Requested ...");
eaudiofx::Processing* process = new eaudiofx::Processing();
if (process == NULL) {
APPL_ERROR("can not create processing ...");
#if 0
APPL_INFO("Play Requested ...");
process = new eaudiofx::Processing();
if (process == NULL) {
APPL_ERROR("can not create processing ...");
return;
}
APPL_INFO("Create Generator ...");
eaudiofx::GeneratorSignal* generator = new eaudiofx::GeneratorSignal();
if (generator == NULL) {
APPL_ERROR("can not create Generator ...");
return;
}
generator->setName("myGenerator");
process->addBlock(generator);
APPL_INFO("Create Receiver ...");
eaudiofx::ReceiverRtAudio* receiver = new eaudiofx::ReceiverRtAudio();
if (receiver == NULL) {
APPL_ERROR("can not create Receiver ...");
return;
}
receiver->setName("myReceiver");
process->addBlock(receiver);
process->linkBlock("myGenerator", "out","myReceiver", "in");
process->start();
return;
}
APPL_ERROR("Create Generator ...");
eaudiofx::GeneratorSignal* generator = new eaudiofx::GeneratorSignal();
if (generator == NULL) {
APPL_ERROR("can not create Generator ...");
#else
APPL_INFO("Play Requested ...");
process = new eaudiofx::Processing();
if (process == NULL) {
APPL_ERROR("can not create processing ...");
return;
}
APPL_INFO("Create Generator ...");
eaudiofx::GeneratorFile* generator = new eaudiofx::GeneratorFile();
if (generator == NULL) {
APPL_ERROR("can not create Generator ...");
return;
}
generator->setName("myGenerator");
process->addBlock(generator);
APPL_INFO("Create DECODER ...");
eaudiofx::BlockDecoder* decoder = new eaudiofx::BlockDecoder();
if (decoder == NULL) {
APPL_ERROR("can not create Generator ...");
return;
}
decoder->setName("myDecoder");
process->addBlock(decoder);
APPL_INFO("Create Receiver ...");
eaudiofx::ReceiverRtAudio* receiver = new eaudiofx::ReceiverRtAudio();
if (receiver == NULL) {
APPL_ERROR("can not create Receiver ...");
return;
}
receiver->setName("myReceiver");
process->addBlock(receiver);
process->linkBlock("myGenerator", "out","myDecoder", "in");
process->linkBlock("myDecoder", "out","myReceiver", "in");
process->start();
return;
}
generator->setName("myGenerator");
process->addBlock(generator);
APPL_ERROR("Create Receiver ...");
eaudiofx::ReceiverRtAudio* receiver = new eaudiofx::ReceiverRtAudio();
if (receiver == NULL) {
APPL_ERROR("can not create Receiver ...");
return;
}
receiver->setName("myReceiver");
process->addBlock(receiver);
process->process();
return;
#endif
}
if (_msg.getMessage() == g_eventPlay2) {
if (process != NULL) {
process->stop();
}
return;
}
}