[DEV] add virtual interface
This commit is contained in:
parent
1e10cc276b
commit
a086674189
@ -12,7 +12,7 @@
|
||||
resampling-option:"quality=10"
|
||||
},
|
||||
feedback:{
|
||||
io:"input",
|
||||
io:"feedback", # note : Feedback is plugged on an output not an input
|
||||
map-on:"speaker",
|
||||
resampling-type:"speexdsp",
|
||||
resampling-option:"quality=10"
|
||||
@ -22,8 +22,9 @@
|
||||
map-on:"speaker",
|
||||
resampling-type:"speexdsp",
|
||||
resampling-option:"quality=10",
|
||||
aec-map-on:"microphone", the second input of the AEC (get a single
|
||||
aec-type:"airtio-remover", # some type is "airtio-remover",
|
||||
# specific case for AEC : only 3 options
|
||||
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"
|
||||
}
|
||||
}
|
@ -31,14 +31,23 @@ bool river::Interface::init(const std::string& _name,
|
||||
const std::vector<audio::channel>& _map,
|
||||
audio::format _format,
|
||||
const std::shared_ptr<river::io::Node>& _node,
|
||||
bool _isInput) {
|
||||
const std::shared_ptr<const ejson::Object>& _config) {
|
||||
m_name = _name;
|
||||
m_node = _node;
|
||||
m_freq = _freq;
|
||||
m_map = _map;
|
||||
m_format = _format;
|
||||
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.
|
||||
m_node->registerAsRemote(shared_from_this());
|
||||
// Create convertion interface
|
||||
@ -79,9 +88,9 @@ std::shared_ptr<river::Interface> river::Interface::create(const std::string& _n
|
||||
const std::vector<audio::channel>& _map,
|
||||
audio::format _format,
|
||||
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());
|
||||
out->init(_name, _freq, _map, _format, _node, _isInput);
|
||||
out->init(_name, _freq, _map, _format, _node, _config);
|
||||
return out;
|
||||
}
|
||||
|
||||
|
@ -19,11 +19,18 @@
|
||||
#include <drain/EndPointCallback.h>
|
||||
#include <drain/EndPointWrite.h>
|
||||
#include <memory>
|
||||
#include <ejson/ejson.h>
|
||||
|
||||
namespace river {
|
||||
namespace io {
|
||||
class Node;
|
||||
}
|
||||
enum modeInterface {
|
||||
modeInterface_unknow,
|
||||
modeInterface_input,
|
||||
modeInterface_output,
|
||||
modeInterface_feedback,
|
||||
};
|
||||
class Interface : public std::enable_shared_from_this<Interface> {
|
||||
friend class io::Node;
|
||||
friend class Manager;
|
||||
@ -35,6 +42,7 @@ namespace river {
|
||||
std::vector<audio::channel> m_map;
|
||||
audio::format m_format;
|
||||
drain::Process m_process;
|
||||
std::shared_ptr<const ejson::Object> m_config;
|
||||
protected:
|
||||
std::string m_name;
|
||||
public:
|
||||
@ -42,13 +50,10 @@ namespace river {
|
||||
return m_name;
|
||||
};
|
||||
protected:
|
||||
bool m_isInput;
|
||||
enum modeInterface m_mode;
|
||||
public:
|
||||
bool isInput() {
|
||||
return m_isInput;
|
||||
}
|
||||
bool isOutput() {
|
||||
return !m_isInput;
|
||||
enum modeInterface getMode() {
|
||||
return m_mode;
|
||||
}
|
||||
protected:
|
||||
/**
|
||||
@ -60,7 +65,7 @@ namespace river {
|
||||
const std::vector<audio::channel>& _map,
|
||||
audio::format _format,
|
||||
const std::shared_ptr<river::io::Node>& _node,
|
||||
bool _isInput);
|
||||
const std::shared_ptr<const ejson::Object>& _config);
|
||||
public:
|
||||
/**
|
||||
* @brief Destructor
|
||||
@ -71,7 +76,7 @@ namespace river {
|
||||
const std::vector<audio::channel>& _map,
|
||||
audio::format _format,
|
||||
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.
|
||||
*/
|
||||
|
@ -23,7 +23,10 @@ std::shared_ptr<river::Manager> river::Manager::create(const std::string& _appli
|
||||
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_ERROR("you must set a basic configuration file for virtual configuration: DATA:virtual.json");
|
||||
}
|
||||
}
|
||||
|
||||
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> > 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;
|
||||
}
|
||||
|
||||
std::vector<std::pair<std::string,std::string> > river::Manager::getListStreamOutput() {
|
||||
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;
|
||||
}
|
||||
|
||||
@ -61,13 +81,26 @@ std::shared_ptr<river::Interface> river::Manager::createOutput(float _freq,
|
||||
audio::format _format,
|
||||
const std::string& _streamName,
|
||||
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:
|
||||
std::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
|
||||
// get the output or input channel :
|
||||
std::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
|
||||
// create user iterface:
|
||||
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).
|
||||
m_listOpenInterface.push_back(interface);
|
||||
return interface;
|
||||
@ -78,13 +111,26 @@ std::shared_ptr<river::Interface> river::Manager::createInput(float _freq,
|
||||
audio::format _format,
|
||||
const std::string& _streamName,
|
||||
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:
|
||||
std::shared_ptr<river::io::Manager> manager = river::io::Manager::getInstance();
|
||||
// get the output or input channel :
|
||||
std::shared_ptr<river::io::Node> node = manager->getNode(_streamName);
|
||||
// create user iterface:
|
||||
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).
|
||||
m_listOpenInterface.push_back(interface);
|
||||
return interface;
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <river/Interface.h>
|
||||
#include <audio/format.h>
|
||||
#include <audio/channel.h>
|
||||
#include <ejson/ejson.h>
|
||||
|
||||
namespace river {
|
||||
/**
|
||||
@ -20,6 +21,7 @@ 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<std::weak_ptr<river::Interface> > m_listOpenInterface; //!< List of all open Stream.
|
||||
protected:
|
||||
|
@ -16,6 +16,7 @@ river::io::Manager::Manager() {
|
||||
if (m_config.load("DATA:hardware.json") == false) {
|
||||
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) {
|
||||
for (size_t iii=0; iii< m_list.size(); ++iii) {
|
||||
std::shared_ptr<river::io::Node> tmppp = m_list[iii].lock();
|
||||
for (auto &it : m_list) {
|
||||
std::shared_ptr<river::io::Node> tmppp = it.lock();
|
||||
if ( tmppp != nullptr
|
||||
&& _name == tmppp->getName()) {
|
||||
return tmppp;
|
||||
|
@ -69,7 +69,7 @@ int32_t river::io::Node::airtAudioCallback(void* _outputBuffer,
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->isOutput() == false) {
|
||||
if (it->getMode() != river::modeInterface_output) {
|
||||
continue;
|
||||
}
|
||||
RIVER_VERBOSE(" IO name="<< it->getName());
|
||||
@ -91,7 +91,7 @@ int32_t river::io::Node::airtAudioCallback(void* _outputBuffer,
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->isInput() == false) {
|
||||
if (it->getMode() != river::modeInterface_feedback) {
|
||||
continue;
|
||||
}
|
||||
RIVER_VERBOSE(" IO name="<< it->getName() << " (feedback)");
|
||||
@ -106,6 +106,9 @@ int32_t river::io::Node::airtAudioCallback(void* _outputBuffer,
|
||||
if (it == nullptr) {
|
||||
continue;
|
||||
}
|
||||
if (it->getMode() != river::modeInterface_input) {
|
||||
continue;
|
||||
}
|
||||
RIVER_INFO(" IO name="<< it->getName());
|
||||
it->systemNewInputData(_time, inputBuffer, _nbChunk);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user