[DEV] add virtual interface

This commit is contained in:
Edouard DUPIN 2015-02-12 22:08:23 +01:00
parent 1e10cc276b
commit a086674189
7 changed files with 99 additions and 32 deletions

View File

@ -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"
}
}

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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;

View File

@ -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:

View File

@ -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;

View File

@ -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);
}