From 3f6d7364545fee1988e85bf3408ced565d7d4905 Mon Sep 17 00:00:00 2001 From: Edouard DUPIN Date: Mon, 23 Mar 2015 21:26:45 +0100 Subject: [PATCH] [DOC] start doc might be OK --- Doxyfile | 36 ++++++ doc/tutorial/000_Build.bb | 2 - doc/tutorial/001_Read.bb | 155 ++++++++++++++++++-------- doc/tutorial/002_Write.bb | 84 ++++++++++++++ doc/tutorial/003_FeadBack.bb | 25 +++++ doc/tutorial/004_ConfigurationFile.bb | 70 ++++++++++++ river/Manager.cpp | 24 +++- 7 files changed, 346 insertions(+), 50 deletions(-) create mode 100644 Doxyfile diff --git a/Doxyfile b/Doxyfile new file mode 100644 index 0000000..d92eebe --- /dev/null +++ b/Doxyfile @@ -0,0 +1,36 @@ +PROJECT_NAME = river +PROJECT_NUMBER = latest +OUTPUT_DIRECTORY = dox/ +SORT_MEMBERS_CTORS_1ST = YES +SORT_GROUP_NAMES = YES +SORT_BY_SCOPE_NAME = YES +SHOW_NAMESPACES = YES +RECURSIVE = YES +EXTRACT_ALL = NO +EXCLUDE_PATTERNS = */examples/* +SOURCE_BROWSER = NO +ALPHABETICAL_INDEX = NO +GENERATE_HTML = YES +#HTML_HEADER = /home/edupin/work/master-2015-02-04/doc/templates/doxygen/header.html +#HTML_FOOTER = /home/edupin/work/master-2015-02-04/doc/templates/doxygen/footer.html +#HTML_STYLESHEET = /home/edupin/work/master-2015-02-04/doc/templates/doxygen/doxygen.css +GENERATE_TREEVIEW = YES +CLASS_DIAGRAMS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = NO +INCLUDE_GRAPH = NO +INCLUDED_BY_GRAPH = NO +GRAPHICAL_HIERARCHY = NO +DOT_MULTI_TARGETS = YES +INPUT = river/ +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +SKIP_FUNCTION_MACROS = YES +BRIEF_MEMBER_DESC = NO +VERBATIM_HEADERS = NO +TAB_SIZE = 4 +#EXAMPLE_PATH = sample/ +GENERATE_XML = YES +GENERATE_LATEX = NO +GENERATE_TAGFILE = dox/ruver-doc.tag diff --git a/doc/tutorial/000_Build.bb b/doc/tutorial/000_Build.bb index e4afbac..00b163f 100644 --- a/doc/tutorial/000_Build.bb +++ b/doc/tutorial/000_Build.bb @@ -1,6 +1,4 @@ =?=River extract and build examples an example=?= -__________________________________________________ -[left][doc[001_bases | Previous: Doc]][/left] [right][tutorial[001_Read | Next: Create an input interface]][/right] All developpement software will start by getting the dependency and the sources. diff --git a/doc/tutorial/001_Read.bb b/doc/tutorial/001_Read.bb index f06ffc4..dafe5a6 100644 --- a/doc/tutorial/001_Read.bb +++ b/doc/tutorial/001_Read.bb @@ -4,7 +4,7 @@ :** Create a simple recording interface that print the average of sample absolute value. === sample source: === - [[http:://github.com/HeeroYui/river.git/sample/read/ | sample source]] + [[http://github.com/HeeroYui/river.git/sample/read/ | sample source]] === Bases: === @@ -37,22 +37,22 @@ To do this We have 2 posibilities: [/code] :** With a json string: [code style=c++] - static const std::string configurationRiver = - "{\n" - " microphone:{\n" - " io:'input',\n" - " map-on:{\n" - " interface:'auto',\n" - " name:'default',\n" - " },\n" - " frequency:0,\n" - " channel-map:['front-left', 'front-right'],\n" - " type:'auto',\n" - " nb-chunk:1024\n" - " }\n" - "}\n"; - // initialize river interface - river::initString(configurationRiver); +static const std::string configurationRiver = + "{\n" + " microphone:{\n" + " io:'input',\n" + " map-on:{\n" + " interface:'auto',\n" + " name:'default',\n" + " },\n" + " frequency:0,\n" + " channel-map:['front-left', 'front-right'],\n" + " type:'auto',\n" + " nb-chunk:1024\n" + " }\n" + "}\n"; +// initialize river interface +river::initString(configurationRiver); [/code] For the example we select the second solution (faster to implement example and resource at the same position. @@ -62,36 +62,97 @@ It is Nearly not dynamic To understand the configuration file Please see [tutorial[004_ConfigurationFile | Configuration file]] +[note] +This json is parsed by the [lib[ejson | e-json library]] it containe some update like: +:** Optionnal " in the name of element. +:** The possibilities to remplace " with '. +[/note] - // Create the River manager for tha application or part of the application. - std11::shared_ptr manager = river::Manager::create("river_sample_read"); - // create interface: - std11::shared_ptr interface; - //Get the generic input: - interface = manager->createInput(48000, - std::vector(), - audio::format_int16, - "microphone"); - if(interface == nullptr) { - std::cout << "nullptr interface" << std::endl; - return -1; +==== Get the river interface manager: ==== + +An application can have many interface and only one Manager, And a process can contain many application. + +Then, we will get the first application manager handle. + +[code style=c++] +// Create the River manager for tha application or part of the application. +std11::shared_ptr manager = river::Manager::create("river_sample_read"); +[/code] + +[note] +You can get back the application handle when you create a new one with the same name. +[/note] + +==== Create your read interface: ==== + +[code style=c++] +// create interface: +std11::shared_ptr interface; +//Get the generic input: +interface = manager->createInput(48000, + std::vector(), + audio::format_int16, + "microphone"); +[/code] + +Here we create an interface with: +:** The frequency of 48000 Hz. +:** The default Low level definition channel +:** A data interface of 16 bits samples coded in [-32768..32767] +:** Select input interaface name "microphone" + + +==== Get datas: ==== + +The best way to get data is to instanciate a simple callback. +The callback is called when sample arrive and you have the nbChunk/frequency +to process the data, otherwise you can generate error in data stream. + + +[code style=c++] +// set callback mode ... +interface->setInputCallback(std11::bind(&onDataReceived, + std11::placeholders::_1, + std11::placeholders::_2, + std11::placeholders::_3, + std11::placeholders::_4, + std11::placeholders::_5, + std11::placeholders::_6)); +[/code] + +==== Callback inplementation: ==== + +Simply declare your function and do what you want inside. + +[code style=c++] +void onDataReceived(const void* _data, + const std11::chrono::system_clock::time_point& _time, + size_t _nbChunk, + enum audio::format _format, + uint32_t _frequency, + const std::vector& _map) { + if (_format == audio::format_int16) { + // stuff here } - // set callback mode ... - interface->setInputCallback(std11::bind(&onDataReceived, - std11::placeholders::_1, - std11::placeholders::_2, - std11::placeholders::_3, - std11::placeholders::_4, - std11::placeholders::_5, - std11::placeholders::_6)); - // start the stream - interface->start(); - // wait 10 second ... - sleep(10); - // stop the stream - interface->stop(); - // remove interface and manager. - interface.reset(); - manager.reset(); - return 0; \ No newline at end of file +} +[/code] + +==== start and stop: ==== + +[code style=c++] +// start the stream +interface->start(); +// wait 10 second ... +sleep(10); +// stop the stream +interface->stop(); +[/code] + +==== Remove interfaces: ==== + +[code style=c++] +// remove interface and manager. +interface.reset(); +manager.reset(); +[/code] diff --git a/doc/tutorial/002_Write.bb b/doc/tutorial/002_Write.bb index e69de29..5b0bfb1 100644 --- a/doc/tutorial/002_Write.bb +++ b/doc/tutorial/002_Write.bb @@ -0,0 +1,84 @@ + +=== Objectif === +:** Understand write audio stream + +=== sample source: === + [[http://github.com/HeeroYui/river.git/sample/write/ | sample source]] + +=== Bases: === + +The writing work nearly like the read turoral. Then we will just see what has change. + +==== File configuration: ==== + +[code style=c++] +static const std::string configurationRiver = + "{\n" + " speaker:{\n" + " io:'output',\n" + " map-on:{\n" + " interface:'auto',\n" + " name:'default',\n" + " },\n" + " frequency:0,\n" + " channel-map:['front-left', 'front-right'],\n" + " type:'auto',\n" + " nb-chunk:1024,\n" + " volume-name:'MASTER'\n" + " }\n" + "}\n"; +[/code] + +==== Create your write interface: ==== + +[code style=c++] +// create interface: +std11::shared_ptr interface; +//Get the generic input: +interface = manager->createOutput(48000, + std::vector(), + audio::format_int16, + "speaker"); +[/code] + +Here we create an interface with: +:** The frequency of 48000 Hz. +:** The default Low level definition channel +:** A data interface of 16 bits samples coded in [-32768..32767] +:** Select input interaface name "speaker" + + +==== write datas: ==== + +The best way to get data is to instanciate a simple callback. +The callback is called when sample are needed and you have the nbChunk/frequency +to generate the data, otherwise you can generate error in data stream. + + +[code style=c++] +// set callback mode ... +interface->setOutputCallback(std11::bind(&onDataNeeded, + std11::placeholders::_1, + std11::placeholders::_2, + std11::placeholders::_3, + std11::placeholders::_4, + std11::placeholders::_5, + std11::placeholders::_6)); +[/code] + +==== Callback inplementation: ==== + +Simply declare your function and do what you want inside. + +[code style=c++] +void onDataNeeded(void* _data, + const std11::chrono::system_clock::time_point& _time, + size_t _nbChunk, + enum audio::format _format, + uint32_t _frequency, + const std::vector& _map) { + if (_format == audio::format_int16) { + // stuff here + } +} +[/code] diff --git a/doc/tutorial/003_FeadBack.bb b/doc/tutorial/003_FeadBack.bb index e69de29..5cf839a 100644 --- a/doc/tutorial/003_FeadBack.bb +++ b/doc/tutorial/003_FeadBack.bb @@ -0,0 +1,25 @@ + +=== Objectif === +:** Implement a feedback. + +=== Bases: === + +A feedback is a stream that is generated by an output. + +To get a feedback this is the same implementation of an input and link it on an output. + + +What change : + +[code style=c++] +//Get the generic feedback on speaker: +interface = manager->createFeedback(48000, + std::vector(), + audio::format_int16, + "speaker"); +[/code] + +[note] +Input interface does not provide feedback. +[/note] + diff --git a/doc/tutorial/004_ConfigurationFile.bb b/doc/tutorial/004_ConfigurationFile.bb index e69de29..ff82b58 100644 --- a/doc/tutorial/004_ConfigurationFile.bb +++ b/doc/tutorial/004_ConfigurationFile.bb @@ -0,0 +1,70 @@ + +=== Objectif === +:** Understand the architecture of the configuration file. +:** all that can be done with it. + + +=== Basis: === + +The river configuration file is a json file. We use [lib[ejson | e-json library]] to parse it then we have some writing facilities. + + +River provide a list a harware interface and virtual interface. + + +The hardware interface are provided by [lib[airtaudio | AirTAudio library]] then we will plug on every platform. + + +The file is simply architecture around a list of object: + +[code style=json] +{ + "speaker":{ + + }, + "microphone":{ + + }, + "mixed-in-out":{ + + }, +} +[/code] + +With this config we declare 3 interfaces : speaker, microphone and mixed-in-out. + + +=== Harware configuration: === + +In every interface we need to define some Element: +:** "io" : +:: Can be input/output/... depending of virtual interface... +:** "map-on": An object to configure airtaudio interface. +:** "frequency": 0 to automatic select one. Or the frequency to open harware device +:** "channel-map": List of all channel in the stream: +::** "front-left" +::** "front-center" +::** "front-right" +::** "rear-left" +::** "rear-center" +::** "rear-right" +::** "surround-left", +::** "surround-right", +::** "sub-woofer", +::** "lfe" +:** "type": Fomat to open the stream: +::** "auto": Detect the best type +::** "int8", +::** "int8-on-int16", +::** "int16", +::** "int16-on-int32", +::** "int24", +::** "int32", +::** "int32-on-int64", +::** "int64", +::** "float", +::** "double" +:** "nb-chunk": Number of chunk to open the stream. + + + diff --git a/river/Manager.cpp b/river/Manager.cpp index 8241d6a..0a12b08 100644 --- a/river/Manager.cpp +++ b/river/Manager.cpp @@ -15,9 +15,31 @@ #undef __class__ #define __class__ "Manager" +static std11::mutex g_mutex; +static std::vector > g_listOfAllManager; std11::shared_ptr river::Manager::create(const std::string& _applicationUniqueId) { - return std11::shared_ptr(new river::Manager(_applicationUniqueId)); + std11::unique_lock lock(g_mutex); + for (size_t iii=0; iii tmp = g_listOfAllManager[iii].lock(); + if (tmp == nullptr) { + continue; + } + if (tmp->m_applicationUniqueId == _applicationUniqueId) { + return tmp; + } + } + // create a new one: + std11::shared_ptr out = std11::shared_ptr(new river::Manager(_applicationUniqueId)); + // add it at the list: + for (size_t iii=0; iii