[DOC] Start riting tutorials and basic documentation.

This commit is contained in:
Edouard DUPIN 2015-03-22 20:44:37 +01:00
parent 3891b0ac52
commit 1c34c157ab
13 changed files with 548 additions and 1 deletions

41
doc/001_bases.bb Normal file
View File

@ -0,0 +1,41 @@
=?=RIVER: Bases =?=
__________________________________________________
[right][tutorial[000_Build | Next: Tutorals]][/right]
=== Overview:===
===User requires:===
To use ewol you need to know only C++ language. It could be usefull to know:
:** [b]Python[/b] for all build tool.
:** [b]git[/b] for all version management
:** [b]Audio[/b] Basic knowlege of audio streaming af data organisation.
=== Architecture:===
River has been designed to replace the pulseAudio basic asyncronous interface that create
more problem that it will solve. The second point is that is not enougth portable to be
embended in a proprietary software without distributing all the sources (Ios).
Start at this point we will have simple objectives :
:** manage multiple Low level interface: (done by the [lib[airtaudio | AirTAudio]] interface):
::** for linux
:::** Alsa
:::** Pulse
:::** Oss
::** for Mac-OsX
:::** CoreAudio
::** for IOs
:::** CoreAudio (embended version)
::** for Windows
:::** ASIO
::** For Android
:::** Java (JDK-6)
:** Synchronous interface ==> no delay and reduce latency
:** Manage the thread priority (need sometimes to be more reactive)
:** manage mixing of some flow (2 inputs stereo and the user want 1 input quad)
:** AEC Acoustic Echo Cancelation (TODO : in the current implementation we have a simple sound cutter)
:** Equalizer (done with [lib[drain | Drain])
:** Resmpling (done by the libspeexDSP)
:** Correct volume management (and configurable)
:** Fade-in and Fade-out (done with [lib[drain | Drain])
:** Channel reorganisation (done with [lib[drain | Drain])
:** A correct feedback interface

36
doc/faq.bb Normal file
View File

@ -0,0 +1,36 @@
=?= FAQ =?=
== What is ewol licence ==
This is really simple : APACHE-2 :
Copyright ewol Edouard DUPIN
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[[http://www.apache.org/licenses/LICENSE-2.0]]
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
== Why we use "DECLARE_FACTORY" Macro ? ==
For some reason!!! But everything might be clear:
:** In ewol we masively use std::shared_ptr<xxx> (I have create my own but it is not "standard" (I like when we use genecic system)).
:** The main class : [class[ewol::Object]] herited from [i]std::enable_shared_from_this<Object>[/i] to permit to access at his own [i]std::shared_ptr[/i].
:** Acces At his own [i]std::shared_ptr[/i] is not allowed in the class contructor/destructor.
:** Many time for meta-widget we need to propagate our [i]std::shared_ptr[/i] in child.
Then for all these reasons, I have create a simple MACRO that create a static template funtion that create the object and just after
creation call the init(...) function to permit to create a complex widget or others with some writing convinience.

69
doc/index.bb Normal file
View File

@ -0,0 +1,69 @@
== [center]RIVER library[/center] ==
__________________________________________________
===What is RIVER, and how can I use it?===
RIVER is a multi-platform library to manage the input and output audio flow.
It can be compared with PulseAudio or Jack, but at the difference at the 2 interfaces
it is designed to be multi-platform and is based on licence that permit to integrate it
on every program we want.
===Where can I use it?===
Everywhere! RIVER is cross-platform devolopped to support bases OS:
: ** Linux (over Alsa, Pulseaudio, JackD)
: ** Windows (over ASIO)
: ** MacOs (over CoreAudio)
: ** Android (Over Ewol wrapper little complicated need to be change later)
: ** IOs (over CoreAudio for ios)
===What languages are supported?===
RIVER is written in C++11 with posibilities to compile it with C++03 + Boost
===Are there any licensing restrictions?===
RIVER is [b]FREE software[/b] and [i]all sub-library are FREE and staticly linkable !!![/i]
That allow you to use it for every program you want, including those developing proprietary software, without any license fees or royalties.
[note]The static support is important for some platform like IOs, and this limit the external library use at some license like :
:** BSD*
:** MIT
:** APPACHE-2
:** PNG
:** ZLIB
This exclude the classical extern library with licence:
:** L-GPL
:** GPL
[/note]
==== License (APACHE 2) ====
Copyright ewol Edouard DUPIN
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
[[http://www.apache.org/licenses/LICENSE-2.0]]
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
==== Depends library: ====
===== License: =====
:** [b][lib[etk | e-tk]][/b] : APACHE-2
:** [b][lib[airtaudio | airtaudio]][/b] : MIT/APACHE-2
:** [b][lib[ejson | e-json]][/b] : APACHE-2
:** [b][lib[drain | Drain]][/b] : APACHE-2
===== Program Using RIVER =====
:** [b][[http://play.google.com/store/apps/details?id=com.edouarddupin.worddown | worddown]][/b] : (Proprietary) Worddown is a simple word game threw [lib[ewolsa | ewol-simple-audio]].
== Main documentation: ==
[doc[001_bases | Global Documantation]]
[tutorial[000_Build | Tutorials]]

59
doc/tutorial/000_Build.bb Normal file
View File

@ -0,0 +1,59 @@
=?=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.
=== Linux dependency packages ===
[code style=shell]
sudo apt-get install g++ zlib1g-dev libasound2-dev
# if you want to compile with clang :
sudo apt-get install clang
[/code]
=== Download instructions ===
Download the software : This is the simple way You really need only a part of the ewol framework
[code style=shell]
# create a working directory path
mkdir your_workspace_path
cd your_workspace_path
# clone ewol and all sub-library
git clone git://github.com/HeeroYui/ewol.git
cd ewol
git submodule init
git submodule update
cd ..
[/code]
If you prefer creating with the packege you needed :
[code style=shell]
mkdir -p your_workspace_path
cd your_workspace_path
# download all you needs
git clone git://github.com/HeeroYui/lutin.git
git clone git://github.com/HeeroYui/etk.git
git clone git://github.com/HeeroYui/audio.git
git clone git://github.com/HeeroYui/ejson.git
git clone git://github.com/HeeroYui/airtaudio.git
git clone git://github.com/HeeroYui/drain.git
git clone git://github.com/HeeroYui/river.git
[/code]
[note]
The full build tool documentation is availlable here : [[http://heeroyui.github.io/lutin/ | lutin]]
[/note]
=== Common build instructions ===
Build the basic examples & test:
[code style=shell]
./ewol/build/lutin.py -mdebug river_sample_read
[/code]
To run an application you will find it directly on the out 'staging' tree :
[code style=shell]
./out/Linux/debug/staging/clang/river_sample_read/usr/bin/river_sample_read -l4
[/code]

97
doc/tutorial/001_Read.bb Normal file
View File

@ -0,0 +1,97 @@
=== Objectif ===
:** Understand basis of river
:** 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]]
=== Bases: ===
When you will create an application based on the river audio interface you need :
==== Include: ====
Include manager and interface node
[code style=c++]
#include <river/river.h>
#include <river/Manager.h>
#include <river/Interface.h>
[/code]
==== Initilize the River library: ====
We first need to initialize etk sub library (needed to select the log level of sub-libraries and file access abstraction
[code style=c++]
// the only one init for etk:
etk::init(_argc, _argv);
[/code]
Now we will initilaize the river library.
To do this We have 2 posibilities:
:** With a file:
[code style=c++]
// initialize river interface
river::init("DATA:configFileName.json");
[/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);
[/code]
For the example we select the second solution (faster to implement example and resource at the same position.
river::init / river::initString must be called only one time for all the application, this represent the hardware configuration.
It is Nearly not dynamic
To understand the configuration file Please see [tutorial[004_ConfigurationFile | Configuration file]]
// Create the River manager for tha application or part of the application.
std11::shared_ptr<river::Manager> manager = river::Manager::create("river_sample_read");
// create interface:
std11::shared_ptr<river::Interface> interface;
//Get the generic input:
interface = manager->createInput(48000,
std::vector<audio::channel>(),
audio::format_int16,
"microphone");
if(interface == nullptr) {
std::cout << "nullptr interface" << std::endl;
return -1;
}
// 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;

View File

View File

View File

View File

@ -31,7 +31,6 @@ def create(target):
myModule.add_module_depend(['river', 'gtest', 'etk'])
# add the currrent module at the
return myModule

View File

@ -0,0 +1,27 @@
#!/usr/bin/python
import lutinModule as module
import lutinTools as tools
import lutinDebug as debug
def get_desc():
return "river_sample_read : Read some data"
def create(target):
myModule = module.Module(__file__, 'river_sample_read', 'BINARY')
myModule.add_src_file([
'main.cpp',
])
myModule.add_module_depend(['river', 'etk'])
return myModule

93
sample/read/main.cpp Normal file
View File

@ -0,0 +1,93 @@
/** @file
* @author Edouard DUPIN
* @copyright 2015, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <river/river.h>
#include <river/Manager.h>
#include <river/Interface.h>
#include <etk/etk.h>
#include <unistd.h>
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";
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<audio::channel>& _map) {
if (_format != audio::format_int16) {
std::cout << "[ERROR] call wrong type ... (need int16_t)" << std::endl;
}
const int16_t* data = static_cast<const int16_t*>(_data);
int64_t value = 0;
for (size_t iii=0; iii<_nbChunk*_map.size(); ++iii) {
value += std::abs(data[iii]);
}
value /= (_nbChunk*_map.size());
std::cout << "Get data ... average=" << int32_t(value) << std::endl;
}
int main(int _argc, char **_argv) {
// the only one init for etk:
etk::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if ( data == "-h"
|| data == "--help") {
std::cout << "Help : " << std::endl;
std::cout << " ./xxx ---" << std::endl;
exit(0);
}
}
// initialize river interface
river::initString(configurationRiver);
// Create the River manager for tha application or part of the application.
std11::shared_ptr<river::Manager> manager = river::Manager::create("river_sample_read");
// create interface:
std11::shared_ptr<river::Interface> interface;
//Get the generic input:
interface = manager->createInput(48000,
std::vector<audio::channel>(),
audio::format_int16,
"microphone");
if(interface == nullptr) {
std::cout << "nullptr interface" << std::endl;
return -1;
}
// 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;
}

View File

@ -0,0 +1,27 @@
#!/usr/bin/python
import lutinModule as module
import lutinTools as tools
import lutinDebug as debug
def get_desc():
return "river_sample_write : Write some data"
def create(target):
myModule = module.Module(__file__, 'river_sample_write', 'BINARY')
myModule.add_src_file([
'main.cpp',
])
myModule.add_module_depend(['river', 'etk'])
return myModule

99
sample/write/main.cpp Normal file
View File

@ -0,0 +1,99 @@
/** @file
* @author Edouard DUPIN
* @copyright 2015, Edouard DUPIN, all right reserved
* @license APACHE v2.0 (see license file)
*/
#include <river/river.h>
#include <river/Manager.h>
#include <river/Interface.h>
#include <etk/etk.h>
#include <unistd.h>
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";
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<audio::channel>& _map) {
static double phase = 0;
if (_format != audio::format_int16) {
std::cout << "[ERROR] call wrong type ... (need int16_t)" << std::endl;
}
int16_t* data = static_cast<int16_t*>(_data);
double baseCycle = 2.0*M_PI/(double)48000 * (double)550;
for (int32_t iii=0; iii<_nbChunk; iii++) {
for (int32_t jjj=0; jjj<_map.size(); jjj++) {
data[_map.size()*iii+jjj] = cos(phase) * 30000;
}
phase += baseCycle;
if (phase >= 2*M_PI) {
phase -= 2*M_PI;
}
}
}
int main(int _argc, char **_argv) {
// the only one init for etk:
etk::init(_argc, _argv);
for (int32_t iii=0; iii<_argc ; ++iii) {
std::string data = _argv[iii];
if ( data == "-h"
|| data == "--help") {
std::cout << "Help : " << std::endl;
std::cout << " ./xxx ---" << std::endl;
exit(0);
}
}
// initialize river interface
river::initString(configurationRiver);
// Create the River manager for tha application or part of the application.
std11::shared_ptr<river::Manager> manager = river::Manager::create("river_sample_read");
// create interface:
std11::shared_ptr<river::Interface> interface;
//Get the generic input:
interface = manager->createOutput(48000,
std::vector<audio::channel>(),
audio::format_int16,
"speaker");
if(interface == nullptr) {
std::cout << "nullptr interface" << std::endl;
return -1;
}
// 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));
// 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;
}