[DEV] some River rework

This commit is contained in:
Edouard DUPIN 2015-03-12 22:28:15 +01:00
parent ec4eae4242
commit f9ae8f23bd
17 changed files with 533 additions and 281 deletions

135
data/hardwareNao.json Normal file
View File

@ -0,0 +1,135 @@
{
speaker:{
io:"output",
map-on:{
interface:"alsa",
name:"AD1989A_outputs",
timestamp-mode:"trigered",
},
frequency:48000,
channel-map:[
"front-left", "front-right",
],
type:"int16",
nb-chunk:6000,
volume-name:"MASTER",
mux-demux-type:"int16-on-int32",
},
microphone:{
io:"input",
map-on:{
interface:"alsa",
name:"AD1989A_inputs",
timestamp-mode:"trigered",
},
frequency:48000,
channel-map:[
"front-left", "front-right"
, "rear-left", "rear-right"
],
type:"int16",
nb-chunk:6000,
mux-demux-type:"int16",
},
speakerGroup:{
io:"output",
map-on:{
interface:"alsa",
name:"hw:0,0",
timestamp-mode:"trigered",
},
group:"baseIOSynchrone",
frequency:48000,
channel-map:[
"front-left", "front-right",
],
type:"int16",
nb-chunk:1024,
volume-name:"MASTER",
mux-demux-type:"int16-on-int32",
},
microphone-front:{
io:"input",
map-on:{
interface:"alsa",
name:"hw:0,0,0",
timestamp-mode:"trigered",
},
group:"baseIOSynchrone",
frequency:48000,
channel-map:[
"front-left", "front-right"
],
type:"int16",
nb-chunk:1024,
mux-demux-type:"int16",
},
microphone-rear:{
io:"input",
map-on:{
interface:"alsa",
name:"hw:0,0,1",
timestamp-mode:"trigered",
},
group:"baseIOSynchrone",
frequency:48000,
channel-map:[
"rear-left", "rear-right"
],
type:"int16",
nb-chunk:1024,
mux-demux-type:"int16",
},
# virtual Nodes :
microphone-clean:{
io:"aec",
# connect in input mode
map-on-microphone:{
# generic virtual definition
io:"input",
map-on:"microphone-muxed",
resampling-type:"speexdsp",
resampling-option:"quality=10"
},
# connect in feedback mode
map-on-feedback:{
io:"feedback",
map-on:"speaker",
resampling-type:"speexdsp",
resampling-option:"quality=10",
},
#classical format configuration:
frequency:16000,
channel-map:[
"front-left", "front-right", "rear-left", "rear-right"
],
type:"int16",
# AEC algo definition
algo:"river-remover",
algo-mode:"cutter",
feedback-delay:10000, # in nanosecond
mux-demux-type:"int16",
},
microphone-muxed:{
io:"muxer",
map-on-input-1:{
# generic virtual definition
io:"input",
map-on:"microphone-front",
resampling-type:"speexdsp",
resampling-option:"quality=10"
},
map-on-input-2:{
io:"input",
map-on:"microphone-rear",
resampling-type:"speexdsp",
resampling-option:"quality=10",
},
frequency:48000,
channel-map:[
"front-left", "front-right", "rear-left", "rear-right"
],
type:"int16",
mux-demux-type:"int16",
},
}

View File

@ -1,38 +0,0 @@
{
# name of the virtual interface
microphone:{
# input or output
io:"input",
# name of the harware device
map-on:"microphone",
# name of the resampler
resampling-type:"speexdsp",
# some option to the resampler
resampling-option:"quality=10"
},
speaker:{
io:"output",
map-on:"speaker",
resampling-type:"speexdsp",
resampling-option:"quality=10"
},
feedback:{
# note : Feedback is plugged on an output not an input
io:"feedback",
map-on:"speaker",
resampling-type:"speexdsp",
resampling-option:"quality=10"
},
microphone-clean:{
io:"input",
map-on:"microphone-clean",
resampling-type:"speexdsp",
resampling-option:"quality=10"
},
microphone-muxed:{
io:"input",
map-on:"microphone-muxed",
resampling-type:"speexdsp",
resampling-option:"quality=10"
},
}

View File

@ -12,6 +12,7 @@ def create(target):
myModule.add_src_file([
'river/debug.cpp',
'river/river.cpp',
'river/Manager.cpp',
'river/Interface.cpp',
'river/CircularBuffer.cpp',

View File

@ -28,7 +28,6 @@ def create(target):
else:
debug.warning("unknow target for AIRTAudio : " + target.name);
myModule.copy_file('data/virtual.json', 'virtual.json')
myModule.add_module_depend(['river', 'gtest', 'etk'])
# add the currrent module at the

View File

@ -18,26 +18,23 @@
river::Interface::Interface(void) :
m_node(),
m_name(""),
m_volume(0.0f) {
m_name("") {
static uint32_t uid = 0;
m_uid = uid++;
}
bool river::Interface::init(const std::string& _name,
float _freq,
bool river::Interface::init(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std11::shared_ptr<river::io::Node>& _node,
const std11::shared_ptr<const ejson::Object>& _config) {
std::vector<audio::channel> map(_map);
m_name = _name;
m_node = _node;
m_volume = 0.0f;
m_config = _config;
m_mode = river::modeInterface_unknow;
std::string type = m_config->getStringValue("io", "error");
m_name = _node->getName() + "__" + (_node->isInput()==true?"input":"output") + "__" + type;
if (type == "output") {
m_mode = river::modeInterface_output;
} else if (type == "input") {
@ -97,14 +94,13 @@ bool river::Interface::init(const std::string& _name,
return true;
}
std11::shared_ptr<river::Interface> river::Interface::create(const std::string& _name,
float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std11::shared_ptr<river::io::Node>& _node,
const std11::shared_ptr<const ejson::Object>& _config) {
std11::shared_ptr<river::Interface> river::Interface::create(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std11::shared_ptr<river::io::Node>& _node,
const std11::shared_ptr<const ejson::Object>& _config) {
std11::shared_ptr<river::Interface> out = std11::shared_ptr<river::Interface>(new river::Interface());
out->init(_name, _freq, _map, _format, _node, _config);
out->init(_freq, _map, _format, _node, _config);
return out;
}

View File

@ -48,24 +48,21 @@ namespace river {
* @brief Constructor
*/
Interface();
bool init(const std::string& _name,
float _freq,
bool init(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std11::shared_ptr<river::io::Node>& _node,
const std11::shared_ptr<const ejson::Object>& _config);
static std11::shared_ptr<Interface> create(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std11::shared_ptr<river::io::Node>& _node,
const std11::shared_ptr<const ejson::Object>& _config);
public:
/**
* @brief Destructor
*/
virtual ~Interface();
static std11::shared_ptr<Interface> create(const std::string& _name,
float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std11::shared_ptr<river::io::Node>& _node,
const std11::shared_ptr<const ejson::Object>& _config);
protected:
mutable std11::recursive_mutex m_mutex;
std11::shared_ptr<const ejson::Object> m_config;
@ -94,6 +91,9 @@ namespace river {
virtual std::string getName() {
return m_name;
};
virtual void setName(const std::string& _name) {
m_name = _name;
};
/**
* @brief set the read/write mode enable.
*/
@ -206,7 +206,6 @@ namespace river {
virtual void systemNewInputData(std11::chrono::system_clock::time_point _time, const void* _data, size_t _nbChunk);
virtual void systemNeedOutputData(std11::chrono::system_clock::time_point _time, void* _data, size_t _nbChunk, size_t _chunkSize);
virtual void systemVolumeChange();
float m_volume; //!< Local channel Volume
public:
virtual void generateDot(etk::FSNode& _node, const std::string& _nameIO, bool _isLink=true);
virtual std::string getDotNodeName() const;

View File

@ -11,27 +11,11 @@
#include "io/Manager.h"
#include "io/Node.h"
#include "debug.h"
#include <ejson/ejson.h>
#undef __class__
#define __class__ "Manager"
static std::string basicAutoConfig =
"{\n"
" microphone:{\n"
" io:'input',\n"
" map-on:'microphone',\n"
" resampling-type:'speexdsp',\n"
" resampling-option:'quality=10'\n"
" },\n"
" speaker:{\n"
" io:'output',\n"
" map-on:'speaker',\n"
" resampling-type:'speexdsp',\n"
" resampling-option:'quality=10'\n"
" }\n"
"}\n";
std11::shared_ptr<river::Manager> river::Manager::create(const std::string& _applicationUniqueId) {
return std11::shared_ptr<river::Manager>(new river::Manager(_applicationUniqueId));
}
@ -39,11 +23,7 @@ std11::shared_ptr<river::Manager> river::Manager::create(const std::string& _app
river::Manager::Manager(const std::string& _applicationUniqueId) :
m_applicationUniqueId(_applicationUniqueId),
m_listOpenInterface() {
// TODO : Maybe create a single interface property (and all get the same ...)
if (m_config.load("DATA:virtual.json") == false) {
RIVER_WARNING("you must set a basic configuration file for virtual configuration: DATA:virtual.json (load default interface)");
m_config.parse(basicAutoConfig);
}
}
river::Manager::~Manager() {
@ -51,114 +31,166 @@ river::Manager::~Manager() {
}
std::vector<std::pair<std::string,std::string> > river::Manager::getListStreamInput() {
std::vector<std::pair<std::string,std::string> > output;
std::vector<std::string> keys = m_config.getKeys();
for (size_t iii=0; iii<keys.size(); ++iii) {
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(keys[iii]);
if (tmppp != nullptr) {
std::string type = tmppp->getStringValue("io", "error");
if ( type == "input"
|| type == "feedback") {
output.push_back(std::make_pair<std::string,std::string>(std::string(keys[iii]), std::string("---")));
}
}
std::vector<std::string> river::Manager::getListStreamInput() {
std::vector<std::string> output;
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
} else {
output = manager->getListStreamInput();
}
return output;
}
std::vector<std::pair<std::string,std::string> > river::Manager::getListStreamOutput() {
std::vector<std::pair<std::string,std::string> > output;
std::vector<std::string> keys = m_config.getKeys();
for (size_t iii=0; iii<keys.size(); ++iii) {
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(keys[iii]);
if (tmppp != nullptr) {
std::string type = tmppp->getStringValue("io", "error");
if (type == "output") {
output.push_back(std::make_pair<std::string,std::string>(std::string(keys[iii]), std::string("---")));
}
}
std::vector<std::string> river::Manager::getListStreamOutput() {
std::vector<std::string> output;
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
} else {
output = manager->getListStreamOutput();
}
return output;
}
std::vector<std::string> river::Manager::getListStreamVirtual() {
std::vector<std::string> output;
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
} else {
output = manager->getListStreamVirtual();
}
return output;
}
std::vector<std::string> river::Manager::getListStream() {
std::vector<std::string> output;
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
} else {
output = manager->getListStream();
}
return output;
}
bool river::Manager::setVolume(const std::string& _volumeName, float _valuedB) {
return river::io::Manager::getInstance()->setVolume(_volumeName, _valuedB);
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
return false;
}
return manager->setVolume(_volumeName, _valuedB);
}
float river::Manager::getVolume(const std::string& _volumeName) const {
return river::io::Manager::getInstance()->getVolume(_volumeName);
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
return false;
}
return manager->getVolume(_volumeName);
}
std::pair<float,float> river::Manager::getVolumeRange(const std::string& _volumeName) const {
return river::io::Manager::getInstance()->getVolumeRange(_volumeName);
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
return std::make_pair<float,float>(0.0f,0.0f);
}
return manager->getVolumeRange(_volumeName);
}
std11::shared_ptr<river::Interface> river::Manager::createOutput(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _streamName,
const std::string& _name) {
// check if the output exist
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(_streamName);
if (tmppp == nullptr) {
RIVER_ERROR("can not open a non existance virtual input: '" << _streamName << "' not present in : " << m_config.getKeys());
return std11::shared_ptr<river::Interface>();
}
// check if it is an Output:
std::string type = tmppp->getStringValue("io", "error");
if (type != "output") {
RIVER_ERROR("can not open in output a virtual interface: '" << _streamName << "' configured has : " << type);
return std11::shared_ptr<river::Interface>();
}
std::string mapOn = tmppp->getStringValue("map-on", "");
if (mapOn == "") {
RIVER_ERROR("can not open in output a virtual interface: '" << _streamName << "' No 'map-on' element in json file ... ");
return std11::shared_ptr<river::Interface>();
}
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _streamName,
const std::string& _options) {
// get global hardware interface:
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
return std11::shared_ptr<river::Interface>();
}
// get the output or input channel :
std11::shared_ptr<river::io::Node> node = manager->getNode(mapOn);
std11::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
if (node == nullptr) {
RIVER_ERROR("Can not get the Requested stream '" << _streamName << "' ==> not listed in : " << manager->getListStream());
return std11::shared_ptr<river::Interface>();
}
if (node->isOutput() != true) {
RIVER_ERROR("Can not Connect output on other thing than output ... for stream '" << _streamName << "'");;
return std11::shared_ptr<river::Interface>();
}
// create user iterface:
std11::shared_ptr<river::Interface> interface;
interface = river::Interface::create(_name, _freq, _map, _format, node, tmppp);
std11::shared_ptr<ejson::Object> tmpOption = ejson::Object::create(_options);
tmpOption->addString("io", "output");
interface = river::Interface::create(_freq, _map, _format, node, tmpOption);
// store it in a list (needed to apply some parameters).
m_listOpenInterface.push_back(interface);
return interface;
}
std11::shared_ptr<river::Interface> river::Manager::createInput(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _streamName,
const std::string& _name) {
// check if the output exist
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(_streamName);
if (tmppp == nullptr) {
RIVER_ERROR("can not open a non existance virtual interface: '" << _streamName << "' not present in : " << m_config.getKeys());
return std11::shared_ptr<river::Interface>();
}
// check if it is an Output:
std::string type = tmppp->getStringValue("io", "error");
if ( type != "input"
&& type != "feedback") {
RIVER_ERROR("can not open in output a virtual interface: '" << _streamName << "' configured has : " << type);
return std11::shared_ptr<river::Interface>();
}
std::string mapOn = tmppp->getStringValue("map-on", "");
if (mapOn == "") {
RIVER_ERROR("can not open in output a virtual interface: '" << _streamName << "' No 'map-on' element in json file ... ");
return std11::shared_ptr<river::Interface>();
}
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _streamName,
const std::string& _options) {
// get global hardware interface:
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
return std11::shared_ptr<river::Interface>();
}
// get the output or input channel :
std11::shared_ptr<river::io::Node> node = manager->getNode(mapOn);
std11::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
if (node == nullptr) {
RIVER_ERROR("Can not get the Requested stream '" << _streamName << "' ==> not listed in : " << manager->getListStream());
return std11::shared_ptr<river::Interface>();
}
if (node->isInput() != true) {
RIVER_ERROR("Can not Connect input on other thing than input ... for stream '" << _streamName << "'");;
return std11::shared_ptr<river::Interface>();
}
// create user iterface:
std11::shared_ptr<river::Interface> interface;
interface = river::Interface::create(_name, _freq, _map, _format, node, tmppp);
std11::shared_ptr<ejson::Object> tmpOption = ejson::Object::create(_options);
tmpOption->addString("io", "input");
interface = river::Interface::create(_freq, _map, _format, node, tmpOption);
// store it in a list (needed to apply some parameters).
m_listOpenInterface.push_back(interface);
return interface;
}
std11::shared_ptr<river::Interface> river::Manager::createFeedback(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _streamName,
const std::string& _options) {
// get global hardware interface:
std11::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
if (manager == nullptr) {
RIVER_ERROR("Unable to load harware IO manager ... ");
return std11::shared_ptr<river::Interface>();
}
// get the output or input channel :
std11::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
if (node == nullptr) {
RIVER_ERROR("Can not get the Requested stream '" << _streamName << "' ==> not listed in : " << manager->getListStream());
return std11::shared_ptr<river::Interface>();
}
if (node->isOutput() != true) {
RIVER_ERROR("Can not Connect feedback on other thing than output ... for stream '" << _streamName << "'");;
return std11::shared_ptr<river::Interface>();
}
// create user iterface:
std11::shared_ptr<river::Interface> interface;
std11::shared_ptr<ejson::Object> tmpOption = ejson::Object::create(_options);
tmpOption->addString("io", "feedback");
interface = river::Interface::create(_freq, _map, _format, node, tmpOption);
// store it in a list (needed to apply some parameters).
m_listOpenInterface.push_back(interface);
return interface;

View File

@ -21,7 +21,6 @@ namespace river {
*/
class Manager {
private:
ejson::Document m_config; // virtual configuration
const std::string& m_applicationUniqueId; //!< name of the application that open the Audio Interface.
std::vector<std11::weak_ptr<river::Interface> > m_listOpenInterface; //!< List of all open Stream.
protected:
@ -37,15 +36,25 @@ namespace river {
virtual ~Manager();
public:
/**
* @brief Get all input audio stream description.
* @return a list of all availlables input stream (name + description)
* @brief Get all input audio stream.
* @return a list of all availlables input stream name
*/
virtual std::vector<std::pair<std::string,std::string> > getListStreamInput();
std::vector<std::string> getListStreamInput();
/**
* @brief Get all output audio stream description.
* @return a list of all availlables output stream (name + description)
* @brief Get all output audio stream.
* @return a list of all availlables output stream name
*/
virtual std::vector<std::pair<std::string,std::string> > getListStreamOutput();
std::vector<std::string> getListStreamOutput();
/**
* @brief Get all audio virtual stream.
* @return a list of all availlables virtual stream name
*/
std::vector<std::string> getListStreamVirtual();
/**
* @brief Get all audio stream.
* @return a list of all availlables stream name
*/
std::vector<std::string> getListStream();
/**
* @brief Set a volume for a specific group
@ -75,30 +84,44 @@ namespace river {
* @brief Create output Interface
* @param[in] _freq Frequency to open Interface [8,16,22,32,48] kHz
* @param[in] _map ChannelMap of the Output
* @param[in] _format Sample Format to open the stream [int8_t]
* @param[in] _format Sample Format to open the stream [int8_t, int16_t, ...]
* @param[in] _streamName Stream name to open: "" or "default" open current selected output
* @param[in] _name Name of this interface
* @param[in] _options Json option to configure default resampling and many other things.
* @return a pointer on the interface
*/
virtual std11::shared_ptr<Interface> createOutput(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _streamName = "",
const std::string& _name = "");
virtual std11::shared_ptr<Interface> createOutput(float _freq = 48000,
const std::vector<audio::channel>& _map = std::vector<audio::channel>(),
audio::format _format = audio::format_int16,
const std::string& _streamName = "",
const std::string& _options = "");
/**
* @brief Create input Interface
* @param[in] _freq Frequency to open Interface [8,16,22,32,48] kHz
* @param[in] _map ChannelMap of the Output
* @param[in] _format Sample Format to open the stream [int8_t]
* @param[in] _format Sample Format to open the stream [int8_t, int16_t, ...]
* @param[in] _streamName Stream name to open: "" or "default" open current selected input
* @param[in] _name Name of this interface
* @param[in] _options Json option to configure default resampling and many other things.
* @return a pointer on the interface
*/
virtual std11::shared_ptr<Interface> createInput(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _streamName = "",
const std::string& _name = "");
virtual std11::shared_ptr<Interface> createInput(float _freq = 48000,
const std::vector<audio::channel>& _map = std::vector<audio::channel>(),
audio::format _format = audio::format_int16,
const std::string& _streamName = "",
const std::string& _options = "");
/**
* @brief Create input Feedback Interface
* @param[in] _freq Frequency to open Interface [8,16,22,32,48] kHz
* @param[in] _map ChannelMap of the Output
* @param[in] _format Sample Format to open the stream [int8_t, int16_t, ...]
* @param[in] _streamName Stream name to open: "" or "default" open current selected input
* @param[in] _options Json option to configure default resampling and many other things.
* @return a pointer on the interface
*/
virtual std11::shared_ptr<Interface> createFeedback(float _freq = 48000,
const std::vector<audio::channel>& _map = std::vector<audio::channel>(),
audio::format _format = audio::format_int16,
const std::string& _streamName = "",
const std::string& _options = "");
/**
* @brief Generate the dot file corresponding at all the actif nodes.
* @param[in] _filename Name of the file to write data.

View File

@ -57,19 +57,27 @@ static std::string basicAutoConfig =
river::io::Manager::Manager() {
if (m_config.load("DATA:hardware.json") == false) {
RIVER_WARNING("you must set a basic configuration file for harware configuration: DATA:hardware.json (load default interface)");
m_config.parse(basicAutoConfig);
}
// TODO : Load virtual.json and check if all is correct ...
#ifdef __PORTAUDIO_INFERFACE__
PaError err = Pa_Initialize();
if(err != paNoError) {
RIVER_WARNING("Can not initialize portaudio : " << Pa_GetErrorText(err));
}
#endif
};
}
void river::io::Manager::init(const std::string _filename) {
std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
if (_filename == "") {
RIVER_INFO("Load default config");
m_config.parse(basicAutoConfig);
} else if (m_config.load(_filename) == false) {
RIVER_ERROR("you must set a basic configuration file for harware configuration: '" << _filename << "'");
}
}
void river::io::Manager::unInit() {
std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
}
river::io::Manager::~Manager() {
#ifdef __PORTAUDIO_INFERFACE__
@ -80,12 +88,85 @@ river::io::Manager::~Manager() {
#endif
};
std11::shared_ptr<river::io::Manager> river::io::Manager::getInstance() {
if (river::isInit() == false) {
return std11::shared_ptr<river::io::Manager>();
}
static std11::shared_ptr<river::io::Manager> manager(new Manager());
return manager;
}
std::vector<std::string> river::io::Manager::getListStreamInput() {
std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
std::vector<std::string> output;
std::vector<std::string> keys = m_config.getKeys();
for (size_t iii=0; iii<keys.size(); ++iii) {
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(keys[iii]);
if (tmppp != nullptr) {
std::string type = tmppp->getStringValue("io", "error");
if ( type == "input"
|| type == "PAinput") {
output.push_back(keys[iii]);
}
}
}
return output;
}
std::vector<std::string> river::io::Manager::getListStreamOutput() {
std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
std::vector<std::string> output;
std::vector<std::string> keys = m_config.getKeys();
for (size_t iii=0; iii<keys.size(); ++iii) {
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(keys[iii]);
if (tmppp != nullptr) {
std::string type = tmppp->getStringValue("io", "error");
if ( type == "output"
|| type == "PAoutput") {
output.push_back(keys[iii]);
}
}
}
return output;
}
std::vector<std::string> river::io::Manager::getListStreamVirtual() {
std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
std::vector<std::string> output;
std::vector<std::string> keys = m_config.getKeys();
for (size_t iii=0; iii<keys.size(); ++iii) {
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(keys[iii]);
if (tmppp != nullptr) {
std::string type = tmppp->getStringValue("io", "error");
if ( type != "input"
&& type != "PAinput"
&& type != "output"
&& type != "PAoutput"
&& type != "error") {
output.push_back(keys[iii]);
}
}
}
return output;
}
std::vector<std::string> river::io::Manager::getListStream() {
std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
std::vector<std::string> output;
std::vector<std::string> keys = m_config.getKeys();
for (size_t iii=0; iii<keys.size(); ++iii) {
const std11::shared_ptr<const ejson::Object> tmppp = m_config.getObject(keys[iii]);
if (tmppp != nullptr) {
std::string type = tmppp->getStringValue("io", "error");
if (type != "error") {
output.push_back(keys[iii]);
}
}
}
return output;
}
std11::shared_ptr<river::io::Node> river::io::Manager::getNode(const std::string& _name) {
std11::unique_lock<std11::recursive_mutex> lock(m_mutex);
RIVER_WARNING("Get node : " << _name);

View File

@ -38,7 +38,9 @@ namespace river {
/**
* @brief Destructor
*/
virtual ~Manager();
~Manager();
void init();
void unInit();
private:
ejson::Document m_config; // harware configuration
std::vector<std11::shared_ptr<river::io::Node> > m_listKeepAlive; //!< list of all Node that might be keep alive sone time
@ -49,6 +51,26 @@ namespace river {
std::vector<std11::shared_ptr<drain::VolumeElement> > m_volumeGroup;
public:
std11::shared_ptr<drain::VolumeElement> getVolumeGroup(const std::string& _name);
/**
* @brief Get all input audio stream.
* @return a list of all availlables input stream name
*/
std::vector<std::string> getListStreamInput();
/**
* @brief Get all output audio stream.
* @return a list of all availlables output stream name
*/
std::vector<std::string> getListStreamOutput();
/**
* @brief Get all audio virtual stream.
* @return a list of all availlables virtual stream name
*/
std::vector<std::string> getListStreamVirtual();
/**
* @brief Get all audio stream.
* @return a list of all availlables stream name
*/
std::vector<std::string> getListStream();
/**
* @brief Set a volume for a specific group
@ -58,26 +80,26 @@ namespace river {
* @return false An error occured
* @example : setVolume("MASTER", -3.0f);
*/
virtual bool setVolume(const std::string& _volumeName, float _valuedB);
bool setVolume(const std::string& _volumeName, float _valuedB);
/**
* @brief Get a volume value
* @param[in] _volumeName Name of the volume (MASTER, MATER_BT ...)
* @return The Volume value in dB.
* @example ret = getVolume("MASTER"); can return something like ret = -3.0f
*/
virtual float getVolume(const std::string& _volumeName);
float getVolume(const std::string& _volumeName);
/**
* @brief Get a parameter value
* @param[in] _volumeName Name of the volume (MASTER, MATER_BT ...)
* @return The requested value Range.
* @example ret = getVolumeRange("MASTER"); can return something like ret=(-120.0f,0.0f)
*/
virtual std::pair<float,float> getVolumeRange(const std::string& _volumeName) const;
std::pair<float,float> getVolumeRange(const std::string& _volumeName) const;
/**
* @brief Generate the dot file corresponding at the actif nodes.
* @param[in] _filename Name of the file to write data.
*/
virtual void generateDot(const std::string& _filename);
void generateDot(const std::string& _filename);
private:
std::map<std::string, std11::shared_ptr<river::io::Group> > m_listGroup; //!< List of all groups
std11::shared_ptr<river::io::Group> getGroup(const std::string& _name);

View File

@ -13,90 +13,15 @@
#undef __class__
#define __class__ "io::NodeAEC"
#if 0
int32_t river::io::NodeAEC::airtAudioCallback(void* _outputBuffer,
void* _inputBuffer,
uint32_t _nbChunk,
const std11::chrono::system_clock::time_point& _time,
airtaudio::status _status) {
std11::unique_lock<std11::mutex> lock(m_mutex);
//RIVER_INFO("Time=" << _time);
/*
for (int32_t iii=0; iii<400; ++iii) {
RIVER_VERBOSE("dummy=" << uint64_t(dummy[iii]));
}
*/
if (_outputBuffer != nullptr) {
RIVER_VERBOSE("data Output size request :" << _nbChunk << " [BEGIN] status=" << _status << " nbIO=" << m_list.size());
std::vector<int32_t> output;
RIVER_VERBOSE("resize=" << _nbChunk*m_process.getInputConfig().getMap().size());
output.resize(_nbChunk*m_process.getInputConfig().getMap().size(), 0);
const int32_t* outputTmp = nullptr;
std::vector<uint8_t> outputTmp2;
RIVER_VERBOSE("resize=" << sizeof(int32_t)*m_process.getInputConfig().getMap().size()*_nbChunk);
outputTmp2.resize(sizeof(int32_t)*m_process.getInputConfig().getMap().size()*_nbChunk, 0);
for (auto &it : m_list) {
if (it == nullptr) {
continue;
}
if (it->getMode() != river::modeInterface_output) {
continue;
}
RIVER_VERBOSE(" IO name="<< it->getName());
// clear datas ...
memset(&outputTmp2[0], 0, sizeof(int32_t)*m_process.getInputConfig().getMap().size()*_nbChunk);
RIVER_VERBOSE(" request Data="<< _nbChunk);
it->systemNeedOutputData(_time, &outputTmp2[0], _nbChunk, sizeof(int32_t)*m_process.getInputConfig().getMap().size());
RIVER_VERBOSE(" Mix it ...");
outputTmp = reinterpret_cast<const int32_t*>(&outputTmp2[0]);
// Add data to the output tmp buffer :
for (size_t kkk=0; kkk<output.size(); ++kkk) {
output[kkk] += outputTmp[kkk];
}
}
RIVER_VERBOSE(" End stack process data ...");
m_process.processIn(&outputTmp2[0], _nbChunk, _outputBuffer, _nbChunk);
RIVER_VERBOSE(" Feedback :");
for (auto &it : m_list) {
if (it == nullptr) {
continue;
}
if (it->getMode() != river::modeInterface_feedback) {
continue;
}
RIVER_VERBOSE(" IO name="<< it->getName() << " (feedback)");
it->systemNewInputData(_time, _outputBuffer, _nbChunk);
}
RIVER_VERBOSE("data Output size request :" << _nbChunk << " [ END ]");
}
if (_inputBuffer != nullptr) {
RIVER_VERBOSE("data Input size request :" << _nbChunk << " [BEGIN] status=" << _status << " nbIO=" << m_list.size());
int16_t* inputBuffer = static_cast<int16_t *>(_inputBuffer);
for (auto &it : m_list) {
if (it == nullptr) {
continue;
}
if (it->getMode() != river::modeInterface_input) {
continue;
}
RIVER_INFO(" IO name="<< it->getName());
it->systemNewInputData(_time, inputBuffer, _nbChunk);
}
RIVER_VERBOSE("data Input size request :" << _nbChunk << " [ END ]");
}
return 0;
}
#endif
std11::shared_ptr<river::io::NodeAEC> river::io::NodeAEC::create(const std::string& _name, const std11::shared_ptr<const ejson::Object>& _config) {
return std11::shared_ptr<river::io::NodeAEC>(new river::io::NodeAEC(_name, _config));
}
std11::shared_ptr<river::Interface> river::io::NodeAEC::createInput(float _freq,
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _objectName,
const std::string& _name) {
const std::vector<audio::channel>& _map,
audio::format _format,
const std::string& _objectName,
const std::string& _name) {
// check if the output exist
const std11::shared_ptr<const ejson::Object> tmppp = m_config->getObject(_objectName);
if (tmppp == nullptr) {
@ -119,7 +44,10 @@ std11::shared_ptr<river::Interface> river::io::NodeAEC::createInput(float _freq,
std11::shared_ptr<river::io::Node> node = manager->getNode(streamName);
// create user iterface:
std11::shared_ptr<river::Interface> interface;
interface = river::Interface::create(_name, _freq, _map, _format, node, tmppp);
interface = river::Interface::create(_freq, _map, _format, node, tmppp);
if (interface != nullptr) {
interface->setName(_name);
}
return interface;
}

View File

@ -44,7 +44,10 @@ std11::shared_ptr<river::Interface> river::io::NodeMuxer::createInput(float _fre
std11::shared_ptr<river::io::Node> node = manager->getNode(streamName);
// create user iterface:
std11::shared_ptr<river::Interface> interface;
interface = river::Interface::create(_name, _freq, _map, _format, node, tmppp);
interface = river::Interface::create(_freq, _map, _format, node, tmppp);
if (interface != nullptr) {
interface->setName(_name);
}
return interface;
}

38
river/river.cpp Normal file
View File

@ -0,0 +1,38 @@
/** @file
* @author Edouard DUPIN
* @copyright 2015, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#iclude <river/river.h>
#iclude <river/debug.h>
#include <river/io/Manager.h>
static bool river_isInit = false;
static std::string river_configFile = "";
void river::init(const std::string& _filename) {
if (river_isInit == false) {
river_isInit = true;
river_configFile = _filename;
RIVER_INFO("init RIVER :" << river_configFile);
std11::shared_ptr<river::io::Manager> mng = river::io::Manager::getInstance();
mng->init(river_configFile);
}
}
void river::unInit() {
if (river_isInit == true) {
river_isInit = false;
RIVER_INFO("un-init RIVER :" << river_configFile);
std11::shared_ptr<river::io::Manager> mng = river::io::Manager::getInstance();
mng->unInit();
}
}
bool river::isInit() {
return river_isInit;
}

33
river/river.h Normal file
View File

@ -0,0 +1,33 @@
/** @file
* @author Edouard DUPIN
* @copyright 2015, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#ifndef __RIVER_H__
#define __RIVER_H__
#include <etk/type.h>
namespace river {
/**
* @brief Initialize the River Library
* @param[in] _filename Name of the configuration file (if "" ==> default config file)
*/
void init(const std::string& _filename);
/**
* @brief Un-initialize the River Library
* @note this close all stream of all interfaces.
* @note really good for test.
*/
void unInit();
/**
* @brief Get the status of initialisation
* @return true River is init
* @return false River is NOT init
*/
bool isInit();
}
#endif

View File

@ -45,8 +45,6 @@ namespace river_test_echo_delay {
m_gain(-40) {
//Set stereo output:
std::vector<audio::channel> channelMap;
channelMap.push_back(audio::channel_frontLeft);
channelMap.push_back(audio::channel_frontRight);
m_interfaceOut = m_manager->createOutput(48000,
channelMap,
audio::format_int16,
@ -345,6 +343,9 @@ namespace river_test_echo_delay {
m_interfaceOut->start();
m_interfaceIn->start();
//m_interfaceFB->start();
while (m_estimateVolumeInput == true) {
usleep(10000);
}
usleep(10000000);
//m_interfaceFB->stop();
m_interfaceIn->stop();

View File

@ -41,7 +41,7 @@ namespace river_test_muxer {
std11::placeholders::_5,
std11::placeholders::_6));
m_interfaceOut->addVolumeGroup("FLOW");
m_interfaceOut->setParameter("volume", "FLOW", "-6dB");
//m_interfaceOut->setParameter("volume", "FLOW", "-6dB");
//Set stereo output:
m_interfaceIn = m_manager->createInput(48000,
@ -71,7 +71,7 @@ namespace river_test_muxer {
double baseCycle = 2.0*M_PI/(double)48000 * 440;
for (int32_t iii=0; iii<_nbChunk; iii++) {
for (int32_t jjj=0; jjj<_map.size(); jjj++) {
data[_map.size()*iii+jjj] = sin(m_phase) * 30000;
data[_map.size()*iii+jjj] = sin(m_phase) * 7000;
}
m_phase += baseCycle;
if (m_phase >= 2*M_PI) {

View File

@ -7,6 +7,8 @@
#ifndef __RIVER_TEST_RECORD_CALLBACK_H__
#define __RIVER_TEST_RECORD_CALLBACK_H__
#include <river/debug.h>
#undef __class__
#define __class__ "test_record_callback"
@ -20,8 +22,6 @@ namespace river_test_record_callback {
m_manager(_manager) {
//Set stereo output:
std::vector<audio::channel> channelMap;
channelMap.push_back(audio::channel_frontLeft);
channelMap.push_back(audio::channel_frontRight);
m_interface = m_manager->createInput(48000,
channelMap,
audio::format_int16,
@ -46,6 +46,7 @@ namespace river_test_record_callback {
if (_format != audio::format_int16) {
APPL_ERROR("call wrong type ... (need int16_t)");
}
RIVER_SAVE_FILE_MACRO(int16_t, "REC_INPUT.raw", _data, _nbChunk * _map.size());
const int16_t* data = static_cast<const int16_t*>(_data);
int64_t value = 0;
for (size_t iii=0; iii<_nbChunk*_map.size(); ++iii) {
@ -57,9 +58,7 @@ namespace river_test_record_callback {
void run() {
m_interface->start();
// wait 2 second ...
usleep(2000000);
usleep(20000000);
m_interface->stop();
}
};