Used libcmpp and put cm startup in kcMain.cpp.

This commit is contained in:
kpl 2012-11-24 10:36:29 -08:00
parent 7a322b8b4c
commit e1593195ea
5 changed files with 220 additions and 298 deletions

3
.gitignore vendored
View File

@ -1,7 +1,6 @@
# directories to ignore # directories to ignore
libcm libcm
libgm libcmpp
libkplfltk
tlCtl tlCtl
.deps .deps

View File

@ -12,12 +12,12 @@ include_HEADERS=
AM_CPPFLAGS = -D _GNU_SOURCE -I.. -I$(srcdir)/src/libcm -I$(srcdir)/src/libcm/dsp -I$(srcdir)/src/libcm/vop -I$(srcdir)/src/libcm/app AM_CPPFLAGS = -D _GNU_SOURCE -I.. -I$(srcdir)/src/libcm -I$(srcdir)/src/libcm/dsp -I$(srcdir)/src/libcm/vop -I$(srcdir)/src/libcm/app
AM_CPPFLAGS += -I$(srcdir)/src/libkplfltk -I$(srcdir)/src/libgm -I$(srcdir)/src/tlCtl AM_CPPFLAGS += -I$(srcdir)/src/libcmpp -I$(srcdir)/src/libcmpp/fltk -I$(srcdir)/src/tlCtl
AM_CFLAGS = -Wno-multichar AM_CFLAGS = -Wno-multichar
AM_CXXFLAGS = AM_CXXFLAGS =
AM_LDFLAGS = AM_LDFLAGS =
MYLIBS = -lpthread -lfftw3f -lfftw3 -lfltk -lcairo -lX11 MYLIBS = -lpthread -lfftw3f -lfftw3 -lfltk -lX11
CMLIBS = src/libcm/libcm.la src/libgm/libgm.la src/libkplfltk/libkplfltk.la # autoconfig manual recommends storing direct referenes to non-3rd party libraries rather than using -L and -l CMLIBS = src/libcm/libcm.la src/libcmpp/libcmpp.la # autoconfig manual recommends storing direct referenes to non-3rd party libraries rather than using -L and -l
# debug/release switches # debug/release switches
@ -56,22 +56,16 @@ src_libcm_libcm_la_SOURCES = $(cmSRC) $(cmHDR)
include_HEADERS += $(cmHDR) include_HEADERS += $(cmHDR)
lib_LTLIBRARIES += src/libcm/libcm.la lib_LTLIBRARIES += src/libcm/libcm.la
include src/libkplfltk/Makefile.am include src/libcmpp/Makefile.am
src_libkplfltk_libkplfltk_la_SOURCES = $(kplfltkSRC) $(kplfltkHDR) src_libcmpp_libcmpp_la_SOURCES = $(cmppSRC) $(cmppHDR)
include_HEADERS += $(kplfltkHDR) include_HEADERS += $(cmppHDR)
lib_LTLIBRARIES += src/libkplfltk/libkplfltk.la lib_LTLIBRARIES += src/libcmpp/libcmpp.la
include src/libgm/Makefile.am
src_libgm_libgm_la_SOURCES = $(gmSRC) $(gmHDR)
include_HEADERS += $(gmHDR)
lib_LTLIBRARIES += src/libgm/libgm.la
include src/tlCtl/Makefile.am include src/tlCtl/Makefile.am
src_kc_kc_SOURCES = $(tlCtlSRC) src_kc_kc_SOURCES = $(tlCtlSRC)
src_kc_kc_SOURCES += src/kc/kcMain.cpp src_kc_kc_SOURCES += src/kc/kcMain.cpp
src_kc_kc_SOURCES += src/kc/kcApp.h src/kc/kcApp.cpp src_kc_kc_SOURCES += src/kc/kcApp.h src/kc/kcApp.cpp
# src_kc_kc_SOURCES += src/kc/Fl_Splitter.h src/kc/Fl_Splitter.cpp
src_kc_kc_SOURCES += src/kc/Fl_File_Btn.h src/kc/Fl_Vert_Progress.h src_kc_kc_SOURCES += src/kc/Fl_File_Btn.h src/kc/Fl_Vert_Progress.h
src_kc_kc_SOURCES += src/kc/Fl_File_Btn.cpp src/kc/Fl_Vert_Progress.cpp src_kc_kc_SOURCES += src/kc/Fl_File_Btn.cpp src/kc/Fl_Vert_Progress.cpp

View File

@ -40,44 +40,35 @@
#include "cmMsgProtocol.h" #include "cmMsgProtocol.h"
#include "cmAudDspIF.h" #include "cmAudDspIF.h"
#include "cmAudDspLocal.h" #include "cmAudDspLocal.h"
#include "kcApp.h"
#include "cmAudioFile.h" #include "cmAudioFile.h"
#include "cmAudioFileMgr.h" #include "cmAudioFileMgr.h"
#include "cmMidi.h" #include "cmMidi.h"
#include "cmMidiFile.h" #include "cmMidiFile.h"
#include "cmTimeLine.h" #include "cmTimeLine.h"
#include "cmScore.h" #include "cmScore.h"
#include "cmdIf.h"
#include "tlCtl.h"
#include "kcApp.h"
#include "cmGr.h" #include "cmGr.h"
#include "cmGrDevCtx.h" #include "cmGrDevCtx.h"
#include "cmGrPlot.h" #include "cmGrPlot.h"
#include "cmGrPage.h" #include "cmGrPage.h"
#include "cmGrDevDrvFltk.h" #include "cmGrFltk.h"
#include "cmGrDevDrvCairoFltk.h"
#include "cmGrWidgetFltk.h"
#include "Fl_CbLinker.h"
#include "cmGrPlotPageFltk.h"
#include "cmGrPlotCtlrFltk.h"
#include "gvHashFunc.h"
#include "cmGrTlCtlrFltk.h"
#include "cmGrScCtlrFltk.h"
#include "cmdIf.h"
#include "tlCtl.h"
#define TIMER_PERIOD (1.0/20.0) // 50ms #define TIMER_PERIOD (1.0/20.0) // 50ms
kcApp::kcApp(int w, int h, const char *l, int argc, char *argv[]) kcApp::kcApp(cmCtx_t* ctx, cmTsMp1cH_t printqH, int w, int h, const cmChar_t* title, cmAiH_t aiH, int argc, char* argv[] )
: Fl_Double_Window(w, h, l), : Fl_Double_Window(w, h,title),
splt(NULL),_menu(NULL), splt(NULL),_menu(NULL),_aiH(aiH),
_adlH(cmAdlNullHandle),_aiH(cmAiNullHandle), _statIdx(0),_pageList(NULL),_ctlList(NULL),
_statIdx(0),_pageList(NULL),_ctlList(NULL),_prH(cmPrNullHandle),_prefsFn(NULL), _stopTimerFl(false),_newPageFl(true),
_stopTimerFl(false),_jsH(cmJsonNullHandle),_newPageFl(true),_incrColW(0),_colW(0),_horzBordFl(false),_horzBord(0), _incrColW(0),_colW(0),_horzBordFl(false),_horzBord(0),
_closeCnt(0),_ssCnt(0),_ssArray(0),_ssPhase(0),_ssUpdateFl(false),_printqH(cmTsQueueNullHandle), _closeCnt(0),_ssCnt(0),_ssArray(0),_ssPhase(0),_ssUpdateFl(false),
_printqH(printqH),_printFl(0),
_tlCtl(NULL) _tlCtl(NULL)
{ {
// install a callback to cleanup when the app window closes // install a callback to cleanup when the app window closes
@ -91,8 +82,7 @@ kcApp::kcApp(int w, int h, const char *l, int argc, char *argv[])
splt = new Fl_HSplitter(0, kMenuH, w, h-kStatusH-kMenuH, h-kStatusH-kMenuH-100); splt = new Fl_HSplitter(0, kMenuH, w, h-kStatusH-kMenuH, h-kStatusH-kMenuH-100);
end(); end();
// Create a text display object for console output and // Create a text display object for console output andvadd it to the lower splitter area
// add it to the lower splitter area
buf = new Fl_Text_Buffer(); buf = new Fl_Text_Buffer();
con = new Fl_Text_Display(splt->container2->x(),splt->container2->y(),splt->container2->w(),splt->container2->h()); con = new Fl_Text_Display(splt->container2->x(),splt->container2->y(),splt->container2->w(),splt->container2->h());
con->buffer(buf); con->buffer(buf);
@ -101,39 +91,26 @@ kcApp::kcApp(int w, int h, const char *l, int argc, char *argv[])
// Create a tab view and added it to the upper splitter area // Create a tab view and added it to the upper splitter area
tabs = new Fl_Tabs(splt->container1->x(),splt->container1->y(),splt->container1->w(),splt->container1->h()); tabs = new Fl_Tabs(splt->container1->x(),splt->container1->y(),splt->container1->w(),splt->container1->h());
tabs->callback(_s_tab_cb,this); tabs->callback(_s_tab_cb,this);
tabs->end();
splt->container1->add(tabs); splt->container1->add(tabs);
int tx,ty,th,tw; int tx,ty,th,tw;
tabs->client_area(tx,ty,tw,th); tabs->client_area(tx,ty,tw,th);
// Create the 'Setup' tab group // Create the 'Setup' tab group
tabs->begin();
Fl_Group* setup_grp = new Fl_Group(tx,ty,tw,th,"Setup"); Fl_Group* setup_grp = new Fl_Group(tx,ty,tw,th,"Setup");
tabs->add(setup_grp);
_createSetupDlg(setup_grp); _createSetupDlg(setup_grp);
tabs->end();
// Create the master group
tabs->add(mstr_grp = new Fl_Group(tx,ty,tw,th,"Master"));
tabs->begin();
mstr_grp = new Fl_Group(tx,ty,tw,th,"Master");
tabs->end();
// Create the 'Controls' tab group
/*
tabs->begin();
ctl_grp = new Fl_Group(tx,ty,tw,th,"Controls");
ctl_grp->begin();
Fl_Box* bx = new Fl_Box(FL_NO_BOX,ctl_grp->x()+ctl_grp->w(),ctl_grp->y()+ctl_grp->h(),1,1,NULL);
ctl_grp->resizable(bx);
ctl_grp->end(); tabs->end();
*/
// Create an empty tab group and make it resizable // Create an empty tab group and make it resizable
// to prevent the other tab groups from being resizable. // to prevent the other tab groups from being resizable.
tabs->begin();
Fl_Group* wdgt = new Fl_Group(tx,ty+30,1,1); Fl_Group* wdgt = new Fl_Group(tx,ty+30,1,1);
tabs->add(wdgt);
tabs->resizable(wdgt); // make other tabs non-resizable tabs->resizable(wdgt); // make other tabs non-resizable
tabs->end();
// make the splitter the resizable group element (thereby making the menu non-resizable). // make the splitter the resizable group element (thereby making the menu non-resizable).
@ -142,13 +119,13 @@ kcApp::kcApp(int w, int h, const char *l, int argc, char *argv[])
show(argc, argv); show(argc, argv);
// initialize the audio DSP system // direct all output to the console window
audioDspInitialize(&_ctx,_s_print,this); cmRptSetup(&_ctx.rpt,_s_print,_s_print, this);
cmTsMp1cSetCbFunc(_printqH, _s_print_queue_cb, this );
// install a timer to check for messages from the engine // install a timer to check for messages from the engine
Fl::add_timeout(TIMER_PERIOD,_s_status_timeout_cb,this); Fl::add_timeout(TIMER_PERIOD,_s_status_timeout_cb,this);
} }
kcApp::~kcApp() kcApp::~kcApp()
@ -158,119 +135,18 @@ kcApp::~kcApp()
} }
// this function is only called from the constructor
kcApp::kcKmRC_t kcApp::audioDspInitialize(cmCtx_t* ctx, cmRptPrintFunc_t printFunc, void* printFuncArg)
{
kcKmRC_t rc = kOkKmRC;
// initialize the heap check library
bool memDebugFl = cmDEBUG_FL;
unsigned memPadByteCnt = memDebugFl ? 8 : 0;
unsigned memAlignByteCnt = 16;
unsigned memFlags = memDebugFl ? (kTrackMmFl | kDeferFreeMmFl | kFillUninitMmFl) : 0;
cmCtxSetup(ctx,"KC Main",printFunc,printFunc,printFuncArg,memPadByteCnt,memAlignByteCnt,memFlags);
cmMdInitialize( memPadByteCnt, memAlignByteCnt, memFlags, &ctx->rpt );
cmTsInitialize(ctx);
cmFsInitialize( ctx, "kc" );
cmJsonInitialize(&_jsH,&_ctx);
//_loadPrefs(ctx);
// create the print queue
if( cmTsQueueCreate( &_printqH, 4*8192, kcApp::_s_print_queue_cb, this, &_ctx.rpt ) != kOkThRC )
cmErrMsg(&ctx->err,kPrintQueFailKmRC,"Print queue creation failed.");
cmAdIfDispatch_t r;
r.cbDataPtr = this;
r.ssInitFunc = _s_handleSsInitMsg;
r.statusFunc = _s_handleStatusMsg;
r.uiFunc = _s_handleUiMsg;
if( cmAudDspLocalAllocate(ctx,&_adlH,&r) != kOkAdlRC )
{
rc = cmErrMsg(&ctx->err,kEngFailKmRC,"The audio DSP local server allocation failed.");
goto errLabel;
}
if(cmAdIfIsValid(_aiH = cmAudDspLocalIF_Handle(_adlH)) == false )
{
rc = cmErrMsg(&ctx->err,kEngFailKmRC,"The audio DSP interface handle is not valid.");
goto errLabel;
}
errLabel:
return rc;
}
bool kcApp::audioDspIsValid()
{ return cmAudDspLocalIsValid(_adlH) && cmAdIfIsValid(_aiH); }
kcApp::kcKmRC_t kcApp::audioDspFinalize()
{
kcKmRC_t rc = kOkKmRC;
_stopTimerFl = true;
if( cmJsonFinalize(&_jsH) != kOkJsRC )
rc = cmErrMsg(&_ctx.err,kJsonFailKmRC,"JSON object finalization failed.");
// If the preferences are dirty or the prefs file does not exist then write them
if( cmPrefsIsValid(_prH) )
{
if( _prefsFn != NULL && (cmPrefsIsValid(_prH) && (cmPrefsIsDirty(_prH) || cmFsIsFile(_prefsFn)==false)) )
if( cmPrefsWrite(_prH,_prefsFn) != kOkPrRC )
rc = cmErrMsg(&_ctx.err,kPrefWriteFailKmRC,"Preference save failed on file '%s'.",_prefsFn);
if( cmPrefsFinalize(&_prH) != kOkPrRC )
rc = cmErrMsg(&_ctx.err,kPrefFailKmRC,"Prefrence finalization failed.");
}
// finalize the real-time system
//rc = stopEngine(_ctx,*hp);
// release the engine
if( cmAudDspLocalFree(&_adlH) != kOkAdlRC )
rc = cmErrMsg(&_ctx.err,kEngFailKmRC,"Audio DSP release failed.");
// print any pending text in the print queue
_checkPrintQueue();
// the app threads are stopped so it is safe to stop using the print queue
if( cmTsQueueDestroy(&_printqH) == kOkThRC )
_printqH = cmTsQueueNullHandle;
else
cmErrMsg(&_ctx.err,kPrintQueFailKmRC,"Print queue destroy failed.");
// finalize the file system
cmFsFinalize();
cmTsFinalize();
// report memory mgr errors
if( cmMdReport( kIgnoreNormalMmFl ) != kOkMmRC )
rc = kMemFailKmRC;
// finalize the memory manager
if( cmMdFinalize() != kOkMmRC )
rc = kMemFailKmRC;
return rc;
}
void kcApp::resize(int x, int y, int w, int h) void kcApp::resize(int x, int y, int w, int h)
{ {
Fl_Double_Window::resize(x, y, w, h); Fl_Double_Window::resize(x, y, w, h);
splt->resize(0, kMenuH, w, h-kStatusH); splt->resize(0, kMenuH, w, h-kStatusH);
} }
void kcApp::tlCtlNewTimeLineFile( tlCtl* tlCtl, const cmChar_t* fn )
{}
void kcApp::tlCtlNewScoreFile( tlCtl* tlCtl, const cmChar_t* fn )
{}
void kcApp::_createSetupDlg( Fl_Group* grp ) void kcApp::_createSetupDlg( Fl_Group* grp )
{ {
@ -334,12 +210,7 @@ void kcApp::_createMenu(int w, int h)
Fl_Menu_Item items[] = Fl_Menu_Item items[] =
{ {
{ "&File", 0, 0, 0, FL_SUBMENU }, { "&File", 0, 0, 0, FL_SUBMENU },
{ "&New File", 0, (Fl_Callback*)_s_file_new_cb }, { "&New File", 0, (Fl_Callback*)_s_menu_cb },
{ "&Open File", FL_COMMAND + 'o', (Fl_Callback*)_s_file_open_cb },
{ 0 },
{ "&Edit", 0, 0, 0, FL_SUBMENU },
{ "&Copy", FL_COMMAND + 'c', (Fl_Callback*)_s_edit_copy_cb },
{ "&Paste", FL_COMMAND + 'v', (Fl_Callback*)_s_edit_paste_cb },
{ 0 }, { 0 },
{ 0 } { 0 }
}; };
@ -1222,7 +1093,7 @@ void kcApp::_createTmln( const cmDspUiHdr_t* m )
w = pg->grp->w(); w = pg->grp->w();
h = pg->grp->h(); h = pg->grp->h();
cp->u.tmln.tlctl = new tlCtl(&_ctx,this,NULL); cp->u.tmln.tlctl = new tlCtl(&_ctx,this,_menu,this);
// currently we only support one time-line control because // currently we only support one time-line control because
// we have not yet implmenented a method of providing // we have not yet implmenented a method of providing
@ -1230,7 +1101,7 @@ void kcApp::_createTmln( const cmDspUiHdr_t* m )
assert( _tlCtl == NULL ); assert( _tlCtl == NULL );
_tlCtl = cp->u.tmln.tlctl; _tlCtl = cp->u.tmln.tlctl;
Fl_Widget* wdgt = cp->u.tmln.tlctl->initTimeLineCtlr(_menu,x,y,w,h); Fl_Widget* wdgt = cp->u.tmln.tlctl->initTimeLineCtlr(x,y,w,h);
_insertNewCtl(cp,m,wdgt,cp->u.tmln.varIdArray,kTmlnVarCnt); _insertNewCtl(cp,m,wdgt,cp->u.tmln.varIdArray,kTmlnVarCnt);
@ -1570,7 +1441,7 @@ void kcApp::_handleSsInitMsg( const cmAudioSysSsInitMsg_t* m, const cmChar_t* in
ss_t* ss = _ssArray + m->asSubIdx; ss_t* ss = _ssArray + m->asSubIdx;
int x = 20; int x = 20;
int y = 30; int y = 30 + kMenuH;
int w = 80; int w = 80;
int h = 20; int h = 20;
char lblArray[][10] = { "Update","Wakeup","Mesg","Audio" }; char lblArray[][10] = { "Update","Wakeup","Mesg","Audio" };
@ -1792,28 +1663,6 @@ void kcApp::_handleUiMsg( const cmDspUiHdr_t* m )
} }
} }
cmRC_t kcApp::_s_handleSsInitMsg( void* cbDataPtr, const cmAudioSysSsInitMsg_t* r, const char* iDevLabel, const char* oDevLabel )
{
kcApp* p = (kcApp*)cbDataPtr;
p->_handleSsInitMsg(r,iDevLabel,oDevLabel);
return cmOkRC;
}
cmRC_t kcApp::_s_handleStatusMsg( void* cbDataPtr, const cmAudioSysStatus_t* r, const double* iMeterArray, const double* oMeterArray )
{
kcApp* p = (kcApp*)cbDataPtr;
p->_handleStatusMsg(r,iMeterArray,oMeterArray);
return cmOkRC;
}
cmRC_t kcApp::_s_handleUiMsg( void* cbDataPtr, const cmDspUiHdr_t* r )
{
kcApp* p = (kcApp*)cbDataPtr;
p->_handleUiMsg(r);
return cmOkRC;
}
// Check for and forward any messages sent to the UI // Check for and forward any messages sent to the UI
// that are waiting in the audio DSP msg queue. // that are waiting in the audio DSP msg queue.
@ -1821,7 +1670,7 @@ void kcApp::_getEngMsg()
{ {
if( audioDspIsValid() ) if( cmAdIfIsValid(_aiH) )
{ {
unsigned i; unsigned i;
@ -1892,16 +1741,18 @@ void kcApp::_callback(void* data)
{ {
if( Fl::event() == FL_CLOSE ) if( Fl::event() == FL_CLOSE )
{ {
unsigned cc = _closeCnt; //unsigned cc = _closeCnt;
ctl_t* cp = _ctlList; ctl_t* cp = _ctlList;
for(; cp!=NULL; cp=cp->linkPtr) for(; cp!=NULL; cp=cp->linkPtr)
if( cp->typeId == kTmlnTypeId ) if( cp->typeId == kTmlnTypeId )
delete cp->u.tmln.tlctl; delete cp->u.tmln.tlctl;
_stopTimerFl = true;
// attempt to shut down the pgm // attempt to shut down the pgm
if( audioDspFinalize() != kOkKmRC ) //if( audioDspFinalize() != kOkKmRC )
++_closeCnt; // ++_closeCnt;
// the first time the pgm fails to shut down // the first time the pgm fails to shut down
// do not allow the pgm to close the main window // do not allow the pgm to close the main window
@ -1931,14 +1782,6 @@ void kcApp::_callback(void* data)
} }
void kcApp::_s_on_idle(void *data)
{ ((kcApp*)data)->_on_idle(); }
void kcApp::_on_idle()
{
//_getEngMsg();
//_getEngStatus();
}
void kcApp::_s_status_timeout_cb(void* userPtr) void kcApp::_s_status_timeout_cb(void* userPtr)
{ {
@ -1948,7 +1791,7 @@ void kcApp::_s_status_timeout_cb(void* userPtr)
bool kcApp::_status_timeout_cb() bool kcApp::_status_timeout_cb()
{ {
if( cmTsQueueIsValid(_printqH) ) if( cmTsMp1cIsValid(_printqH) )
_checkPrintQueue(); _checkPrintQueue();
if( !_stopTimerFl ) if( !_stopTimerFl )
@ -1974,37 +1817,13 @@ bool kcApp::_status_timeout_cb()
//if( !_stopTimerFl ) //if( !_stopTimerFl )
// _getEngStatus(); // _getEngStatus();
return _stopTimerFl==false || cmTsQueueIsValid(_printqH); return _stopTimerFl==false || cmTsMp1cIsValid(_printqH);
} }
void kcApp::_s_file_new_cb(Fl_Widget *w, void *data) void kcApp::_s_menu_cb(Fl_Widget *w, void *data)
{ ((kcApp*)data)->_file_new_cb(w); }
void kcApp::_file_new_cb(Fl_Widget *w)
{ }
void kcApp::_s_file_open_cb(Fl_Widget *w, void *data)
{ ((kcApp*)data)->_file_open_cb(w); }
void kcApp::_file_open_cb(Fl_Widget *w)
{ }
void kcApp::_s_edit_copy_cb(Fl_Widget *w, void *data)
{ ((kcApp*)data)->_edit_copy_cb(w); }
void kcApp::_edit_copy_cb(Fl_Widget *w)
{ }
void kcApp::_s_edit_paste_cb(Fl_Widget *w, void *data)
{ ((kcApp*)data)->_edit_paste_cb(w); }
void kcApp::_edit_paste_cb(Fl_Widget *w)
{ } { }
@ -2016,7 +1835,7 @@ void kcApp::_tab_cb(Fl_Widget*)
Fl_Widget* w = tabs->value(); Fl_Widget* w = tabs->value();
_ssUpdateFl = w == (Fl_Widget*)mstr_grp; _ssUpdateFl = w == (Fl_Widget*)mstr_grp;
_ssPhase = kSsPhaseMax; _ssPhase = kSsPhaseMax;
if( audioDspIsValid() ) if( cmAdIfIsValid(_aiH) )
{ {
if( cmAdIfEnableStatusNotify(_aiH, _ssUpdateFl ) != kOkAiRC ) if( cmAdIfEnableStatusNotify(_aiH, _ssUpdateFl ) != kOkAiRC )
cmErrMsg(&_ctx.err,kEngFailKmRC,"A request to enable/disable status notification failed."); cmErrMsg(&_ctx.err,kEngFailKmRC,"A request to enable/disable status notification failed.");
@ -2174,15 +1993,15 @@ void kcApp::vprint(const char* fmt, va_list vl )
if( n > 0 ) if( n > 0 )
{ {
// if the print queue exists (it might not during startup or shutdown) ... // if the print queue exists (it might not during startup or shutdown) ...
if( cmTsQueueIsValid(_printqH) ) if( cmTsMp1cIsValid(_printqH) )
{ {
// ... enqueue the text to print // ... enqueue the text to print
if( cmTsQueueEnqueueMsg(_printqH,buf,n+1) != kOkThRC ) if( cmTsMp1cEnqueueMsg(_printqH,buf,n+1) != kOkThRC && _printFl==0 )
{ {
printf("Print enqueue failed on msg:%s\n",buf); // use _printFl to guard against recursion which would eventually overflow the stack.
// we can't call an error here because it would generate an error ++_printFl;
// msg which would possibly fail at this same point resulting in cmErrMsg(&_ctx.err,kQueueFailKmRC,"Print enqueue failed on msg:%s.",buf);
// a recursion which would eventually overflow the stack. --_printFl;
} }
} }
@ -2212,9 +2031,13 @@ cmRC_t kcApp::_s_print_queue_cb(void* userCbPtr, unsigned msgByteCnt, const void
void kcApp::_checkPrintQueue() void kcApp::_checkPrintQueue()
{ {
while( cmTsQueueMsgWaiting(_printqH) ) while( cmTsMp1cMsgWaiting(_printqH) )
if( cmTsQueueDequeueMsg(_printqH, NULL, 0) != kOkThRC ) if( cmTsMp1cDequeueMsg(_printqH, NULL, 0) != kOkThRC && _printFl==0 )
{
++_printFl;
cmErrMsg(&_ctx.err,kPrintQueFailKmRC,"Print dequeue failed."); cmErrMsg(&_ctx.err,kPrintQueFailKmRC,"Print dequeue failed.");
--_printFl;
}
} }
void kcApp::_print( const char* text ) void kcApp::_print( const char* text )

View File

@ -17,19 +17,16 @@ class Fl_Select_Browser;
class Fl_Valuator; class Fl_Valuator;
class Fl_Value_Input; class Fl_Value_Input;
class Fl_Progress; class Fl_Progress;
class tlCtl;
class kcApp : public Fl_Double_Window
{
public:
typedef unsigned kcKmRC_t;
enum enum
{ {
kOkKmRC, kOkKmRC,
kEngFailKmRC, kEngFailKmRC,
kMemFailKmRC, kMemFailKmRC,
kFileSysFailKmRC,
kQueueFailKmRC,
kTextSysFailKmRC,
kPrefsNotFoundKmRC, kPrefsNotFoundKmRC,
kPrefWriteFailKmRC, kPrefWriteFailKmRC,
kPrefLoadFailKmRC, kPrefLoadFailKmRC,
@ -42,13 +39,22 @@ public:
}; };
class kcApp : public Fl_Double_Window, public tlCtlRspdr
{
public:
typedef unsigned kcKmRC_t;
kcApp(int w, int h, const char *l, int argc, char *argv[]);
kcApp(cmCtx_t* ctx, cmTsMp1cH_t printQH, int w, int h, const cmChar_t* title, cmAiH_t aiH, int argc, char* argv[] );
virtual ~kcApp(); virtual ~kcApp();
kcKmRC_t audioDspInitialize( cmCtx_t* ctx, cmRptPrintFunc_t printFunc, void* printFuncArg ); void resize(int x, int y, int w, int h);
kcKmRC_t audioDspFinalize();
bool audioDspIsValid(); virtual void tlCtlNewTimeLineFile( tlCtl* tlCtl, const cmChar_t* fn );
virtual void tlCtlNewScoreFile( tlCtl* tlCtl, const cmChar_t* fn );
void print( const char* fmt, ... ); void print( const char* fmt, ... );
void vprint( const char* fmt, va_list vl ); void vprint( const char* fmt, va_list vl );
@ -281,16 +287,11 @@ private:
cmCtx_t _ctx; cmCtx_t _ctx;
Fl_Menu_Bar* _menu; Fl_Menu_Bar* _menu;
cmAdlH_t _adlH;
cmAiH_t _aiH; cmAiH_t _aiH;
unsigned _statIdx; unsigned _statIdx;
page_t* _pageList; page_t* _pageList;
ctl_t* _ctlList; ctl_t* _ctlList;
const cmChar_t* _prefFn;
cmPrH_t _prH;
const cmChar_t* _prefsFn;
bool _stopTimerFl; bool _stopTimerFl;
cmJsonH_t _jsH;
bool _newPageFl; bool _newPageFl;
unsigned _incrColW; unsigned _incrColW;
unsigned _colW; unsigned _colW;
@ -301,11 +302,10 @@ private:
ss_t* _ssArray; ss_t* _ssArray;
int _ssPhase; int _ssPhase;
bool _ssUpdateFl; bool _ssUpdateFl;
cmTsQueueH_t _printqH; // thread-safe queue for controlling access to the output console from multiple threads cmTsMp1cH_t _printqH; // thread-safe queue for controlling access to the output console from multiple threads
int _printFl;
tlCtl* _tlCtl; tlCtl* _tlCtl;
void resize(int x, int y, int w, int h);
void _createSetupDlg(Fl_Group* grp); void _createSetupDlg(Fl_Group* grp);
void _createMenu( int w, int h ); void _createMenu( int w, int h );
page_t* _createPage( const char* title ); page_t* _createPage( const char* title );
@ -351,51 +351,35 @@ private:
void _updateMeters( unsigned asSubIdx, unsigned devIdx, unsigned inFl, const double* meterArray, unsigned meterCnt ); void _updateMeters( unsigned asSubIdx, unsigned devIdx, unsigned inFl, const double* meterArray, unsigned meterCnt );
void _updateSsStatusIndicator( unsigned asSubIdx, unsigned indicatorIdx, unsigned cnt ); void _updateSsStatusIndicator( unsigned asSubIdx, unsigned indicatorIdx, unsigned cnt );
void _printStatusCounts(); void _printStatusCounts();
void _handleStatusMsg( const cmAudioSysStatus_t* st, const double* iMeterArray, const double* oMeterArray );
void _clearStatusIndicators(); void _clearStatusIndicators();
void _sendMasterUiMsg( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned instVarId, const cmDspValue_t* v ); void _sendMasterUiMsg( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned instVarId, const cmDspValue_t* v );
void _sendMasterUiValue(unsigned asSubIdx, unsigned instId, const double* v, unsigned vn, const cmChar_t* text ); void _sendMasterUiValue(unsigned asSubIdx, unsigned instId, const double* v, unsigned vn, const cmChar_t* text );
void _createMasterCtl( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned varCnt, const double* dv, unsigned dn, const cmChar_t* label); void _createMasterCtl( unsigned asSubIdx, unsigned selId, unsigned instId, unsigned varCnt, const double* dv, unsigned dn, const cmChar_t* label);
void _handleSsInitMsg( const cmAudioSysSsInitMsg_t* m, const cmChar_t* inDevLabel, const cmChar_t* outDevLabel );
void _onRecvValue( const cmDspUiHdr_t* m ); void _onRecvValue( const cmDspUiHdr_t* m );
void _handleUiMsg( const cmDspUiHdr_t* m );
void _getEngMsg(); void _getEngMsg();
static cmRC_t _s_handleSsInitMsg( void* cbDataPtr, const cmAudioSysSsInitMsg_t* r, const char* iDevLabel, const char* oDevLabel ); public:
static cmRC_t _s_handleStatusMsg( void* cbDataPtr, const cmAudioSysStatus_t* r, const double* iMeterArray, const double* oMeterArray ); void _handleStatusMsg( const cmAudioSysStatus_t* st, const double* iMeterArray, const double* oMeterArray );
static cmRC_t _s_handleUiMsg( void* cbDataPtr, const cmDspUiHdr_t* r ); void _handleSsInitMsg( const cmAudioSysSsInitMsg_t* m, const cmChar_t* inDevLabel, const cmChar_t* outDevLabel );
void _handleUiMsg( const cmDspUiHdr_t* m );
private:
static kcApp* _getApp( Fl_Widget* w ); static kcApp* _getApp( Fl_Widget* w );
kcKmRC_t _restartEngine();
void _testStub(); void _testStub();
// main app callback // main app callback
static void _s_callback(Fl_Widget* wp, void* data); static void _s_callback(Fl_Widget* wp, void* data);
void _callback(void* data); void _callback(void* data);
// idle callback
static void _s_on_idle(void* data);
void _on_idle();
// timer callback // timer callback
static void _s_status_timeout_cb(void* userPtr); static void _s_status_timeout_cb(void* userPtr);
bool _status_timeout_cb(); bool _status_timeout_cb();
static void _s_file_new_cb(Fl_Widget *w, void *data); static void _s_menu_cb(Fl_Widget *w, void *data);
void _file_new_cb(Fl_Widget *w);
static void _s_file_open_cb(Fl_Widget *w, void *data);
void _file_open_cb(Fl_Widget *w);
static void _s_edit_copy_cb(Fl_Widget *w, void *data);
void _edit_copy_cb(Fl_Widget *w);
static void _s_edit_paste_cb(Fl_Widget *w, void *data);
void _edit_paste_cb(Fl_Widget *w);
static void _s_btn_cb(Fl_Widget* w, long data); static void _s_btn_cb(Fl_Widget* w, long data);
void _btn_cb(Fl_Widget* w, long arg); void _btn_cb(Fl_Widget* w, long arg);

View File

@ -15,25 +15,147 @@
#include "cmRpt.h" #include "cmRpt.h"
#include "cmErr.h" #include "cmErr.h"
#include "cmCtx.h" #include "cmCtx.h"
#include "cmPrefs.h" #include "cmMem.h"
#include "cmMallocDebug.h"
#include "cmLinkedHeap.h"
#include "cmJson.h" #include "cmJson.h"
#include "cmThread.h" #include "cmThread.h"
#include "cmText.h"
#include "cmFileSys.h"
#include "cmDspValue.h" #include "cmDspValue.h"
#include "cmMsgProtocol.h" #include "cmMsgProtocol.h"
#include "cmAudDspIF.h" #include "cmAudDspIF.h"
#include "cmAudDspLocal.h" #include "cmAudDspLocal.h"
#include "cmAudioFile.h"
#include "cmAudioFileMgr.h"
#include "cmMidi.h"
#include "cmMidiFile.h"
#include "cmTimeLine.h"
#include "cmScore.h"
#include "cmdIf.h"
#include "tlCtl.h"
#include "kcApp.h" #include "kcApp.h"
kcApp* kcAppPtr = NULL;
void print(void* cmRptUserPtr, const char* text)
{ printf("%s",text); }
int main(int argc, char* argv[] ) void print( void*, const cmChar_t* text)
{ puts(text); }
cmRC_t print_queue_cb(void* userCbPtr, unsigned msgByteCnt, const void* msgDataPtr )
{ {
kcApp myApp(1600, 750, "Console", argc, argv); print(NULL,(const char*)msgDataPtr);
Fl::run(); return cmOkRC;
}
//test(); cmRC_t handleSsInitMsg( void* cbDataPtr, const cmAudioSysSsInitMsg_t* r, const char* iDevLabel, const char* oDevLabel )
{ kcAppPtr->_handleSsInitMsg(r,iDevLabel,oDevLabel); return cmOkRC; }
cmRC_t handleStatusMsg( void* cbDataPtr, const cmAudioSysStatus_t* r, const double* iMeterArray, const double* oMeterArray )
{ kcAppPtr->_handleStatusMsg(r,iMeterArray,oMeterArray); return cmOkRC;}
cmRC_t handleUiMsg( void* cbDataPtr, const cmDspUiHdr_t* r )
{ kcAppPtr->_handleUiMsg(r); return cmOkRC;}
int main( int argc, char* argv[] )
{
cmCtx_t ctx;
cmTsMp1cH_t printqH = cmTsMp1cNullHandle;
int appWndW = 1600;
int appWndH = 750;
const char* appPrefDir = "kc";
const char* appTitle = "KC Console";
bool memDebugFl = cmDEBUG_FL;
unsigned memPadByteCnt = memDebugFl ? 8 : 0;
unsigned memAlignByteCnt = 16;
unsigned memFlags = memDebugFl ? (kTrackMmFl | kDeferFreeMmFl | kFillUninitMmFl) : 0;
cmAdlH_t adlH = cmAdlNullHandle;
cmAiH_t aiH = cmAiNullHandle;
cmAdIfDispatch_t r;
cmCtxSetup(&ctx,appTitle,print,print,NULL,memPadByteCnt,memAlignByteCnt,memFlags);
// initialize the memory mgr
if(cmMdInitialize( memPadByteCnt, memAlignByteCnt, memFlags, &ctx.rpt ) != kOkMmRC )
{
cmErrMsg(&ctx.err,kMemFailKmRC,"Heap initialization failed.");
goto errLabel;
}
// initialize the file system
if( cmFsInitialize( &ctx, appPrefDir ) != kOkFsRC )
cmErrMsg(&ctx.err,kFileSysFailKmRC,"File system initialization failed.");
// initialize the text system
if( cmTsInitialize(&ctx) != kOkTxRC )
cmErrMsg(&ctx.err,kTextSysFailKmRC,"Text system initialization failed.");
// create the print queue
if( cmTsMp1cCreate( &printqH, 8192, print_queue_cb, NULL, NULL ) != kOkThRC )
cmErrMsg(&ctx.err,kQueueFailKmRC,"Print queue creation failed.");
r.cbDataPtr = NULL;
r.ssInitFunc = handleSsInitMsg;
r.statusFunc = handleStatusMsg;
r.uiFunc = handleUiMsg;
// initialize the audio engine
if( cmAudDspLocalAllocate(&ctx,&adlH,&r) != kOkAdlRC )
cmErrMsg(&ctx.err,kEngFailKmRC,"The audio DSP local server allocation failed.");
else
if(cmAdIfIsValid(aiH = cmAudDspLocalIF_Handle(adlH)) == false )
cmErrMsg(&ctx.err,kEngFailKmRC,"The audio DSP interface handle is not valid.");
if( cmErrLastRC(&ctx.err) == kOkKmRC )
{
kcAppPtr = new kcApp(&ctx, printqH, appWndW, appWndH, appTitle, aiH, argc, argv);
cmAudDspLocalSendSetup(adlH);
Fl::run();
delete kcAppPtr;
kcAppPtr=NULL;
// reset the pgm context and print queue console output to stdout
cmRptSetup(&ctx.rpt,print,print,NULL);
cmTsMp1cSetCbFunc(printqH, print_queue_cb, NULL );
}
// empty any pending text to stdout
while( cmTsMp1cMsgWaiting(printqH) )
if( cmTsMp1cDequeueMsg(printqH, NULL, 0) != kOkThRC )
cmErrMsg(&ctx.err,kQueueFailKmRC,"Print dequeue failed.");
// release the engine
if( cmAudDspLocalFree(&adlH) != kOkAdlRC )
cmErrMsg(&ctx.err,kEngFailKmRC,"Audio DSP release failed.");
// destroy the print queue
if( cmTsMp1cDestroy(&printqH) != kOkThRC )
cmErrMsg(&ctx.err,kQueueFailKmRC,"Print queue destroy failed.");
// finalize the text system
if( cmTsFinalize() != kOkTxRC )
cmErrMsg(&ctx.err,kTextSysFailKmRC,"Text system finalization failed.");
// finalize the file system
if( cmFsFinalize() != kOkFsRC )
cmErrMsg(&ctx.err,kFileSysFailKmRC,"File system finalize failed.");
// report memory mgr errors
if( cmMdIsValid() )
cmMdReport( kIgnoreNormalMmFl );
// finalize the memory manager
if( cmMdFinalize() != kOkMmRC )
cmErrMsg(&ctx.err,kMemFailKmRC,"Heap finalization failed.");
errLabel:
return 0; return 0;
} }