[DEV] add virtual interface
This commit is contained in:
parent
1e10cc276b
commit
a086674189
@ -12,7 +12,7 @@
|
|||||||
resampling-option:"quality=10"
|
resampling-option:"quality=10"
|
||||||
},
|
},
|
||||||
feedback:{
|
feedback:{
|
||||||
io:"input",
|
io:"feedback", # note : Feedback is plugged on an output not an input
|
||||||
map-on:"speaker",
|
map-on:"speaker",
|
||||||
resampling-type:"speexdsp",
|
resampling-type:"speexdsp",
|
||||||
resampling-option:"quality=10"
|
resampling-option:"quality=10"
|
||||||
@ -22,8 +22,9 @@
|
|||||||
map-on:"speaker",
|
map-on:"speaker",
|
||||||
resampling-type:"speexdsp",
|
resampling-type:"speexdsp",
|
||||||
resampling-option:"quality=10",
|
resampling-option:"quality=10",
|
||||||
aec-map-on:"microphone", the second input of the AEC (get a single
|
# specific case for AEC : only 3 options
|
||||||
aec-type:"airtio-remover", # some type is "airtio-remover",
|
aec-map-on:"microphone", # the second input of the AEC (get a single)
|
||||||
|
aec-type:"river-remover", # some type is "airtio-remover",
|
||||||
aec-option:"mode=cutter"
|
aec-option:"mode=cutter"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -27,18 +27,27 @@ river::Interface::Interface(void) :
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool river::Interface::init(const std::string& _name,
|
bool river::Interface::init(const std::string& _name,
|
||||||
float _freq,
|
float _freq,
|
||||||
const std::vector<audio::channel>& _map,
|
const std::vector<audio::channel>& _map,
|
||||||
audio::format _format,
|
audio::format _format,
|
||||||
const std::shared_ptr<river::io::Node>& _node,
|
const std::shared_ptr<river::io::Node>& _node,
|
||||||
bool _isInput) {
|
const std::shared_ptr<const ejson::Object>& _config) {
|
||||||
m_name = _name;
|
m_name = _name;
|
||||||
m_node = _node;
|
m_node = _node;
|
||||||
m_freq = _freq;
|
m_freq = _freq;
|
||||||
m_map = _map;
|
m_map = _map;
|
||||||
m_format = _format;
|
m_format = _format;
|
||||||
m_volume = 0.0f;
|
m_volume = 0.0f;
|
||||||
m_isInput = _isInput;
|
m_config = _config;
|
||||||
|
m_mode = river::modeInterface_unknow;
|
||||||
|
std::string type = m_config->getStringValue("io", "error");
|
||||||
|
if (type == "output") {
|
||||||
|
m_mode = river::modeInterface_output;
|
||||||
|
} else if (type == "input") {
|
||||||
|
m_mode = river::modeInterface_input;
|
||||||
|
} else if (type == "feedback") {
|
||||||
|
m_mode = river::modeInterface_feedback;
|
||||||
|
}
|
||||||
// register interface to be notify from the volume change.
|
// register interface to be notify from the volume change.
|
||||||
m_node->registerAsRemote(shared_from_this());
|
m_node->registerAsRemote(shared_from_this());
|
||||||
// Create convertion interface
|
// Create convertion interface
|
||||||
@ -75,13 +84,13 @@ bool river::Interface::init(const std::string& _name,
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<river::Interface> river::Interface::create(const std::string& _name,
|
std::shared_ptr<river::Interface> river::Interface::create(const std::string& _name,
|
||||||
float _freq,
|
float _freq,
|
||||||
const std::vector<audio::channel>& _map,
|
const std::vector<audio::channel>& _map,
|
||||||
audio::format _format,
|
audio::format _format,
|
||||||
const std::shared_ptr<river::io::Node>& _node,
|
const std::shared_ptr<river::io::Node>& _node,
|
||||||
bool _isInput) {
|
const std::shared_ptr<const ejson::Object>& _config) {
|
||||||
std::shared_ptr<river::Interface> out = std::shared_ptr<river::Interface>(new river::Interface());
|
std::shared_ptr<river::Interface> out = std::shared_ptr<river::Interface>(new river::Interface());
|
||||||
out->init(_name, _freq, _map, _format, _node, _isInput);
|
out->init(_name, _freq, _map, _format, _node, _config);
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,11 +19,18 @@
|
|||||||
#include <drain/EndPointCallback.h>
|
#include <drain/EndPointCallback.h>
|
||||||
#include <drain/EndPointWrite.h>
|
#include <drain/EndPointWrite.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <ejson/ejson.h>
|
||||||
|
|
||||||
namespace river {
|
namespace river {
|
||||||
namespace io {
|
namespace io {
|
||||||
class Node;
|
class Node;
|
||||||
}
|
}
|
||||||
|
enum modeInterface {
|
||||||
|
modeInterface_unknow,
|
||||||
|
modeInterface_input,
|
||||||
|
modeInterface_output,
|
||||||
|
modeInterface_feedback,
|
||||||
|
};
|
||||||
class Interface : public std::enable_shared_from_this<Interface> {
|
class Interface : public std::enable_shared_from_this<Interface> {
|
||||||
friend class io::Node;
|
friend class io::Node;
|
||||||
friend class Manager;
|
friend class Manager;
|
||||||
@ -35,6 +42,7 @@ namespace river {
|
|||||||
std::vector<audio::channel> m_map;
|
std::vector<audio::channel> m_map;
|
||||||
audio::format m_format;
|
audio::format m_format;
|
||||||
drain::Process m_process;
|
drain::Process m_process;
|
||||||
|
std::shared_ptr<const ejson::Object> m_config;
|
||||||
protected:
|
protected:
|
||||||
std::string m_name;
|
std::string m_name;
|
||||||
public:
|
public:
|
||||||
@ -42,13 +50,10 @@ namespace river {
|
|||||||
return m_name;
|
return m_name;
|
||||||
};
|
};
|
||||||
protected:
|
protected:
|
||||||
bool m_isInput;
|
enum modeInterface m_mode;
|
||||||
public:
|
public:
|
||||||
bool isInput() {
|
enum modeInterface getMode() {
|
||||||
return m_isInput;
|
return m_mode;
|
||||||
}
|
|
||||||
bool isOutput() {
|
|
||||||
return !m_isInput;
|
|
||||||
}
|
}
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@ -60,7 +65,7 @@ namespace river {
|
|||||||
const std::vector<audio::channel>& _map,
|
const std::vector<audio::channel>& _map,
|
||||||
audio::format _format,
|
audio::format _format,
|
||||||
const std::shared_ptr<river::io::Node>& _node,
|
const std::shared_ptr<river::io::Node>& _node,
|
||||||
bool _isInput);
|
const std::shared_ptr<const ejson::Object>& _config);
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Destructor
|
* @brief Destructor
|
||||||
@ -71,7 +76,7 @@ namespace river {
|
|||||||
const std::vector<audio::channel>& _map,
|
const std::vector<audio::channel>& _map,
|
||||||
audio::format _format,
|
audio::format _format,
|
||||||
const std::shared_ptr<river::io::Node>& _node,
|
const std::shared_ptr<river::io::Node>& _node,
|
||||||
bool _isInput);
|
const std::shared_ptr<const ejson::Object>& _config);
|
||||||
/**
|
/**
|
||||||
* @brief set the read/write mode enable.
|
* @brief set the read/write mode enable.
|
||||||
*/
|
*/
|
||||||
|
@ -23,7 +23,10 @@ std::shared_ptr<river::Manager> river::Manager::create(const std::string& _appli
|
|||||||
river::Manager::Manager(const std::string& _applicationUniqueId) :
|
river::Manager::Manager(const std::string& _applicationUniqueId) :
|
||||||
m_applicationUniqueId(_applicationUniqueId),
|
m_applicationUniqueId(_applicationUniqueId),
|
||||||
m_listOpenInterface() {
|
m_listOpenInterface() {
|
||||||
|
// TODO : Maybe create a single interface property (and all get the same ...)
|
||||||
|
if (m_config.load("DATA:virtual.json") == false) {
|
||||||
|
RIVER_ERROR("you must set a basic configuration file for virtual configuration: DATA:virtual.json");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
river::Manager::~Manager() {
|
river::Manager::~Manager() {
|
||||||
@ -33,13 +36,30 @@ river::Manager::~Manager() {
|
|||||||
|
|
||||||
std::vector<std::pair<std::string,std::string> > river::Manager::getListStreamInput() {
|
std::vector<std::pair<std::string,std::string> > river::Manager::getListStreamInput() {
|
||||||
std::vector<std::pair<std::string,std::string> > output;
|
std::vector<std::pair<std::string,std::string> > output;
|
||||||
//output.push_back(std::make_pair<std::string,std::string>("default", "48000 Hz, 16 bits, 2 channels: Default input "));
|
for (auto &it : m_config.getKeys()) {
|
||||||
|
const std::shared_ptr<const ejson::Object> tmppp = m_config.getObject(it);
|
||||||
|
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(it), std::string("---")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<std::string,std::string> > river::Manager::getListStreamOutput() {
|
std::vector<std::pair<std::string,std::string> > river::Manager::getListStreamOutput() {
|
||||||
std::vector<std::pair<std::string,std::string> > output;
|
std::vector<std::pair<std::string,std::string> > output;
|
||||||
//output.push_back(std::make_pair<std::string,std::string>("default", "48000 Hz, 16 bits, 2 channels: Default output "));
|
for (auto &it : m_config.getKeys()) {
|
||||||
|
const std::shared_ptr<const ejson::Object> tmppp = m_config.getObject(it);
|
||||||
|
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(it), std::string("---")));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,13 +81,26 @@ std::shared_ptr<river::Interface> river::Manager::createOutput(float _freq,
|
|||||||
audio::format _format,
|
audio::format _format,
|
||||||
const std::string& _streamName,
|
const std::string& _streamName,
|
||||||
const std::string& _name) {
|
const std::string& _name) {
|
||||||
|
// check if the output exist
|
||||||
|
const std::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 nullptr;
|
||||||
|
}
|
||||||
|
// 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 nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
// get global hardware interface:
|
// get global hardware interface:
|
||||||
std::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
|
std::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
|
||||||
// get the output or input channel :
|
// get the output or input channel :
|
||||||
std::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
|
std::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
|
||||||
// create user iterface:
|
// create user iterface:
|
||||||
std::shared_ptr<river::Interface> interface;
|
std::shared_ptr<river::Interface> interface;
|
||||||
interface = river::Interface::create(_name, _freq, _map, _format, node, false);
|
interface = river::Interface::create(_name, _freq, _map, _format, node, tmppp);
|
||||||
// store it in a list (needed to apply some parameters).
|
// store it in a list (needed to apply some parameters).
|
||||||
m_listOpenInterface.push_back(interface);
|
m_listOpenInterface.push_back(interface);
|
||||||
return interface;
|
return interface;
|
||||||
@ -78,13 +111,26 @@ std::shared_ptr<river::Interface> river::Manager::createInput(float _freq,
|
|||||||
audio::format _format,
|
audio::format _format,
|
||||||
const std::string& _streamName,
|
const std::string& _streamName,
|
||||||
const std::string& _name) {
|
const std::string& _name) {
|
||||||
|
// check if the output exist
|
||||||
|
const std::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 nullptr;
|
||||||
|
}
|
||||||
|
// 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 nullptr;
|
||||||
|
}
|
||||||
// get global hardware interface:
|
// get global hardware interface:
|
||||||
std::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
|
std::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
|
||||||
// get the output or input channel :
|
// get the output or input channel :
|
||||||
std::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
|
std::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
|
||||||
// create user iterface:
|
// create user iterface:
|
||||||
std::shared_ptr<river::Interface> interface;
|
std::shared_ptr<river::Interface> interface;
|
||||||
interface = river::Interface::create(_name, _freq, _map, _format, node, true);
|
interface = river::Interface::create(_name, _freq, _map, _format, node, tmppp);
|
||||||
// store it in a list (needed to apply some parameters).
|
// store it in a list (needed to apply some parameters).
|
||||||
m_listOpenInterface.push_back(interface);
|
m_listOpenInterface.push_back(interface);
|
||||||
return interface;
|
return interface;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <river/Interface.h>
|
#include <river/Interface.h>
|
||||||
#include <audio/format.h>
|
#include <audio/format.h>
|
||||||
#include <audio/channel.h>
|
#include <audio/channel.h>
|
||||||
|
#include <ejson/ejson.h>
|
||||||
|
|
||||||
namespace river {
|
namespace river {
|
||||||
/**
|
/**
|
||||||
@ -20,6 +21,7 @@ namespace river {
|
|||||||
*/
|
*/
|
||||||
class Manager {
|
class Manager {
|
||||||
private:
|
private:
|
||||||
|
ejson::Document m_config; // virtual configuration
|
||||||
const std::string& m_applicationUniqueId; //!< name of the application that open the Audio Interface.
|
const std::string& m_applicationUniqueId; //!< name of the application that open the Audio Interface.
|
||||||
std::vector<std::weak_ptr<river::Interface> > m_listOpenInterface; //!< List of all open Stream.
|
std::vector<std::weak_ptr<river::Interface> > m_listOpenInterface; //!< List of all open Stream.
|
||||||
protected:
|
protected:
|
||||||
|
@ -16,6 +16,7 @@ river::io::Manager::Manager() {
|
|||||||
if (m_config.load("DATA:hardware.json") == false) {
|
if (m_config.load("DATA:hardware.json") == false) {
|
||||||
RIVER_ERROR("you must set a basic configuration file for harware configuration: DATA:hardware.json");
|
RIVER_ERROR("you must set a basic configuration file for harware configuration: DATA:hardware.json");
|
||||||
}
|
}
|
||||||
|
// TODO : Load virtual.json and check if all is correct ...
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -25,8 +26,8 @@ std::shared_ptr<river::io::Manager> river::io::Manager::getInstance() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<river::io::Node> river::io::Manager::getNode(const std::string& _name) {
|
std::shared_ptr<river::io::Node> river::io::Manager::getNode(const std::string& _name) {
|
||||||
for (size_t iii=0; iii< m_list.size(); ++iii) {
|
for (auto &it : m_list) {
|
||||||
std::shared_ptr<river::io::Node> tmppp = m_list[iii].lock();
|
std::shared_ptr<river::io::Node> tmppp = it.lock();
|
||||||
if ( tmppp != nullptr
|
if ( tmppp != nullptr
|
||||||
&& _name == tmppp->getName()) {
|
&& _name == tmppp->getName()) {
|
||||||
return tmppp;
|
return tmppp;
|
||||||
|
@ -69,7 +69,7 @@ int32_t river::io::Node::airtAudioCallback(void* _outputBuffer,
|
|||||||
if (it == nullptr) {
|
if (it == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (it->isOutput() == false) {
|
if (it->getMode() != river::modeInterface_output) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RIVER_VERBOSE(" IO name="<< it->getName());
|
RIVER_VERBOSE(" IO name="<< it->getName());
|
||||||
@ -91,7 +91,7 @@ int32_t river::io::Node::airtAudioCallback(void* _outputBuffer,
|
|||||||
if (it == nullptr) {
|
if (it == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (it->isInput() == false) {
|
if (it->getMode() != river::modeInterface_feedback) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
RIVER_VERBOSE(" IO name="<< it->getName() << " (feedback)");
|
RIVER_VERBOSE(" IO name="<< it->getName() << " (feedback)");
|
||||||
@ -106,6 +106,9 @@ int32_t river::io::Node::airtAudioCallback(void* _outputBuffer,
|
|||||||
if (it == nullptr) {
|
if (it == nullptr) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (it->getMode() != river::modeInterface_input) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
RIVER_INFO(" IO name="<< it->getName());
|
RIVER_INFO(" IO name="<< it->getName());
|
||||||
it->systemNewInputData(_time, inputBuffer, _nbChunk);
|
it->systemNewInputData(_time, inputBuffer, _nbChunk);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user