Initial working version.
This commit is contained in:
parent
ff643dd314
commit
f566198285
@ -1,5 +1,4 @@
|
||||
ACLOCAL_AMFLAGS = -I m4 # use custom macro's in ./m4
|
||||
|
||||
lib_LTLIBRARIES=
|
||||
bin_PROGRAMS=
|
||||
include_HEADERS=
|
||||
@ -16,9 +15,6 @@ include_HEADERS=
|
||||
# -Wno-multichar - turns off multi-character constant warnings from cmAudioFile.c
|
||||
|
||||
|
||||
WS_DIR = $(HOME)/sdk/libwebsockets/build/out
|
||||
|
||||
|
||||
AM_CPPFLAGS = -I.. -I$(srcdir)/src/libcw
|
||||
AM_CFLAGS = -Wno-multichar
|
||||
AM_CXXFLAGS = -Wno-multichar
|
||||
@ -38,7 +34,7 @@ endif
|
||||
if OS_LINUX
|
||||
|
||||
if OS_64
|
||||
AM_LDFLAGS += -L/usr/lib64
|
||||
AM_LDFLAGS += -L/usr/lib64/atlas -L/usr/lib64
|
||||
AM_CFLAGS += -m64
|
||||
endif
|
||||
|
||||
@ -86,8 +82,6 @@ if cwWEB
|
||||
endif
|
||||
|
||||
if cwWEBSOCK
|
||||
# AM_CPPFLAGS += -I$(WS_DIR)/include
|
||||
# AM_LDFLAGS += -L$(WS_DIR)/lib
|
||||
src_proj_proj_LDADD += -lwebsockets
|
||||
endif
|
||||
|
||||
|
@ -16,8 +16,6 @@ cd ${curdir}
|
||||
--enable-alsa \
|
||||
CFLAGS="-g -Wall" \
|
||||
CXXFLAGS="-g -Wall" \
|
||||
CPPFLAGS="-I${HOME}/sdk/libwebsockets/build/out/include" \
|
||||
LDFLAGS="-L${HOME}/sdk/libwebsockets/build/out/lib" \
|
||||
LIBS=
|
||||
|
||||
|
||||
|
59
src/proj/html/css/preset_sel.css
Normal file
59
src/proj/html/css/preset_sel.css
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
|
||||
.fragList {
|
||||
border: 1px solid LightSteelBlue;
|
||||
width: 1000px;
|
||||
height: 450px;
|
||||
}
|
||||
|
||||
.fragList label {
|
||||
width: 50px;
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
.fragList .uiNumbDisp {
|
||||
width: 25px;
|
||||
}
|
||||
|
||||
.fragPanel {
|
||||
border: 1px solid LightSteelBlue;
|
||||
padding-bottom: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.fragPanelRow {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
justify-content: space-around;
|
||||
}
|
||||
|
||||
.fragPresetCtl {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.fragPresetCtl:nth-of-type(even){
|
||||
border: 1px solid Yellow;
|
||||
}
|
||||
|
||||
.fragPresetCtl .uiNumber {
|
||||
border: 1px solid LightSteelBlue;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.fragPresetCtl .uiString {
|
||||
border: 1px solid LightSteelBlue;
|
||||
width: 80%;
|
||||
}
|
||||
|
||||
.fragNote {
|
||||
width: 575px;
|
||||
}
|
||||
|
||||
.uiRow {
|
||||
padding-bottom: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.velTunerPanel {
|
||||
border: 1px solid black;
|
||||
}
|
148
src/proj/html/css/ui.css
Normal file
148
src/proj/html/css/ui.css
Normal file
@ -0,0 +1,148 @@
|
||||
|
||||
body {
|
||||
background-color: LightCyan;
|
||||
}
|
||||
|
||||
|
||||
.title_disconnected {
|
||||
color: red;
|
||||
}
|
||||
|
||||
.title_connected {
|
||||
color: green;
|
||||
}
|
||||
|
||||
input, label, button, select {
|
||||
font-family: sans-serif;
|
||||
font-size: 10px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
|
||||
div {
|
||||
/*border: 1px solid black; */
|
||||
background-color: LightSteelBlue;
|
||||
}
|
||||
|
||||
div p {
|
||||
font-family: sans-serif;
|
||||
font-size: 12px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
background-color: LightSteelBlue;
|
||||
}
|
||||
|
||||
label {
|
||||
/*border: 1px solid red;*/
|
||||
width: 50px;
|
||||
padding-left: 10px;
|
||||
margin-top: 3px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.uiCtlDiv {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
.uiCtlDiv input {
|
||||
background-color: PowderBlue;
|
||||
}
|
||||
|
||||
.uiNumberDiv input {
|
||||
width: 50px;
|
||||
}
|
||||
|
||||
.uiPanel {
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
.uiRow {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
.uiCol {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
background-color: LightBlue;
|
||||
}
|
||||
|
||||
|
||||
/* outer log div - contains the log label and the log scroller */
|
||||
.uiLogDiv {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
align-items: flex-start; /* left justify */
|
||||
align-content: flex-stretch; /* fill horizontal space */
|
||||
|
||||
}
|
||||
|
||||
.uiLogDiv label {
|
||||
width: 100%;
|
||||
background-color: LightSteelBlue;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/* log scroller */
|
||||
.uiLog {
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
|
||||
height: 150px;
|
||||
overflow-x: hidden; /* 'hidden' to remove x scroll bar */
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
|
||||
background-color: PowderBlue;
|
||||
|
||||
}
|
||||
|
||||
/* The log text */
|
||||
.uiLog pre {
|
||||
}
|
||||
|
||||
|
||||
/* outer list div - contains the list label and the list scroller */
|
||||
.uiListDiv {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
align-items: flex-start; /* left justify */
|
||||
align-content: flex-stretch; /* fill horizontal space */
|
||||
|
||||
}
|
||||
|
||||
.uiListDiv label {
|
||||
width: 100%;
|
||||
background-color: LightSteelBlue;
|
||||
|
||||
}
|
||||
|
||||
.uiList {
|
||||
display:flex;
|
||||
flex-direction: column;
|
||||
|
||||
height: 100px;
|
||||
overflow-x: hidden; /* 'hidden' to remove scroll bar */
|
||||
overflow-y: auto;
|
||||
width: 100%;
|
||||
|
||||
background-color: PowderBlue;
|
||||
}
|
||||
|
||||
.uiStringDisp {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.uiSelected {
|
||||
border: 1px solid blue;
|
||||
}
|
24
src/proj/html/index.html
Normal file
24
src/proj/html/index.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Preset Selection App</title>
|
||||
<script type="text/javascript" src="js/ui.js"></script>
|
||||
<link href="css/ui.css" rel="stylesheet">
|
||||
<link href="css/preset_sel.css" rel="stylesheet">
|
||||
|
||||
<script text="text/javascript">
|
||||
window.addEventListener("load",main, false )
|
||||
</script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div id="appTitleDiv" class="uiRow">
|
||||
<p id="appTitleId">Preset Selection:</p>
|
||||
<p id="connectTitleId">Disconnected</p>
|
||||
</div>
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
1201
src/proj/html/js/ui.js
Normal file
1201
src/proj/html/js/ui.js
Normal file
File diff suppressed because it is too large
Load Diff
25
src/proj/html/ui.cfg
Normal file
25
src/proj/html/ui.cfg
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
main: {
|
||||
parent: "uiDivId"
|
||||
|
||||
panel: {
|
||||
|
||||
name: "panelDivId",
|
||||
title: "",
|
||||
|
||||
row: {
|
||||
button:{ name: quitBtnId, title:"Quit" },
|
||||
button:{ name: ioReportBtnId, title:"IO Report" },
|
||||
button:{ name: netPrintBtnId, title:"Print Network" }
|
||||
button:{ name: reportBtnId, title:"App Report" },
|
||||
button:{ name: latencyBtnId, title:"Latency Reset"},
|
||||
},
|
||||
|
||||
row: {
|
||||
number: { name:valueNumbId, title:"Value", min:0, max:10, step:1, decpl:0 },
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,3 +1,104 @@
|
||||
{
|
||||
param: "hello"
|
||||
param: 5,
|
||||
|
||||
libcw: {
|
||||
|
||||
io: {
|
||||
callbackMutexTimeOutMs: 100,
|
||||
}
|
||||
|
||||
ui: {
|
||||
physRootDir: "~/src/cw_io_template/src/proj/html",
|
||||
dfltPageFn: "index.html",
|
||||
port: 5687,
|
||||
rcvBufByteN: 2048,
|
||||
xmtBufByteN: 2048,
|
||||
fmtBufByteN: 4096,
|
||||
websockTimeOutMs: 50, // max time out while blocking for a websock event
|
||||
idleMsgPeriodMs: 50, // period without messages before an idle message is generated
|
||||
uiCfgFn: "ui.cfg", // default UI resource description
|
||||
asyncFl: false
|
||||
},
|
||||
|
||||
serial: {
|
||||
pollPeriodMs: 50,
|
||||
recvBufByteN: 512,
|
||||
|
||||
array: [
|
||||
{
|
||||
enableFl: false,
|
||||
asyncFl: false,
|
||||
label: "port1", // User label
|
||||
device: "/dev/ttyUSB0", // Serial device name
|
||||
baud: 115200,
|
||||
bits: 8,
|
||||
stop: 1,
|
||||
parity: "no",
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
midi: {
|
||||
parseBufByteCnt: 1024,
|
||||
appNameStr: "cwtest",
|
||||
fileDevName: "file_dev",
|
||||
fileDevReadAheadMicros: 3000,
|
||||
testFileLabel: "file_0",
|
||||
testFileEnableFl: false
|
||||
|
||||
file_ports: [
|
||||
|
||||
{ "label":"file_0",
|
||||
//"file": "/home/kevin/src/cwtest/src/cwtest/cfg/gutim_full/data1/beck1/record_4/midi.mid",
|
||||
"enable_fl": false },
|
||||
]
|
||||
|
||||
asyncFl: true,
|
||||
},
|
||||
|
||||
audio: {
|
||||
meterMs: 50, // audio meter filter length and meter callback period
|
||||
threadTimeOutMs: 50, // audio thread cond var time out
|
||||
|
||||
groupL: [
|
||||
{
|
||||
enableFl: false, // (req)
|
||||
asyncFl: true,
|
||||
label: "main", // (req) User label
|
||||
id: 0, // (req) User id (can also be set at runtime)
|
||||
srate: 48000, // (req) Sample rate used by all devices in this group
|
||||
dspFrameCnt: 64 // (req) Size of DSP processing buffers
|
||||
}
|
||||
],
|
||||
|
||||
deviceL: [
|
||||
{
|
||||
// System device name
|
||||
|
||||
//device: "Scarlett 18i20 USB USB Audio",
|
||||
device: "USB Audio CODEC USB Audio",
|
||||
//device: "HDA Intel PCH CS4208 Analog",
|
||||
|
||||
activeFl: false, // (req)
|
||||
meterFl: true, // (opt)
|
||||
label: "main", // (req) User label
|
||||
userId: 0, // (opt) User id (can also be set at runtime)
|
||||
framesPerCycle: 512, // (req) Samples per audio device cycle
|
||||
cycleCnt: 3, // (req) Count of device cycle buffers.
|
||||
inGroup: "main", // (opt) All devices in a group must be 'ready' to source
|
||||
outGroup: "main", // (opt) or sink data before an audio callback is made for that group
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
socket: {
|
||||
asyncFl: false,
|
||||
maxSocketCnt: 10,
|
||||
recvBufByteCnt: 4096,
|
||||
threadTimeOutMs: 50,
|
||||
socketL: [],
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -4,46 +4,272 @@
|
||||
#include "cwText.h"
|
||||
#include "cwObject.h"
|
||||
|
||||
#include "cwIo.h"
|
||||
|
||||
using namespace cw;
|
||||
|
||||
typedef struct app_str
|
||||
{
|
||||
object_t* cfg;
|
||||
unsigned value;
|
||||
const object_t* io_cfg;
|
||||
io::handle_t ioH;
|
||||
} app_t;
|
||||
|
||||
enum
|
||||
{
|
||||
kPanelDivId,
|
||||
kQuitBtnId,
|
||||
kIoReportBtnId,
|
||||
kNetPrintBtnId,
|
||||
kReportBtnId,
|
||||
kLatencyBtnId,
|
||||
kValueNumbId
|
||||
};
|
||||
|
||||
ui::appIdMap_t appIdMapA[] = {
|
||||
|
||||
{ ui::kRootAppId, kPanelDivId, "panelDivId" },
|
||||
{ kPanelDivId, kQuitBtnId, "quitBtnId" },
|
||||
{ kPanelDivId, kIoReportBtnId, "ioReportBtnId" },
|
||||
{ kPanelDivId, kNetPrintBtnId, "netPrintBtnId" },
|
||||
{ kPanelDivId, kReportBtnId, "reportBtnId" },
|
||||
{ kPanelDivId, kLatencyBtnId, "latencyBtnId" },
|
||||
{ kPanelDivId, kValueNumbId, "valueNumbId" }
|
||||
};
|
||||
|
||||
const unsigned appIdMapN = sizeof(appIdMapA)/sizeof(appIdMapA[0]);
|
||||
|
||||
void print( void* arg, const char* text )
|
||||
{
|
||||
printf("%s\n",text);
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
|
||||
rc_t _ui_value_callback(app_t* app, const io::ui_msg_t& m )
|
||||
{
|
||||
switch( m.appId )
|
||||
{
|
||||
case kQuitBtnId:
|
||||
io::stop( app->ioH );
|
||||
break;
|
||||
|
||||
case kIoReportBtnId:
|
||||
io::report(app->ioH);
|
||||
break;
|
||||
|
||||
case kNetPrintBtnId:
|
||||
break;
|
||||
|
||||
case kReportBtnId:
|
||||
break;
|
||||
|
||||
case kLatencyBtnId:
|
||||
latency_measure_report(app->ioH);
|
||||
latency_measure_setup(app->ioH);
|
||||
break;
|
||||
|
||||
case kValueNumbId:
|
||||
app->value = m.value->u.u;
|
||||
cwLogInfo("Setting value:%i",app->value);
|
||||
break;
|
||||
|
||||
}
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
rc_t _ui_echo_callback(app_t* app, const io::ui_msg_t& m )
|
||||
{
|
||||
switch( m.appId )
|
||||
{
|
||||
case kValueNumbId:
|
||||
{
|
||||
uiSendValue( app->ioH, io::uiFindElementUuId( app->ioH, kValueNumbId ), app->value );
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
rc_t _ui_callback( app_t* app, const io::ui_msg_t& m )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
object_t* cfg = nullptr;
|
||||
cw::log::createGlobal();
|
||||
|
||||
cwLogInfo("Project template: args:%i", argc);
|
||||
|
||||
switch( m.opId )
|
||||
{
|
||||
case ui::kConnectOpId:
|
||||
cwLogInfo("UI Connected: wsSessId:%i.",m.wsSessId);
|
||||
break;
|
||||
|
||||
case ui::kDisconnectOpId:
|
||||
cwLogInfo("UI Disconnected: wsSessId:%i.",m.wsSessId);
|
||||
break;
|
||||
|
||||
case ui::kInitOpId:
|
||||
cwLogInfo("UI Init.");
|
||||
break;
|
||||
|
||||
case ui::kValueOpId:
|
||||
_ui_value_callback( app, m );
|
||||
break;
|
||||
|
||||
case ui::kCorruptOpId:
|
||||
cwLogInfo("UI Corrupt.");
|
||||
break;
|
||||
|
||||
case ui::kClickOpId:
|
||||
cwLogInfo("UI Click.");
|
||||
break;
|
||||
|
||||
case ui::kSelectOpId:
|
||||
cwLogInfo("UI Select.");
|
||||
break;
|
||||
|
||||
case ui::kEchoOpId:
|
||||
_ui_echo_callback( app, m );
|
||||
break;
|
||||
|
||||
case ui::kIdleOpId:
|
||||
break;
|
||||
|
||||
case ui::kInvalidOpId:
|
||||
// fall through
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
rc_t _io_callback( void* arg, const io::msg_t* m )
|
||||
{
|
||||
app_t* app = (app_t*)arg;
|
||||
|
||||
switch( m->tid )
|
||||
{
|
||||
case io::kThreadTId:
|
||||
break;
|
||||
|
||||
case io::kTimerTId:
|
||||
break;
|
||||
|
||||
case io::kSerialTId:
|
||||
break;
|
||||
|
||||
case io::kMidiTId:
|
||||
break;
|
||||
|
||||
case io::kAudioTId:
|
||||
break;
|
||||
|
||||
case io::kAudioMeterTId:
|
||||
break;
|
||||
|
||||
case io::kSockTId:
|
||||
break;
|
||||
|
||||
case io::kWebSockTId:
|
||||
break;
|
||||
|
||||
case io::kUiTId:
|
||||
_ui_callback(app,m->u.ui);
|
||||
break;
|
||||
|
||||
case io::kExecTId:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
return kOkRC;
|
||||
}
|
||||
|
||||
rc_t _parse_cfg( app_t& app, int argc, char* argv[] )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
if( argc < 2 || textLength(argv[1])==0 )
|
||||
{
|
||||
cwLogError(kInvalidArgRC,"No cfg. file was given.");
|
||||
rc = cwLogError(kInvalidArgRC,"No cfg. file was given.");
|
||||
goto errLabel;
|
||||
}
|
||||
else
|
||||
{
|
||||
const char* val = nullptr;
|
||||
|
||||
if((rc = objectFromFile(argv[1],cfg)) != kOkRC )
|
||||
if((rc = objectFromFile(argv[1],app.cfg)) != kOkRC )
|
||||
{
|
||||
cwLogError(rc,"The file '%s'.",argv[1]);
|
||||
rc = cwLogError(rc,"The file '%s'.",argv[1]);
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
if((rc = cfg->getv("param",val)) != kOkRC )
|
||||
if((rc = app.cfg->getv("param", app.value,
|
||||
"libcw", app.io_cfg)) != kOkRC )
|
||||
{
|
||||
cwLogError(kSyntaxErrorRC,"The 'param' cfg. field was not found.");
|
||||
rc = cwLogError(kSyntaxErrorRC,"The 'param' cfg. field was not found.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
cwLogInfo("param=%s",cwStringNullGuard(val));
|
||||
}
|
||||
errLabel:
|
||||
if( rc != kOkRC )
|
||||
rc = cwLogError(rc,"App. cfg. parse failed.");
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
app_t app = {};
|
||||
cw::log::createGlobal();
|
||||
|
||||
cwLogInfo("Project template: args:%i", argc);
|
||||
|
||||
if((rc = _parse_cfg(app,argc,argv)) != kOkRC )
|
||||
goto errLabel;
|
||||
|
||||
if((rc = create( app.ioH, app.io_cfg, _io_callback, &app, appIdMapA, appIdMapN ) ) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"IO create failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
|
||||
// start the IO framework instance
|
||||
if((rc = io::start(app.ioH)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Preset-select app start failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
//io::uiReport(app.ioH);
|
||||
|
||||
|
||||
// execute the io framework
|
||||
while( !io::isShuttingDown(app.ioH))
|
||||
{
|
||||
// This call will block on the websocket handle
|
||||
// for up to io_cfg->ui.websockTimeOutMs milliseconds
|
||||
io::exec(app.ioH);
|
||||
|
||||
|
||||
}
|
||||
|
||||
// stop the io framework
|
||||
if((rc = io::stop(app.ioH)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"IO API stop failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
|
||||
errLabel:
|
||||
destroy(app.ioH);
|
||||
if( app.cfg != nullptr )
|
||||
app.cfg->free();
|
||||
cw::log::destroyGlobal();
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user