[DEV] add a basic tool to record audio sentence/ word or other things ...
This commit is contained in:
parent
1773297dab
commit
715598a0ae
@ -1,6 +1,6 @@
|
|||||||
/** @file
|
/** @file
|
||||||
* @author Edouard DUPIN
|
* @author Edouard DUPIN
|
||||||
* @copyright 2015, Edouard DUPIN, all right reserved
|
* @copyright 2019, Edouard DUPIN, all right reserved
|
||||||
* @license MPL v2.0 (see license file)
|
* @license MPL v2.0 (see license file)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#include <ewol/widget/Manager.hpp>
|
#include <ewol/widget/Manager.hpp>
|
||||||
#include <ewol/context/Context.hpp>
|
#include <ewol/context/Context.hpp>
|
||||||
#include <audio/river/widget/TemporalViewer.hpp>
|
#include <audio/river/widget/TemporalViewer.hpp>
|
||||||
|
#include <etk/theme/theme.hpp>
|
||||||
|
|
||||||
static const etk::String configurationRiver =
|
static const etk::String configurationRiver =
|
||||||
"{\n"
|
"{\n"
|
||||||
@ -34,9 +35,38 @@ static const etk::String configurationRiver =
|
|||||||
|
|
||||||
class MainApplication : public ewol::context::Application {
|
class MainApplication : public ewol::context::Application {
|
||||||
public:
|
public:
|
||||||
bool init(ewol::Context& _context, size_t _initId) {
|
virtual void onCreate(ewol::Context& _context) override {
|
||||||
APPL_INFO("==> Init APPL (START) [" << gale::getBoardType() << "] (" << gale::getCompilationMode() << ")");
|
APPL_INFO(" == > CREATE ... (START) [" << gale::getBoardType() << "] (" << gale::getCompilationMode() << ") (BEGIN)");
|
||||||
|
for( int32_t iii=0 ; iii<_context.getCmd().size(); iii++) {
|
||||||
|
etk::String tmpppp = _context.getCmd().get(iii);
|
||||||
|
if ( tmpppp == "-h"
|
||||||
|
|| tmpppp == "--help") {
|
||||||
|
//APPL_PRINT(" --ctags=xxx c-flags-file-name" );
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
etk::theme::setName("COLOR", "color/white/");
|
||||||
|
|
||||||
|
_context.setSize(vec2(800, 600));
|
||||||
|
|
||||||
|
_context.setTitle("edn");
|
||||||
|
|
||||||
|
// select internal data for font ...
|
||||||
|
_context.getFontDefault().setUseExternal(true);
|
||||||
|
#ifdef __TARGET_OS__Android
|
||||||
|
_context.getFontDefault().set("FreeSerif", 19);
|
||||||
|
#else
|
||||||
|
_context.getFontDefault().set("FreeSerif;DejaVuSansMono",14);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// set the application icon ...
|
||||||
|
//_context.setIcon("DATA:///icon.png");
|
||||||
|
APPL_INFO("==> CREATE ... (END)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void onStart(ewol::Context& _context) override {
|
||||||
|
APPL_INFO("==> START ... (BEGIN)");
|
||||||
|
// init internal global value
|
||||||
audio::river::initString(configurationRiver);
|
audio::river::initString(configurationRiver);
|
||||||
|
|
||||||
_context.setSize(vec2(800, 600));
|
_context.setSize(vec2(800, 600));
|
||||||
@ -48,15 +78,54 @@ class MainApplication : public ewol::context::Application {
|
|||||||
audio::river::widget::TemporalViewer::createManagerWidget(_context.getWidgetManager());
|
audio::river::widget::TemporalViewer::createManagerWidget(_context.getWidgetManager());
|
||||||
|
|
||||||
ememory::SharedPtr<ewol::widget::Windows> basicWindows = appl::Windows::create();
|
ememory::SharedPtr<ewol::widget::Windows> basicWindows = appl::Windows::create();
|
||||||
|
if (basicWindows == null) {
|
||||||
|
APPL_ERROR("Can not allocate the basic windows");
|
||||||
|
_context.exit(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
// create the specific windows
|
// create the specific windows
|
||||||
_context.setWindows(basicWindows);
|
_context.setWindows(basicWindows);
|
||||||
APPL_INFO("==> Init APPL (END)");
|
|
||||||
return true;
|
// add files
|
||||||
|
APPL_INFO("show list of files : ");
|
||||||
|
/*
|
||||||
|
for( int32_t iii=0 ; iii<_context.getCmd().size(); iii++) {
|
||||||
|
etk::String tmpppp = _context.getCmd().get(iii);
|
||||||
|
if (tmpppp.startWith("--ctags=") == true) {
|
||||||
|
etk::String name = tmpppp.extract(8);
|
||||||
|
APPL_INFO("Load ctag file : \"" << name << "\"" );
|
||||||
|
appl::setCtagsFileName(name);
|
||||||
|
} else if ( tmpppp == "-h"
|
||||||
|
|| tmpppp == "--help") {
|
||||||
|
// nothing to do ...
|
||||||
|
} else {
|
||||||
|
etk::Path file(tmpppp);
|
||||||
|
if (etk::path::isFile(file) == true) {
|
||||||
|
APPL_INFO("need load file : \"" << file << "\"" );
|
||||||
|
m_bufferManager->open(file);
|
||||||
|
} else if (etk::path::isDirectory(file) == true) {
|
||||||
|
etk::Vector<etk::Path> listOfFiles = etk::path::list(file, etk::path::LIST_FILE);
|
||||||
|
for (auto &it: listOfFiles) {
|
||||||
|
if (etk::path::isFile(it) == true) {
|
||||||
|
APPL_INFO("need load file : \"" << it << "\"" );
|
||||||
|
m_bufferManager->open(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
APPL_INFO("==> START ... (END)");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
void unInit(ewol::Context& _context) {
|
void onStop(ewol::Context& _context) override {
|
||||||
APPL_INFO("==> Un-Init APPL (START)");
|
APPL_INFO("==> STOP ... (START)");
|
||||||
// nothing to do...
|
APPL_INFO("==> STOP ... (END)");
|
||||||
APPL_INFO("==> Un-Init APPL (END)");
|
}
|
||||||
|
void onKillDemand(ewol::Context& _context) override {
|
||||||
|
APPL_INFO("==> User demand kill ... (START)");
|
||||||
|
_context.exit(0);
|
||||||
|
APPL_INFO("==> User demand kill ... (END)");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
70
tool/recoWord/appl/Windows.cpp
Normal file
70
tool/recoWord/appl/Windows.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2019, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ewol/ewol.hpp>
|
||||||
|
#include <appl/debug.hpp>
|
||||||
|
#include <appl/Windows.hpp>
|
||||||
|
#include <ewol/widget/Label.hpp>
|
||||||
|
#include <ewol/widget/Button.hpp>
|
||||||
|
#include <appl/widget/DataViewer.hpp>
|
||||||
|
#include <etk/tool.hpp>
|
||||||
|
|
||||||
|
appl::Windows::Windows() :
|
||||||
|
m_composer(null) {
|
||||||
|
addObjectType("appl::Windows");
|
||||||
|
propertyTitle.setDirectCheck("River IO viewer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void appl::Windows::init() {
|
||||||
|
ewol::widget::Windows::init();
|
||||||
|
APPL_ERROR("Load Application");
|
||||||
|
etk::String composition = etk::String("");
|
||||||
|
composition += "<sizer mode='vert'>\n";
|
||||||
|
composition += " <sizer mode='hori' lock='true' min-size='10,10%'>\n";
|
||||||
|
composition += " <button name='bt-record' expend='true' fill='true'>\n";
|
||||||
|
composition += " <label>\n";
|
||||||
|
composition += " Start/Stop record\n";
|
||||||
|
composition += " </label>\n";
|
||||||
|
composition += " </button>\n";
|
||||||
|
composition += " <button name='bt-reset' expend='true' fill='true'>\n";
|
||||||
|
composition += " <label>\n";
|
||||||
|
composition += " Reset Currrent Record\n";
|
||||||
|
composition += " </label>\n";
|
||||||
|
composition += " </button>\n";
|
||||||
|
composition += " </sizer>\n";
|
||||||
|
composition += " <DataViewer name='displayer' expand='true' fill='true'/>\n";
|
||||||
|
composition += "</sizer>\n";
|
||||||
|
|
||||||
|
m_composer = ewol::widget::Composer::create();
|
||||||
|
if (m_composer == null) {
|
||||||
|
APPL_CRITICAL(" An error occured ... in the windows creatrion ...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
APPL_ERROR("Composer LOAD [BEGIN]");
|
||||||
|
m_composer->loadFromString(composition);
|
||||||
|
setSubWidget(m_composer);
|
||||||
|
APPL_ERROR("Composer LOAD [ END ]");
|
||||||
|
subBind(ewol::widget::Button, "bt-record", signalPressed, sharedFromThis(), &appl::Windows::onCallbackRecord);
|
||||||
|
subBind(ewol::widget::Button, "bt-reset", signalPressed, sharedFromThis(), &appl::Windows::onCallbackGenerate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void appl::Windows::onCallbackRecord() {
|
||||||
|
APPL_INFO("Start/stop Record of data");
|
||||||
|
ememory::SharedPtr<appl::widget::DataViewer> tmpDisp = ememory::dynamicPointerCast<appl::widget::DataViewer>(getSubObjectNamed("displayer"));
|
||||||
|
if (tmpDisp != null) {
|
||||||
|
tmpDisp->recordToggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appl::Windows::onCallbackGenerate() {
|
||||||
|
ememory::SharedPtr<appl::widget::DataViewer> tmpDisp = ememory::dynamicPointerCast<appl::widget::DataViewer>(getSubObjectNamed("displayer"));
|
||||||
|
if (tmpDisp != null) {
|
||||||
|
tmpDisp->recordToggle();
|
||||||
|
tmpDisp->reset();
|
||||||
|
tmpDisp->recordToggle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
tool/recoWord/appl/Windows.hpp
Normal file
25
tool/recoWord/appl/Windows.hpp
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2019, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ewol/widget/Windows.hpp>
|
||||||
|
#include <ewol/widget/Composer.hpp>
|
||||||
|
|
||||||
|
namespace appl {
|
||||||
|
class Windows : public ewol::widget::Windows {
|
||||||
|
private:
|
||||||
|
ememory::SharedPtr<ewol::widget::Composer> m_composer;
|
||||||
|
protected:
|
||||||
|
Windows();
|
||||||
|
void init() override;
|
||||||
|
public:
|
||||||
|
DECLARE_FACTORY(Windows);
|
||||||
|
public: // callback functions
|
||||||
|
void onCallbackRecord();
|
||||||
|
void onCallbackGenerate();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
13
tool/recoWord/appl/debug.cpp
Normal file
13
tool/recoWord/appl/debug.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2019, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <appl/debug.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
int32_t appl::getLogId() {
|
||||||
|
static int32_t g_val = elog::registerInstance("RecoWord");
|
||||||
|
return g_val;
|
||||||
|
}
|
39
tool/recoWord/appl/debug.hpp
Normal file
39
tool/recoWord/appl/debug.hpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2019, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <elog/log.hpp>
|
||||||
|
|
||||||
|
namespace appl {
|
||||||
|
int32_t getLogId();
|
||||||
|
}
|
||||||
|
|
||||||
|
#define APPL_BASE(info,data) ELOG_BASE(appl::getLogId(),info,data)
|
||||||
|
|
||||||
|
#define APPL_PRINT(data) APPL_BASE(-1, data)
|
||||||
|
#define APPL_CRITICAL(data) APPL_BASE(1, data)
|
||||||
|
#define APPL_ERROR(data) APPL_BASE(2, data)
|
||||||
|
#define APPL_WARNING(data) APPL_BASE(3, data)
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define APPL_INFO(data) APPL_BASE(4, data)
|
||||||
|
#define APPL_DEBUG(data) APPL_BASE(5, data)
|
||||||
|
#define APPL_VERBOSE(data) APPL_BASE(6, data)
|
||||||
|
#define APPL_TODO(data) APPL_BASE(4, "TODO : " << data)
|
||||||
|
#else
|
||||||
|
#define APPL_INFO(data) do { } while(false)
|
||||||
|
#define APPL_DEBUG(data) do { } while(false)
|
||||||
|
#define APPL_VERBOSE(data) do { } while(false)
|
||||||
|
#define APPL_TODO(data) do { } while(false)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define APPL_ASSERT(cond,data) \
|
||||||
|
do { \
|
||||||
|
if (!(cond)) { \
|
||||||
|
APPL_CRITICAL(data); \
|
||||||
|
assert(!#cond); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
140
tool/recoWord/appl/main.cpp
Normal file
140
tool/recoWord/appl/main.cpp
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2019, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <etk/types.hpp>
|
||||||
|
#include <ewol/ewol.hpp>
|
||||||
|
#include <gale/context/commandLine.hpp>
|
||||||
|
|
||||||
|
#include <appl/debug.hpp>
|
||||||
|
#include <appl/Windows.hpp>
|
||||||
|
#include <ewol/object/Object.hpp>
|
||||||
|
#include <ewol/widget/Manager.hpp>
|
||||||
|
#include <ewol/context/Context.hpp>
|
||||||
|
#include <appl/widget/DataViewer.hpp>
|
||||||
|
#include <etk/theme/theme.hpp>
|
||||||
|
|
||||||
|
static const etk::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";
|
||||||
|
|
||||||
|
|
||||||
|
class MainApplication : public ewol::context::Application {
|
||||||
|
public:
|
||||||
|
virtual void onCreate(ewol::Context& _context) override {
|
||||||
|
APPL_INFO(" == > CREATE ... (START) [" << gale::getBoardType() << "] (" << gale::getCompilationMode() << ") (BEGIN)");
|
||||||
|
for( int32_t iii=0 ; iii<_context.getCmd().size(); iii++) {
|
||||||
|
etk::String tmpppp = _context.getCmd().get(iii);
|
||||||
|
if ( tmpppp == "-h"
|
||||||
|
|| tmpppp == "--help") {
|
||||||
|
//APPL_PRINT(" --ctags=xxx c-flags-file-name" );
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
etk::theme::setName("COLOR", "color/white/");
|
||||||
|
|
||||||
|
_context.setSize(vec2(800, 600));
|
||||||
|
|
||||||
|
_context.setTitle("edn");
|
||||||
|
|
||||||
|
// select internal data for font ...
|
||||||
|
_context.getFontDefault().setUseExternal(true);
|
||||||
|
#ifdef __TARGET_OS__Android
|
||||||
|
_context.getFontDefault().set("FreeSerif", 19);
|
||||||
|
#else
|
||||||
|
_context.getFontDefault().set("FreeSerif;DejaVuSansMono",14);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// set the application icon ...
|
||||||
|
//_context.setIcon("DATA:///icon.png");
|
||||||
|
APPL_INFO("==> CREATE ... (END)");
|
||||||
|
}
|
||||||
|
|
||||||
|
void onStart(ewol::Context& _context) override {
|
||||||
|
APPL_INFO("==> START ... (BEGIN)");
|
||||||
|
// init internal global value
|
||||||
|
audio::river::initString(configurationRiver);
|
||||||
|
|
||||||
|
_context.setSize(vec2(800, 600));
|
||||||
|
|
||||||
|
// select internal data for font ...
|
||||||
|
_context.getFontDefault().setUseExternal(true);
|
||||||
|
_context.getFontDefault().setSize(19);
|
||||||
|
|
||||||
|
appl::widget::DataViewer::createManagerWidget(_context.getWidgetManager());
|
||||||
|
|
||||||
|
ememory::SharedPtr<ewol::widget::Windows> basicWindows = appl::Windows::create();
|
||||||
|
if (basicWindows == null) {
|
||||||
|
APPL_ERROR("Can not allocate the basic windows");
|
||||||
|
_context.exit(-1);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// create the specific windows
|
||||||
|
_context.setWindows(basicWindows);
|
||||||
|
|
||||||
|
// add files
|
||||||
|
APPL_INFO("show list of files : ");
|
||||||
|
/*
|
||||||
|
for( int32_t iii=0 ; iii<_context.getCmd().size(); iii++) {
|
||||||
|
etk::String tmpppp = _context.getCmd().get(iii);
|
||||||
|
if (tmpppp.startWith("--ctags=") == true) {
|
||||||
|
etk::String name = tmpppp.extract(8);
|
||||||
|
APPL_INFO("Load ctag file : \"" << name << "\"" );
|
||||||
|
appl::setCtagsFileName(name);
|
||||||
|
} else if ( tmpppp == "-h"
|
||||||
|
|| tmpppp == "--help") {
|
||||||
|
// nothing to do ...
|
||||||
|
} else {
|
||||||
|
etk::Path file(tmpppp);
|
||||||
|
if (etk::path::isFile(file) == true) {
|
||||||
|
APPL_INFO("need load file : \"" << file << "\"" );
|
||||||
|
m_bufferManager->open(file);
|
||||||
|
} else if (etk::path::isDirectory(file) == true) {
|
||||||
|
etk::Vector<etk::Path> listOfFiles = etk::path::list(file, etk::path::LIST_FILE);
|
||||||
|
for (auto &it: listOfFiles) {
|
||||||
|
if (etk::path::isFile(it) == true) {
|
||||||
|
APPL_INFO("need load file : \"" << it << "\"" );
|
||||||
|
m_bufferManager->open(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
APPL_INFO("==> START ... (END)");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
void onStop(ewol::Context& _context) override {
|
||||||
|
APPL_INFO("==> STOP ... (START)");
|
||||||
|
APPL_INFO("==> STOP ... (END)");
|
||||||
|
}
|
||||||
|
void onKillDemand(ewol::Context& _context) override {
|
||||||
|
APPL_INFO("==> User demand kill ... (START)");
|
||||||
|
_context.exit(0);
|
||||||
|
APPL_INFO("==> User demand kill ... (END)");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Main of the program (This can be set in every case, but it is not used in Andoid...).
|
||||||
|
* @param std IO
|
||||||
|
* @return std IO
|
||||||
|
*/
|
||||||
|
int main(int _argc, const char *_argv[]) {
|
||||||
|
// second possibility
|
||||||
|
return ewol::run(ETK_NEW(MainApplication), _argc, _argv);
|
||||||
|
}
|
265
tool/recoWord/appl/widget/DataViewer.cpp
Normal file
265
tool/recoWord/appl/widget/DataViewer.cpp
Normal file
@ -0,0 +1,265 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <appl/debug.hpp>
|
||||||
|
#include <appl/widget/DataViewer.hpp>
|
||||||
|
#include <etk/tool.hpp>
|
||||||
|
#include <ewol/object/Manager.hpp>
|
||||||
|
|
||||||
|
static const int32_t nbSecondOffset = 3;
|
||||||
|
static const int32_t nbSecondSilence = 1;
|
||||||
|
static const int32_t nbSecond = 10;
|
||||||
|
static const int32_t nbSecondPreviousPost = 1;
|
||||||
|
static const float startThresholdLevel = 0.2;
|
||||||
|
static const float stopThresholdLevel = 0.1;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
appl::widget::DataViewer::DataViewer() :
|
||||||
|
m_minVal(-1.0f),
|
||||||
|
m_maxVal(1.0f),
|
||||||
|
m_sampleRate(48000) {
|
||||||
|
addObjectType("appl::widget::DataViewer");
|
||||||
|
}
|
||||||
|
|
||||||
|
void appl::widget::DataViewer::init() {
|
||||||
|
ewol::Widget::init();
|
||||||
|
m_manager = audio::river::Manager::create("appl::widget::DataViewer");
|
||||||
|
m_data.resize(m_sampleRate*nbSecond*3, 0.0);
|
||||||
|
m_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
appl::widget::DataViewer::~DataViewer() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void appl::widget::DataViewer::onDataReceived(const void* _data,
|
||||||
|
const audio::Time& _time,
|
||||||
|
size_t _nbChunk,
|
||||||
|
enum audio::format _format,
|
||||||
|
uint32_t _frequency,
|
||||||
|
const etk::Vector<audio::channel>& _map) {
|
||||||
|
ethread::UniqueLock lock(m_mutex);
|
||||||
|
if (_format != audio::format_float) {
|
||||||
|
APPL_ERROR("call wrong type ... (need int16_t)");
|
||||||
|
}
|
||||||
|
// get the curent power of the signal.
|
||||||
|
const float* data = static_cast<const float*>(_data);
|
||||||
|
for (size_t iii=0; iii<_nbChunk*_map.size(); ++iii) {
|
||||||
|
m_data.pushBack(data[iii]);
|
||||||
|
if (m_startAnalyse == false) {
|
||||||
|
if (data[iii] > startThresholdLevel) {
|
||||||
|
m_startAnalyse = true;
|
||||||
|
m_silenceCount = 0;
|
||||||
|
m_detectStartPosition = m_data.size();
|
||||||
|
m_detectStopPosition = m_data.size() + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (data[iii] > stopThresholdLevel) {
|
||||||
|
m_silenceCount = 0;
|
||||||
|
m_detectStopPosition = m_data.size();
|
||||||
|
m_detectMax = etk::max(m_detectMax, etk::abs(data[iii]));
|
||||||
|
} else {
|
||||||
|
m_silenceCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
if (m_data.size()>m_sampleRate*nbSecond*10) {
|
||||||
|
m_data.erase(m_data.begin(), m_data.begin()+(m_data.size()-m_sampleRate*nbSecond));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//markToRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void appl::widget::DataViewer::recordToggle() {
|
||||||
|
ethread::UniqueLock lock(m_mutex);
|
||||||
|
if (m_interface == null) {
|
||||||
|
//Get the generic input:
|
||||||
|
etk::Vector<audio::channel> channel;
|
||||||
|
channel.pushBack(audio::channel_frontLeft);
|
||||||
|
m_interface = m_manager->createInput(m_sampleRate,
|
||||||
|
channel,
|
||||||
|
audio::format_float,
|
||||||
|
"microphone");
|
||||||
|
if(m_interface == null) {
|
||||||
|
APPL_ERROR("null interface");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// set callback mode ...
|
||||||
|
m_interface->setInputCallback([&](const void* _data,
|
||||||
|
const audio::Time& _time,
|
||||||
|
size_t _nbChunk,
|
||||||
|
enum audio::format _format,
|
||||||
|
uint32_t _frequency,
|
||||||
|
const etk::Vector<audio::channel>& _map) {
|
||||||
|
onDataReceived(_data, _time, _nbChunk, _format, _frequency, _map);
|
||||||
|
});
|
||||||
|
// start the stream
|
||||||
|
m_interface->start();
|
||||||
|
m_PCH = getObjectManager().periodicCall.connect(this, &appl::widget::DataViewer::periodicCall);
|
||||||
|
} else {
|
||||||
|
m_interface->stop();
|
||||||
|
m_interface.reset();
|
||||||
|
m_PCH.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void appl::widget::DataViewer::onDraw() {
|
||||||
|
m_draw.draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void appl::widget::DataViewer::onRegenerateDisplay() {
|
||||||
|
//!< Check if we really need to redraw the display, if not needed, we redraw the previous data ...
|
||||||
|
if (needRedraw() == false) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// remove previous data
|
||||||
|
m_draw.clear();
|
||||||
|
// set background
|
||||||
|
m_draw.setColor(etk::color::black);
|
||||||
|
m_draw.setPos(vec2(0,0));
|
||||||
|
m_draw.rectangleWidth(m_size);
|
||||||
|
ethread::UniqueLock lock(m_mutex);
|
||||||
|
if (m_data.size() == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// create n section for display:
|
||||||
|
int32_t nbSlot = m_size.x();
|
||||||
|
int32_t sizeSlot = m_size.x()/nbSlot;
|
||||||
|
etk::Vector<float> list;
|
||||||
|
//APPL_INFO("nbSlot : " << nbSlot << " sizeSlot=" << sizeSlot << " m_size=" << m_size);
|
||||||
|
list.resize(nbSlot,0.0f);
|
||||||
|
int32_t step = m_sampleRate*nbSecond/nbSlot;
|
||||||
|
for (size_t kkk=0; kkk<m_sampleRate*nbSecond; ++kkk) {
|
||||||
|
int32_t id = kkk/step;
|
||||||
|
if (id < list.size()) {
|
||||||
|
if (kkk < m_data.size()-m_startDisplayOffset) {
|
||||||
|
list[id] = etk::max(list[id], m_data[m_startDisplayOffset+kkk]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// set all the line:
|
||||||
|
m_draw.setColor(etk::color::white);
|
||||||
|
m_draw.setThickness(1);
|
||||||
|
float origin = m_size.y()*0.5f;
|
||||||
|
|
||||||
|
float ratioY = m_size.y() / (m_maxVal - m_minVal);
|
||||||
|
float baseX = 0;
|
||||||
|
for (size_t iii=1; iii<list.size(); ++iii) {
|
||||||
|
m_draw.setPos(vec2(iii*sizeSlot, origin - ratioY*list[iii]));
|
||||||
|
m_draw.rectangle(vec2((iii+1)*sizeSlot, origin + ratioY*list[iii]));
|
||||||
|
if ((iii+1)*sizeSlot > m_size.x()) {
|
||||||
|
APPL_ERROR("wrong display position");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// detect sound
|
||||||
|
if (m_detectStopPosition > m_detectStartPosition) {
|
||||||
|
m_draw.setColor(etk::color::orange);
|
||||||
|
m_draw.setThickness(1);
|
||||||
|
float posStart = double(m_detectStartPosition-m_startDisplayOffset)/double(step)*sizeSlot;
|
||||||
|
float posStop = double(m_detectStopPosition-m_startDisplayOffset)/double(step)*sizeSlot;
|
||||||
|
m_draw.setPos(vec2(posStart, origin - ratioY*m_detectMax));
|
||||||
|
//m_draw.rectangle(vec2(posStop, origin + ratioY*m_detectMax));
|
||||||
|
//APPL_ERROR("draw position: " << posStart << " " << posStop);
|
||||||
|
|
||||||
|
m_draw.lineTo(vec2(posStart, origin + ratioY*m_detectMax));
|
||||||
|
m_draw.lineTo(vec2(posStop, origin + ratioY*m_detectMax));
|
||||||
|
m_draw.lineTo(vec2(posStop, origin - ratioY*m_detectMax));
|
||||||
|
m_draw.lineTo(vec2(posStart, origin - ratioY*m_detectMax));
|
||||||
|
}
|
||||||
|
// sound recorded
|
||||||
|
if (m_detectStopPosition > m_detectStartPosition) {
|
||||||
|
m_draw.setColor(etk::color::blue);
|
||||||
|
m_draw.setThickness(1);
|
||||||
|
float posStart = double(m_detectStartPosition-m_startDisplayOffset-nbSecondPreviousPost*m_sampleRate)/double(step)*sizeSlot;
|
||||||
|
float posStop = double(m_detectStopPosition-m_startDisplayOffset+nbSecondPreviousPost*m_sampleRate)/double(step)*sizeSlot;
|
||||||
|
m_draw.setPos(vec2(posStart, origin - ratioY*0.5));
|
||||||
|
m_draw.lineTo(vec2(posStart, origin + ratioY*0.5));
|
||||||
|
m_draw.lineTo(vec2(posStop, origin + ratioY*0.5));
|
||||||
|
m_draw.lineTo(vec2(posStop, origin - ratioY*0.5));
|
||||||
|
m_draw.lineTo(vec2(posStart, origin - ratioY*0.5));
|
||||||
|
}
|
||||||
|
// End of silence detection
|
||||||
|
if (m_detectStopPosition > m_detectStartPosition) {
|
||||||
|
m_draw.setColor(etk::color::red);
|
||||||
|
m_draw.setThickness(1);
|
||||||
|
float pos = double(m_detectStopPosition-m_startDisplayOffset+nbSecondSilence*m_sampleRate)/double(step)*sizeSlot;
|
||||||
|
m_draw.setPos(vec2(pos, origin - ratioY*0.5));
|
||||||
|
m_draw.lineTo(vec2(pos, origin + ratioY*0.5));
|
||||||
|
}
|
||||||
|
if (m_detectStopPosition <= m_detectStartPosition) {
|
||||||
|
m_draw.setColor(etk::color::red);
|
||||||
|
m_draw.setThickness(1);
|
||||||
|
// start threshold
|
||||||
|
m_draw.setPos(vec2(0, origin - ratioY*startThresholdLevel));
|
||||||
|
m_draw.lineTo(vec2(m_size.x(), origin - ratioY*startThresholdLevel));
|
||||||
|
m_draw.setPos(vec2(0, origin + ratioY*startThresholdLevel));
|
||||||
|
m_draw.lineTo(vec2(m_size.x(), origin + ratioY*startThresholdLevel));
|
||||||
|
} else {
|
||||||
|
m_draw.setColor(etk::color::red);
|
||||||
|
m_draw.setThickness(1);
|
||||||
|
float posStop = double(m_detectStopPosition-m_startDisplayOffset)/double(step)*sizeSlot;
|
||||||
|
// start threshold
|
||||||
|
m_draw.setPos(vec2(0, origin - ratioY*startThresholdLevel));
|
||||||
|
m_draw.lineTo(vec2(posStop, origin - ratioY*startThresholdLevel));
|
||||||
|
m_draw.setPos(vec2(0, origin + ratioY*startThresholdLevel));
|
||||||
|
m_draw.lineTo(vec2(posStop, origin + ratioY*startThresholdLevel));
|
||||||
|
|
||||||
|
// stop threshold
|
||||||
|
m_draw.setPos(vec2(posStop, origin - ratioY*stopThresholdLevel));
|
||||||
|
m_draw.lineTo(vec2(m_size.x(), origin - ratioY*stopThresholdLevel));
|
||||||
|
m_draw.setPos(vec2(posStop, origin + ratioY*stopThresholdLevel));
|
||||||
|
m_draw.lineTo(vec2(m_size.x(), origin + ratioY*stopThresholdLevel));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void appl::widget::DataViewer::periodicCall(const ewol::event::Time& _event) {
|
||||||
|
ethread::UniqueLock lock(m_mutex);
|
||||||
|
int32_t nbSampleDelta = _event.getDeltaCall() * float(m_sampleRate);
|
||||||
|
if (m_startAnalyse == false) {
|
||||||
|
if (m_data.size()>m_sampleRate*nbSecondOffset) {
|
||||||
|
m_startDisplayOffset = m_data.size() - m_sampleRate*nbSecondOffset;
|
||||||
|
/*
|
||||||
|
if (nbSampleDelta < m_data.size()) {
|
||||||
|
m_data.erase(m_data.begin(), m_data.begin()+nbSampleDelta);
|
||||||
|
} else {
|
||||||
|
m_data.erase(m_data.begin(), m_data.begin()+(m_data.size()-m_sampleRate*nbSecond));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (m_silenceCount > m_sampleRate*nbSecondSilence) {
|
||||||
|
if (m_interface != null) {
|
||||||
|
m_interface->stop();
|
||||||
|
m_interface.reset();
|
||||||
|
m_PCH.disconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
markToRedraw();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void appl::widget::DataViewer::reset() {
|
||||||
|
ethread::UniqueLock lock(m_mutex);
|
||||||
|
m_data.clear();
|
||||||
|
m_startDisplayOffset = 0;
|
||||||
|
m_startAnalyse = false;
|
||||||
|
m_silenceCount = 0;
|
||||||
|
m_detectStartPosition = 0;
|
||||||
|
m_detectStopPosition = 0;
|
||||||
|
m_detectMax = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
67
tool/recoWord/appl/widget/DataViewer.hpp
Normal file
67
tool/recoWord/appl/widget/DataViewer.hpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/** @file
|
||||||
|
* @author Edouard DUPIN
|
||||||
|
* @copyright 2011, Edouard DUPIN, all right reserved
|
||||||
|
* @license MPL v2.0 (see license file)
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <ewol/widget/Widget.hpp>
|
||||||
|
#include <ewol/compositing/Drawing.hpp>
|
||||||
|
#include <audio/river/river.hpp>
|
||||||
|
#include <audio/river/Manager.hpp>
|
||||||
|
#include <audio/river/Interface.hpp>
|
||||||
|
#include <ethread/Mutex.hpp>
|
||||||
|
|
||||||
|
namespace appl {
|
||||||
|
namespace widget {
|
||||||
|
class DataViewer : public ewol::Widget {
|
||||||
|
private:
|
||||||
|
mutable ethread::Mutex m_mutex;
|
||||||
|
private:
|
||||||
|
ewol::compositing::Drawing m_draw; //!< drawing instance
|
||||||
|
protected:
|
||||||
|
//! @brief constructor
|
||||||
|
DataViewer();
|
||||||
|
void init();
|
||||||
|
public:
|
||||||
|
DECLARE_WIDGET_FACTORY(DataViewer, "DataViewer");
|
||||||
|
//! @brief destructor
|
||||||
|
virtual ~DataViewer();
|
||||||
|
|
||||||
|
void recordToggle();
|
||||||
|
void reset();
|
||||||
|
private:
|
||||||
|
etk::Vector<float> m_data;
|
||||||
|
size_t m_startDisplayOffset = 0;
|
||||||
|
bool m_startAnalyse = false;
|
||||||
|
size_t m_silenceCount = 0;
|
||||||
|
float m_detectMax = 0;
|
||||||
|
size_t m_detectStartPosition = 0;
|
||||||
|
size_t m_detectStopPosition = 0;
|
||||||
|
private:
|
||||||
|
float m_minVal; //!< display minimum value
|
||||||
|
float m_maxVal; //!< display maximum value
|
||||||
|
public: // herited function
|
||||||
|
virtual void onDraw();
|
||||||
|
virtual void onRegenerateDisplay();
|
||||||
|
protected:
|
||||||
|
esignal::Connection m_PCH; //!< Periodic Call Handle to remove it when needed
|
||||||
|
/**
|
||||||
|
* @brief Periodic call to update grapgic display
|
||||||
|
* @param[in] _event Time generic event
|
||||||
|
*/
|
||||||
|
virtual void periodicCall(const ewol::event::Time& _event);
|
||||||
|
private:
|
||||||
|
ememory::SharedPtr<audio::river::Manager> m_manager;
|
||||||
|
ememory::SharedPtr<audio::river::Interface> m_interface;
|
||||||
|
void onDataReceived(const void* _data,
|
||||||
|
const audio::Time& _time,
|
||||||
|
size_t _nbChunk,
|
||||||
|
enum audio::format _format,
|
||||||
|
uint32_t _frequency,
|
||||||
|
const etk::Vector<audio::channel>& _map);
|
||||||
|
int32_t m_sampleRate;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
41
tool/recoWord/lutin_recoWord.py
Normal file
41
tool/recoWord/lutin_recoWord.py
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
import lutin.debug as debug
|
||||||
|
import lutin.tools as tools
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def get_type():
|
||||||
|
return "BINARY"
|
||||||
|
|
||||||
|
def get_desc():
|
||||||
|
return "Simpleaudio IO viewer and test ..."
|
||||||
|
|
||||||
|
def get_licence():
|
||||||
|
return "MPL-2"
|
||||||
|
|
||||||
|
def get_compagny_type():
|
||||||
|
return "com"
|
||||||
|
|
||||||
|
def get_compagny_name():
|
||||||
|
return "atria-soft"
|
||||||
|
|
||||||
|
def get_maintainer():
|
||||||
|
return ["Mr DUPIN Edouard <yui.heero@gmail.com>"]
|
||||||
|
|
||||||
|
def configure(target, my_module):
|
||||||
|
my_module.add_extra_flags()
|
||||||
|
my_module.add_src_file([
|
||||||
|
'appl/debug.cpp',
|
||||||
|
'appl/main.cpp',
|
||||||
|
'appl/Windows.cpp',
|
||||||
|
'appl/widget/DataViewer.cpp',
|
||||||
|
])
|
||||||
|
my_module.add_depend(['ewol', 'audio-river'])
|
||||||
|
my_module.add_path(".")
|
||||||
|
# set the package properties :
|
||||||
|
my_module.set_pkg("SECTION", ["Development"])
|
||||||
|
my_module.set_pkg("PRIORITY", "optional")
|
||||||
|
|
||||||
|
my_module.add_pkg("RIGHT", "RECORD_AUDIO")
|
||||||
|
return True
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user