[DEV] change callback name and update the timestamp of the resampler

This commit is contained in:
Edouard DUPIN 2015-02-17 21:08:15 +01:00
parent c667f6c327
commit 01d36bd995
9 changed files with 333 additions and 310 deletions

View File

@ -120,6 +120,7 @@ namespace drain{
* @param[in] _output number of chunk estimate in output
* @return number of sample needed to have nearly the good number of sample
*/
// TODO : Manage the change of the timestamp ...
virtual size_t needInputData(size_t _output);
protected: // note when nothing ==> support all type
std::vector<audio::format> m_supportedFormat;

View File

@ -16,24 +16,24 @@ drain::EndPointCallback::EndPointCallback() :
}
void drain::EndPointCallback::init(needDataFunction _callback) {
void drain::EndPointCallback::init(playbackFunction _callback) {
m_outputFunction = _callback;
drain::EndPoint::init();
m_type = "EndPointCallback";
}
void drain::EndPointCallback::init(haveNewDataFunction _callback) {
void drain::EndPointCallback::init(recordFunction _callback) {
m_inputFunction = _callback;
drain::EndPoint::init();
m_type = "EndPointCallback";
}
std::shared_ptr<drain::EndPointCallback> drain::EndPointCallback::create(needDataFunction _callback) {
std::shared_ptr<drain::EndPointCallback> drain::EndPointCallback::create(playbackFunction _callback) {
std::shared_ptr<drain::EndPointCallback> tmp(new drain::EndPointCallback());
tmp->init(_callback);
return tmp;
}
std::shared_ptr<drain::EndPointCallback> drain::EndPointCallback::create(haveNewDataFunction _callback) {
std::shared_ptr<drain::EndPointCallback> drain::EndPointCallback::create(recordFunction _callback) {
std::shared_ptr<drain::EndPointCallback> tmp(new drain::EndPointCallback());
tmp->init(_callback);
return tmp;
@ -47,21 +47,33 @@ void drain::EndPointCallback::configurationChange() {
bool drain::EndPointCallback::process(std::chrono::system_clock::time_point& _time,
void* _input, // uneeded
size_t _inputNbChunk, // requested number of sample ...
void*& _output,
size_t& _outputNbChunk){
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
drain::AutoLogInOut tmpLog("EndPointCallback");
if (m_inputFunction != nullptr) {
// Call user ...
DRAIN_VERBOSE("call user set " << _inputNbChunk << "*" << m_input.getMap().size());
m_inputFunction(_input,
_time,
_inputNbChunk,
m_output.getFormat(),
m_output.getFrequency(),
m_output.getMap());
return true;
}
if (m_outputFunction != nullptr) {
// update buffer size ...
m_outputData.resize(_inputNbChunk*m_output.getMap().size()*m_formatSize);
// call user
DRAIN_VERBOSE("call user get " << _inputNbChunk << "*" << m_output.getMap().size() << " map=" << m_output.getMap() << " datasize=" << int32_t(m_formatSize));
m_outputFunction(_time,
m_outputFunction(&m_outputData[0],
_time,
_inputNbChunk,
m_output.getMap(),
&m_outputData[0],
m_output.getFormat());
m_output.getFormat(),
m_output.getFrequency(),
m_output.getMap());
if (m_outputData.size() != _inputNbChunk*m_output.getMap().size()*m_formatSize) {
DRAIN_ERROR(" can not get enough data from user ... " << m_outputData.size() << " != " << _inputNbChunk*m_output.getMap().size());
return false;
@ -70,16 +82,6 @@ bool drain::EndPointCallback::process(std::chrono::system_clock::time_point& _ti
_outputNbChunk = _inputNbChunk;
return true;
}
if (m_inputFunction != nullptr) {
// Call user ...
DRAIN_VERBOSE("call user set " << _inputNbChunk << "*" << m_input.getMap().size());
m_inputFunction(_time,
_inputNbChunk,
m_input.getMap(),
_input,
m_input.getFormat());
return true;
}
return false;
}

View File

@ -12,30 +12,32 @@
namespace drain {
typedef std::function<void (const std::chrono::system_clock::time_point& _playTime,
typedef std::function<void (void* _data,
const std::chrono::system_clock::time_point& _playTime,
size_t _nbChunk,
const std::vector<audio::channel>& _map,
void* _data,
enum audio::format _type)> needDataFunction;
typedef std::function<void (const std::chrono::system_clock::time_point& _readTime,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> playbackFunction;
typedef std::function<void (const void* _data,
const std::chrono::system_clock::time_point& _readTime,
size_t _nbChunk,
const std::vector<audio::channel>& _map,
const void* _data,
enum audio::format _type)> haveNewDataFunction;
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> recordFunction;
class EndPointCallback : public EndPoint {
private:
needDataFunction m_outputFunction;
haveNewDataFunction m_inputFunction;
playbackFunction m_outputFunction;
recordFunction m_inputFunction;
protected:
/**
* @brief Constructor
*/
EndPointCallback();
void init(needDataFunction _callback);
void init(haveNewDataFunction _callback);
void init(playbackFunction _callback);
void init(recordFunction _callback);
public:
static std::shared_ptr<EndPointCallback> create(needDataFunction _callback);
static std::shared_ptr<EndPointCallback> create(haveNewDataFunction _callback);
static std::shared_ptr<EndPointCallback> create(playbackFunction _callback);
static std::shared_ptr<EndPointCallback> create(recordFunction _callback);
/**
* @brief Destructor
*/

View File

@ -33,15 +33,15 @@ void drain::EndPointWrite::configurationChange() {
bool drain::EndPointWrite::process(std::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk){
drain::AutoLogInOut tmpLog("EndPointWrite");
//DRAIN_INFO(" nb Sample in buffer : " << m_tmpData.size());
if (m_function != nullptr) {
if (m_tmpData.size() <= 20000) {
m_function(_time, _inputNbChunk, m_output.getMap(), m_output.getFormat());
m_function(_time, _inputNbChunk, m_output.getFormat(), m_output.getFrequency(), m_output.getMap());
}
}
// resize output buffer:

View File

@ -12,14 +12,15 @@
#include <functional>
namespace drain{
typedef std::function<void (const std::chrono::system_clock::time_point& _playTime,
const size_t& _nbChunk,
const std::vector<audio::channel>& _map,
enum audio::format _type)> needDataFunctionWrite;
typedef std::function<void (const std::chrono::system_clock::time_point& _time,
size_t _nbChunk,
enum audio::format _format,
uint32_t _frequency,
const std::vector<audio::channel>& _map)> playbackFunctionWrite;
class EndPointWrite : public EndPoint {
private:
std::vector<int8_t> m_tmpData;
needDataFunctionWrite m_function;
playbackFunctionWrite m_function;
std::mutex m_mutex;
protected:
/**
@ -40,7 +41,7 @@ namespace drain{
void*& _output,
size_t& _outputNbChunk);
virtual void write(const void* _value, size_t _nbChunk);
virtual void setCallback(needDataFunctionWrite _function) {
virtual void setCallback(playbackFunctionWrite _function) {
m_function = _function;
}
};

View File

@ -143,12 +143,8 @@ template<typename T> std::vector<T> getUnion(const std::vector<T>& _out, const s
return out;
}
void drain::Process::updateInterAlgo() {
if (m_isConfigured == true) {
// cahin is already configured
return ;
}
DRAIN_DEBUG("Display properties : nbAlgo : " << m_listAlgo.size());
void drain::Process::displayAlgo() {
DRAIN_DEBUG(" Input : " << m_inputConfig);
for (auto &it : m_listAlgo) {
DRAIN_DEBUG(" [" << it->getType() << "] '" << it->getName() << "'");
@ -170,272 +166,254 @@ void drain::Process::updateInterAlgo() {
}
}
DRAIN_DEBUG(" Output : " << m_outputConfig);
DRAIN_DEBUG("********* configuration START *************");
// TODO : Better management of this ...
/*
if (m_listAlgo.size() == 0) {
DRAIN_ERROR("manage empty drain ...");
return;
}
if (m_listAlgo.size() == 1) {
DRAIN_ERROR("manage Single drain ...");
return;
}
*/
/*
DRAIN_INFO("configuration Input");
if (m_listAlgo.size()>1) {
m_listAlgo[0]->setInputFormat(m_inputConfig);
}
DRAIN_INFO("configuration Output");
if (m_listAlgo.size()>1) {
m_listAlgo[m_listAlgo.size()-1]->setOutputFormat(m_outputConfig);
}
*/
for (size_t iii=0; iii<=m_listAlgo.size(); ++iii) {
DRAIN_VERBOSE(" id = " << iii);
if ( ( iii == 0
|| ( iii > 0
&& m_listAlgo[iii-1]->getOutputFormat().getConfigured() == false
)
)
&& ( iii == m_listAlgo.size()
|| ( iii < m_listAlgo.size()
&& m_listAlgo[iii]->getInputFormat().getConfigured() == false
)
)
) {
// step 1 : check frequency:
std::vector<float> freqOut;
std::vector<float> freqIn;
if (iii == 0) {
freqOut.push_back(m_inputConfig.getFrequency());
} else {
freqOut = m_listAlgo[iii-1]->getFrequencySupportedOutput();
}
void drain::Process::updateAlgo(size_t _position) {
DRAIN_VERBOSE(" id = " << _position);
if ( ( _position == 0
|| ( _position > 0
&& m_listAlgo[_position-1]->getOutputFormat().getConfigured() == false
)
)
&& ( _position == m_listAlgo.size()
|| ( _position < m_listAlgo.size()
&& m_listAlgo[_position]->getInputFormat().getConfigured() == false
)
)
) {
// step 1 : check frequency:
std::vector<float> freqOut;
std::vector<float> freqIn;
if (_position == 0) {
freqOut.push_back(m_inputConfig.getFrequency());
} else {
freqOut = m_listAlgo[_position-1]->getFrequencySupportedOutput();
}
if (_position == m_listAlgo.size()) {
freqIn.push_back(m_outputConfig.getFrequency());
} else {
freqIn = m_listAlgo[_position]->getFrequencySupportedInput();
}
std::vector<float> freq = getUnion<float>(freqOut, freqIn);
DRAIN_VERBOSE(" freq out :" << freqOut);
DRAIN_VERBOSE(" freq in :" << freqIn);
DRAIN_DEBUG(" freq union :" << freq);
// step 2 : Check map:
std::vector<std::vector<audio::channel>> mapOut;
std::vector<std::vector<audio::channel>> mapIn;
if (_position == 0) {
mapOut.push_back(m_inputConfig.getMap());
} else {
mapOut = m_listAlgo[_position-1]->getMapSupportedOutput();
}
if (_position == m_listAlgo.size()) {
mapIn.push_back(m_outputConfig.getMap());
} else {
mapIn = m_listAlgo[_position]->getMapSupportedInput();
}
std::vector<std::vector<audio::channel>> map = getUnion<std::vector<audio::channel>>(mapOut, mapIn);
DRAIN_VERBOSE(" map out :" << mapOut);
DRAIN_VERBOSE(" map in :" << mapIn);
DRAIN_DEBUG(" map union :" << map);
// step 3 : Check Format:
std::vector<audio::format> formatOut;
std::vector<audio::format> formatIn;
if (_position == 0) {
formatOut.push_back(m_inputConfig.getFormat());
} else {
formatOut = m_listAlgo[_position-1]->getFormatSupportedOutput();
}
if (_position == m_listAlgo.size()) {
formatIn.push_back(m_outputConfig.getFormat());
} else {
formatIn = m_listAlgo[_position]->getFormatSupportedInput();
}
std::vector<audio::format> format = getUnion<audio::format>(formatOut, formatIn);
DRAIN_VERBOSE(" format out :" << formatOut);
DRAIN_VERBOSE(" format in :" << formatIn);
DRAIN_DEBUG(" format union :" << format);
if ( freq.size() >= 1
&& map.size() >= 1
&& format.size() >= 1) {
DRAIN_DEBUG(" find 1 compatibility :{format=" << format << ",frequency=" << freq << ",map=" << map << "}");
drain::IOFormatInterface tmp(map[0], format[0], freq[0]);
if (_position > 0) {
m_listAlgo[_position-1]->setOutputFormat(tmp);
}
if (iii == m_listAlgo.size()) {
freqIn.push_back(m_outputConfig.getFrequency());
} else {
freqIn = m_listAlgo[iii]->getFrequencySupportedInput();
if (_position <m_listAlgo.size()) {
m_listAlgo[_position]->setInputFormat(tmp);
}
std::vector<float> freq = getUnion<float>(freqOut, freqIn);
DRAIN_VERBOSE(" freq out :" << freqOut);
DRAIN_VERBOSE(" freq in :" << freqIn);
DRAIN_DEBUG(" freq union :" << freq);
return;
}
// create mapping to transform:
drain::IOFormatInterface out;
drain::IOFormatInterface in;
if (freq.size() > 0) {
out.setFrequency(freq[0]);
in.setFrequency(freq[0]);
} else {
if (freqOut.size() == 0) {
if (freqIn.size() == 0) {
if (_position == 0) {
DRAIN_ERROR("IMPOSSIBLE CASE");
} else {
out.setFrequency(m_listAlgo[_position-1]->getInputFormat().getFrequency());
in.setFrequency(m_listAlgo[_position-1]->getInputFormat().getFrequency());
}
} else {
out.setFrequency(freqIn[0]);
in.setFrequency(freqIn[0]);
}
} else {
if (freqIn.size() == 0) {
out.setFrequency(freqOut[0]);
in.setFrequency(freqOut[0]);
} else {
out.setFrequency(freqOut[0]);
in.setFrequency(freqIn[0]);
}
}
}
if (map.size() > 0) {
out.setMap(map[0]);
in.setMap(map[0]);
} else {
if (mapOut.size() == 0) {
if (mapIn.size() == 0) {
if (_position == 0) {
DRAIN_ERROR("IMPOSSIBLE CASE");
} else {
out.setMap(m_listAlgo[_position-1]->getInputFormat().getMap());
in.setMap(m_listAlgo[_position-1]->getInputFormat().getMap());
}
} else {
out.setMap(mapIn[0]);
in.setMap(mapIn[0]);
}
} else {
if (mapIn.size() == 0) {
out.setMap(mapOut[0]);
in.setMap(mapOut[0]);
} else {
out.setMap(mapOut[0]);
in.setMap(mapIn[0]);
}
}
}
if (format.size() > 0) {
out.setFormat(format[0]);
in.setFormat(format[0]);
} else {
if (formatOut.size() == 0) {
if (formatIn.size() == 0) {
if (_position == 0) {
DRAIN_ERROR("IMPOSSIBLE CASE");
} else {
out.setFormat(m_listAlgo[_position-1]->getInputFormat().getFormat());
in.setFormat(m_listAlgo[_position-1]->getInputFormat().getFormat());
}
} else {
out.setFormat(formatIn[0]);
in.setFormat(formatIn[0]);
}
} else {
if (formatIn.size() == 0) {
out.setFormat(formatOut[0]);
in.setFormat(formatOut[0]);
} else {
out.setFormat(formatOut[0]);
in.setFormat(formatIn[0]);
}
}
}
DRAIN_DEBUG(" update: out=" << out);
DRAIN_DEBUG(" in=" << in);
if (_position > 0) {
m_listAlgo[_position-1]->setOutputFormat(out);
}
if (_position < m_listAlgo.size()) {
m_listAlgo[_position]->setInputFormat(in);
}
// TODO : Add updater with an optimisation of CPU
if (out.getFrequency() != in.getFrequency()) {
// step 2 : Check map:
std::vector<std::vector<audio::channel>> mapOut;
std::vector<std::vector<audio::channel>> mapIn;
if (iii == 0) {
mapOut.push_back(m_inputConfig.getMap());
} else {
mapOut = m_listAlgo[iii-1]->getMapSupportedOutput();
}
if (iii == m_listAlgo.size()) {
mapIn.push_back(m_outputConfig.getMap());
} else {
mapIn = m_listAlgo[iii]->getMapSupportedInput();
}
std::vector<std::vector<audio::channel>> map = getUnion<std::vector<audio::channel>>(mapOut, mapIn);
DRAIN_VERBOSE(" map out :" << mapOut);
DRAIN_VERBOSE(" map in :" << mapIn);
DRAIN_DEBUG(" map union :" << map);
// step 3 : Check Format:
std::vector<audio::format> formatOut;
std::vector<audio::format> formatIn;
if (iii == 0) {
formatOut.push_back(m_inputConfig.getFormat());
} else {
formatOut = m_listAlgo[iii-1]->getFormatSupportedOutput();
}
if (iii == m_listAlgo.size()) {
formatIn.push_back(m_outputConfig.getFormat());
} else {
formatIn = m_listAlgo[iii]->getFormatSupportedInput();
}
std::vector<audio::format> format = getUnion<audio::format>(formatOut, formatIn);
DRAIN_VERBOSE(" format out :" << formatOut);
DRAIN_VERBOSE(" format in :" << formatIn);
DRAIN_DEBUG(" format union :" << format);
if ( freq.size() >= 1
&& map.size() >= 1
&& format.size() >= 1) {
DRAIN_DEBUG(" find 1 compatibility :{format=" << format << ",frequency=" << freq << ",map=" << map << "}");
drain::IOFormatInterface tmp(map[0], format[0], freq[0]);
if (iii > 0) {
m_listAlgo[iii-1]->setOutputFormat(tmp);
}
if (iii <m_listAlgo.size()) {
m_listAlgo[iii]->setInputFormat(tmp);
}
continue;
}
// create mapping to transform:
drain::IOFormatInterface out;
drain::IOFormatInterface in;
if (freq.size() > 0) {
out.setFrequency(freq[0]);
in.setFrequency(freq[0]);
} else {
if (freqOut.size() == 0) {
if (freqIn.size() == 0) {
if (iii == 0) {
DRAIN_ERROR("IMPOSSIBLE CASE");
} else {
out.setFrequency(m_listAlgo[iii-1]->getInputFormat().getFrequency());
in.setFrequency(m_listAlgo[iii-1]->getInputFormat().getFrequency());
}
} else {
out.setFrequency(freqIn[0]);
in.setFrequency(freqIn[0]);
}
} else {
if (freqIn.size() == 0) {
out.setFrequency(freqOut[0]);
in.setFrequency(freqOut[0]);
} else {
out.setFrequency(freqOut[0]);
in.setFrequency(freqIn[0]);
}
}
}
if (map.size() > 0) {
out.setMap(map[0]);
in.setMap(map[0]);
} else {
if (mapOut.size() == 0) {
if (mapIn.size() == 0) {
if (iii == 0) {
DRAIN_ERROR("IMPOSSIBLE CASE");
} else {
out.setMap(m_listAlgo[iii-1]->getInputFormat().getMap());
in.setMap(m_listAlgo[iii-1]->getInputFormat().getMap());
}
} else {
out.setMap(mapIn[0]);
in.setMap(mapIn[0]);
}
} else {
if (mapIn.size() == 0) {
out.setMap(mapOut[0]);
in.setMap(mapOut[0]);
} else {
out.setMap(mapOut[0]);
in.setMap(mapIn[0]);
}
}
}
if (format.size() > 0) {
out.setFormat(format[0]);
in.setFormat(format[0]);
} else {
if (formatOut.size() == 0) {
if (formatIn.size() == 0) {
if (iii == 0) {
DRAIN_ERROR("IMPOSSIBLE CASE");
} else {
out.setFormat(m_listAlgo[iii-1]->getInputFormat().getFormat());
in.setFormat(m_listAlgo[iii-1]->getInputFormat().getFormat());
}
} else {
out.setFormat(formatIn[0]);
in.setFormat(formatIn[0]);
}
} else {
if (formatIn.size() == 0) {
out.setFormat(formatOut[0]);
in.setFormat(formatOut[0]);
} else {
out.setFormat(formatOut[0]);
in.setFormat(formatIn[0]);
}
}
}
DRAIN_DEBUG(" update: out=" << out);
DRAIN_DEBUG(" in=" << in);
if (iii > 0) {
m_listAlgo[iii-1]->setOutputFormat(out);
}
if (iii < m_listAlgo.size()) {
m_listAlgo[iii]->setInputFormat(in);
}
// TODO : Add updater with an optimisation of CPU
if (out.getFrequency() != in.getFrequency()) {
// TODO : Do it better: special check for resampler : only support int16_t
if ( out.getFormat() != audio::format_int16
/* && out.getFormat() != format_float */) {
// need add a format Updater
std::shared_ptr<drain::FormatUpdate> algo = drain::FormatUpdate::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFormat(audio::format_int16);
algo->setOutputFormat(out);
m_listAlgo.insert(m_listAlgo.begin()+iii, algo);
DRAIN_DEBUG("convert " << out.getFormat() << " -> " << in.getFormat());
iii++;
}
// need add a resampler
std::shared_ptr<drain::Resampler> algo = drain::Resampler::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFrequency(in.getFrequency());
algo->setOutputFormat(out);
m_listAlgo.insert(m_listAlgo.begin()+iii, algo);
DRAIN_DEBUG("convert " << out.getFrequency() << " -> " << in.getFrequency());
out.setFrequency(in.getFrequency());
iii++;
}
if (out.getMap() != in.getMap()) {
// need add a channel Reorder
std::shared_ptr<drain::ChannelReorder> algo = drain::ChannelReorder::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setMap(in.getMap());
algo->setOutputFormat(out);
m_listAlgo.insert(m_listAlgo.begin()+iii, algo);
DRAIN_DEBUG("convert " << out.getMap() << " -> " << in.getMap());
iii++;
}
if (out.getFormat() != in.getFormat()) {
// TODO : Do it better: special check for resampler : only support int16_t
if ( out.getFormat() != audio::format_int16
/* && out.getFormat() != format_float */) {
// need add a format Updater
std::shared_ptr<drain::FormatUpdate> algo = drain::FormatUpdate::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFormat(in.getFormat());
out.setFormat(audio::format_int16);
algo->setOutputFormat(out);
m_listAlgo.insert(m_listAlgo.begin()+iii, algo);
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_DEBUG("convert " << out.getFormat() << " -> " << in.getFormat());
iii++;
_position++;
}
} else if ( ( iii > 0
&& m_listAlgo[iii-1]->getOutputFormat().getConfigured() == false
)
|| ( iii < m_listAlgo.size()
&& m_listAlgo[iii]->getInputFormat().getConfigured() == false
)
) {
DRAIN_ERROR(" configuration error mode in " << iii-1 << " && " << iii );
// need add a resampler
std::shared_ptr<drain::Resampler> algo = drain::Resampler::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFrequency(in.getFrequency());
algo->setOutputFormat(out);
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_DEBUG("convert " << out.getFrequency() << " -> " << in.getFrequency());
out.setFrequency(in.getFrequency());
_position++;
}
if (out.getMap() != in.getMap()) {
// need add a channel Reorder
std::shared_ptr<drain::ChannelReorder> algo = drain::ChannelReorder::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setMap(in.getMap());
algo->setOutputFormat(out);
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_DEBUG("convert " << out.getMap() << " -> " << in.getMap());
_position++;
}
if (out.getFormat() != in.getFormat()) {
// need add a format Updater
std::shared_ptr<drain::FormatUpdate> algo = drain::FormatUpdate::create();
algo->setTemporary();
algo->setInputFormat(out);
out.setFormat(in.getFormat());
algo->setOutputFormat(out);
m_listAlgo.insert(m_listAlgo.begin()+_position, algo);
DRAIN_DEBUG("convert " << out.getFormat() << " -> " << in.getFormat());
_position++;
}
} else if ( ( _position > 0
&& m_listAlgo[_position-1]->getOutputFormat().getConfigured() == false
)
|| ( _position < m_listAlgo.size()
&& m_listAlgo[_position]->getInputFormat().getConfigured() == false
)
) {
DRAIN_ERROR(" configuration error mode in " << _position-1 << " && " << _position );
}
}
void drain::Process::updateInterAlgo() {
if (m_isConfigured == true) {
// cahin is already configured
return ;
}
DRAIN_DEBUG("Display properties : nbAlgo : " << m_listAlgo.size());
displayAlgo();
DRAIN_DEBUG("********* configuration START *************");
// configure first the endpoint ...
if (m_listAlgo.size() > 1) {
updateAlgo(m_listAlgo.size());
}
for (size_t iii=0; iii<=m_listAlgo.size(); ++iii) {
updateAlgo(iii);
}
DRAIN_DEBUG("********* configuration will be done *************");
DRAIN_DEBUG(" Input : " << m_inputConfig);
for (auto &it : m_listAlgo) {
DRAIN_DEBUG(" [" << it->getType() << "] '" << it->getName() << "'");
if (it->getInputFormat().getConfigured() == true) {
DRAIN_DEBUG(" Input : " << it->getInputFormat());
} else {
DRAIN_ERROR(" Input : Not configured");
}
if (it->getOutputFormat().getConfigured() == true) {
DRAIN_DEBUG(" Output: " << it->getOutputFormat());
} else {
DRAIN_ERROR(" Output : Not configured");
}
}
DRAIN_DEBUG(" Output : " << m_outputConfig);
displayAlgo();
m_isConfigured = true;
//exit(-1);
}

View File

@ -157,6 +157,9 @@ namespace drain{
public:
void updateInterAlgo();
void removeAlgoDynamic();
private:
void displayAlgo();
void updateAlgo(size_t _position);
};
};

View File

@ -83,12 +83,30 @@ void drain::Resampler::configurationChange() {
#endif
}
namespace std {
static std::ostream& operator <<(std::ostream& _os, const std::chrono::system_clock::time_point& _obj) {
std::chrono::nanoseconds ns = std::chrono::duration_cast<std::chrono::nanoseconds>(_obj.time_since_epoch());
int64_t totalSecond = ns.count()/1000000000;
int64_t millisecond = (ns.count()%1000000000)/1000000;
int64_t microsecond = (ns.count()%1000000)/1000;
int64_t nanosecond = ns.count()%1000;
//_os << totalSecond << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns";
int32_t second = totalSecond % 60;
int32_t minute = (totalSecond/60)%60;
int32_t hour = (totalSecond/3600)%24;
int32_t day = (totalSecond/(24*3600))%365;
int32_t year = totalSecond/(24*3600*365);
_os << year << "y " << day << "d " << hour << "h" << minute << ":"<< second << "s " << millisecond << "ms " << microsecond << "µs " << nanosecond << "ns";
return _os;
}
}
bool drain::Resampler::process(std::chrono::system_clock::time_point& _time,
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
void* _input,
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk) {
drain::AutoLogInOut tmpLog("Resampler");
_outputNbChunk = 2048;
// chack if we need to process:
@ -104,6 +122,12 @@ bool drain::Resampler::process(std::chrono::system_clock::time_point& _time,
DRAIN_ERROR("null pointer input ... ");
return false;
}
// Update Output time with the previous delta of the buffer
DRAIN_VERBOSE("Resampler correct timestamp : " << _time << " ==> " << (_time - m_residualTimeInResampler));
_time -= m_residualTimeInResampler;
std::chrono::nanoseconds inTime((int64_t(_inputNbChunk)*int64_t(1000000000)) / int64_t(m_input.getFrequency()));
m_residualTimeInResampler += inTime;
#ifdef HAVE_SPEEX_DSP_RESAMPLE
float nbInputTime = float(_inputNbChunk)/m_input.getFrequency();
float nbOutputSample = nbInputTime*m_output.getFrequency();
@ -141,6 +165,14 @@ bool drain::Resampler::process(std::chrono::system_clock::time_point& _time,
}
_outputNbChunk = nbChunkOutput;
DRAIN_VERBOSE(" process chunk=" << nbChunkInput << " out=" << nbChunkOutput);
std::chrono::nanoseconds outTime((int64_t(_outputNbChunk)*int64_t(1000000000)) / int64_t(m_output.getFrequency()));
// correct time :
m_residualTimeInResampler -= outTime;
/*
if (m_residualTimeInResampler.count() < 0) {
DRAIN_TODO("manage this case ... residual time in resampler : " << m_residualTimeInResampler.count() << "ns");
}
*/
return true;
#else
_output = _input;

View File

@ -14,6 +14,8 @@
#include <memory>
namespace drain {
// TODO: Manage change timestamp when pull mode
// TODO: drain ...
class Resampler : public Algo {
private:
#ifdef HAVE_SPEEX_DSP_RESAMPLE
@ -41,6 +43,8 @@ namespace drain {
size_t _inputNbChunk,
void*& _output,
size_t& _outputNbChunk);
private:
std::chrono::nanoseconds m_residualTimeInResampler; //!< the time of data locked in the resampler ...
};
};