#include #include #include #include #include #include #include #include "Fl_CbLinker.h" #include "cmGlobal.h" #include "cmFloatTypes.h" #include "cmRpt.h" #include "cmErr.h" #include "cmCtx.h" #include "cmMem.h" #include "cmMallocDebug.h" #include "cmLinkedHeap.h" #include "cmText.h" #include "cmThread.h" #include "cmPrefs.h" #include "cmSymTbl.h" #include "cmTime.h" #include "cmMidi.h" #include "cmMidiFile.h" #include "cmAudioFile.h" #include "cmAudioFileMgr.h" #include "cmTimeLine.h" #include "cmScore.h" #include "cmGr.h" #include "cmGrDevCtx.h" #include "cmGrPlot.h" #include "cmGrPage.h" #include "cmGrFltk.h" #include "gvHashFunc.h" #include "cmGrScFltk.h" #include "cmGrPlotAudio.h" #include "cmdIf.h" cmGrScFltk::cmGrScFltk(cmCtx_t* ctx, cmdIf* cp, Fl_Menu_Bar* menu, int x, int y, int w, int h) : cmGrPlotFltk(ctx,x,y,w,h), _srate(0),_cmdIf(cp),_menuBar(menu), _samplesMetricId(cmInvalidId),_secondsMetricId(cmInvalidId), _objSecs(0),_objId(0), _togFl(true), _lastBarPlotObjH(cmGrPlObjNullHandle) { cmErrSetup(&_err,&ctx->rpt,"cmGrScFltk"); _createMenu(); if( cmGrPageIsValid(pageHandle()) == false ) return; initViews(1,1); unsigned vwIdx = 0; cmGrPgH_t pgH = pageHandle(); cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx); cmGrH_t cvH = cmGrViewGrHandle( vwH ); cmGrAxH_t axH = cmGrAxNullHandle; cmGrVExt_t limExt; _samplesMetricId = cmGrPageLabelFuncRegister( pgH, gvRoundHashValueFunc, this, "Round" ); _secondsMetricId = cmGrPageLabelFuncRegister( pgH, gvMinSecMsHashValueFunc, this, "Min:Sec:Ms" ); unsigned pitchLabelFuncId = cmGrPageLabelFuncRegister( pgH, gvMidiSciPitchValueFunc, this, "Pitch" ); cmGrVExtSetD(&limExt,0,0,0,127); cmGrObjSetWorldExt( cvH, cmGrRootObjH(cvH), &limExt ); cmGrObjSetWorldLimitExt(cvH, cmGrRootObjH(cvH), &limExt, kTopGrFl | kBottomGrFl ); axH = cmGrViewAxisHandle(vwH, kTopGrIdx); cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashMarkGrFl | kHashLabelGrFl )); axH = cmGrViewAxisHandle(vwH, kLeftGrIdx ); cmGrAxisSetLabelFunc( axH, pitchLabelFuncId ); cmGrViewSetLabelFunc( vwH, kLeftGrIdx, pitchLabelFuncId ); axH = cmGrViewAxisHandle(vwH, kRightGrIdx); cmGrAxisSetCfg( axH, cmClrFlag(cmGrAxisCfg( axH ), kHashLabelGrFl )); cmGrViewSetCfg( vwH, cmSetFlag(cmGrViewCfg(vwH),kSelectHorzGrFl) ); } cmGrScFltk::~cmGrScFltk() { } cmScMsgTypeId_t cmGrScFltk::recvScoreMsg( const void* msg, unsigned msgByteCnt ) { cmScMsg_t m; cmScoreDecode(msg,msgByteCnt,&m); switch( m.typeId ) { case kBeginMsgScId: { _objId = 0; _objSecs = 0; // remove all objects from all views //cmGrPageClear(pageHandle()); //_srate = m.srate; //_updateSeqMenu(m.seqCnt,m.seqId); } break; case kEndMsgScId: //size(w(),h()+1); break; case kEventMsgScId: _insertEvent(&m.u.evt); break; case kSectionMsgScId: _insertSection(&m.u.sect); break; case kVarMsgScId: break; default: { assert(0); } } return m.typeId; } void cmGrScFltk::setSampleRate( double srate ) { _srate = srate; } double cmGrScFltk::sampleRate() const { return _srate; } bool cmGrScFltk::on_plot_object( cmGrPlotCbArg_t* arg ) { if( arg->selId==kStateChangeGrPlId && cmIsFlag(arg->deltaFlags,kSelectGrPlFl) ) { scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(arg->objH); if( sop!=NULL && sop->id==kEventMsgScId && sop->u.ep != NULL /* && sep->type == kBarEvtScId */ ) { _lastBarPlotObjH = arg->objH; unsigned scoreIdx = scoreSelectedEleIndex(); // callback to: kcApp::_ctl_cb(ctl_t* cp) callback()(this,user_data()); _cmdIf->onScoreBarSelected(scoreIdx); setStatusText(cmTsPrintfS("Score Index:%i",scoreIdx)); } } return true; } void cmGrScFltk::selectBar( unsigned barNumb ) { cmGrPlH_t plH = plotHandle(); unsigned n = cmGrPlotObjectCount(plH); unsigned i; for(i=0; iid==kEventMsgScId && sop->u.ep!=NULL && sop->u.ep->type==kBarEvtScId && sop->u.ep->barNumb==barNumb ) { unsigned flags = cmGrPlotObjStateFlags(poH); cmGrPlotObjSetStateFlags(poH,cmSetFlag(flags,kFocusGrPlFl | kSelectGrPlFl)); redraw(); _lastBarPlotObjH = poH; _cmdIf->onScoreBarSelected(sop->u.ep->locIdx); setStatusText(cmTsPrintfS("Score Index:%i",sop->u.ep->locIdx)); break; } } } } unsigned cmGrScFltk::scoreSelectedEleIndex() const { if( cmGrPlotObjIsValid(_lastBarPlotObjH) ) { scObj_t* sop = (scObj_t*)cmGrPlotObjUserPtr(_lastBarPlotObjH); if( sop!=NULL && sop->id==kEventMsgScId && sop->u.ep != NULL /* && sop->u.ep->type == kBarEvtScId */ ) return sop->u.ep->locIdx; } return cmInvalidIdx; } void cmGrScFltk::setScoreLocation( unsigned locIdx, unsigned vel, unsigned smpIdx ) { } void cmGrScFltk::_insertSection( const cmScoreSection_t* m ) { // The argument is a serialzed copy of a cmScoreSection_t record. // Convert it to a pointer to an actual object in the local score mgr. if( cmGrPageIsValid(pageHandle()) == false ) return; m = _cmdIf->scoreSectionIdToPtr(m->index); assert(m!=NULL); const cmScoreEvt_t* ep = _cmdIf->scoreEventIdToPtr(m->begEvtIndex); assert( ep != NULL ); cmGrPlH_t plH = plotHandle(); cmGrPgH_t pgH = pageHandle(); unsigned vwIdx = 0; cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx ); cmGrH_t cvH = cmGrViewGrHandle( vwH ); cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle; cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle; cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle; cmGrPlObjH_t objH = cmGrPlObjNullHandle; cmGrPlObjTypeId_t objTypeId = kLineGrPlId; cmReal_t x = ep->secs; cmReal_t y = 120; cmReal_t w = 0; cmReal_t h = 7; const cmChar_t* label = m->label; unsigned flags = kNoDragGrPlFl; cmGrVExt_t wext; scObj_t scObj(m); cmGrVExtSetNull(&wext); if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC ) { cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score section.", cmStringNullGuard(label)); return; } cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj)); unsigned f = 0 ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl); cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlackGrId ); cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kGreenGrId ); //cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 ); cmGrPlotObjSetFontSize(objH,8); } void cmGrScFltk::_insertEvent( const cmScoreEvt_t* m ) { // The argument is a serialzed copy of a cmScoreEvt record. // Convert it to a pointer to an actual object in the local score mgr. if( cmGrPageIsValid(pageHandle()) == false ) return; m = _cmdIf->scoreEventIdToPtr(m->index); assert(m!=NULL); cmGrPlH_t plH = plotHandle(); cmGrPgH_t pgH = pageHandle(); unsigned vwIdx = 0; cmGrVwH_t vwH = cmGrPageViewHandle( pgH, vwIdx ); cmGrH_t cvH = cmGrViewGrHandle( vwH ); cmGrPlObjH_t parentObjH = cmGrPlObjNullHandle; cmGrPlObjH_t xAnchorObjH = cmGrPlObjNullHandle; cmGrPlObjH_t yAnchorObjH = cmGrPlObjNullHandle; cmGrPlObjH_t objH = cmGrPlObjNullHandle; cmGrPlObjTypeId_t objTypeId = kVLineGrPlId; cmReal_t x = m->secs; cmReal_t y = 0; cmReal_t w = 0; cmReal_t h = 127; const cmChar_t* label = NULL; unsigned flags = kNoDragGrPlFl; int bufN = 7; cmChar_t buf[bufN+1]; cmGrVExt_t wext; scObj_t scObj(m); cmGrVExtSetNull(&wext); switch( m->type ) { case kNonEvtScId: objTypeId = kRectGrPlId; y = m->pitch; h = 1; w = m->durSecs; label = cmMidiToSciPitch(m->pitch,NULL,0); break; case kBarEvtScId: { buf[bufN] = 0; snprintf(buf,bufN,"%i",m->barNumb); objTypeId = kVLineGrPlId; label = buf; } break; case kPedalEvtScId: if( cmIsFlag(m->flags, kPedalDnScFl ) == false ) return; objTypeId = kRectGrPlId; y = m->pitch; // pedal type (damper=64, sostenuto=66) is held in pitch h = 1; w = m->durSecs; flags += kNoFillGrPlFl; break; default: return; } if( cmGrPlotObjCreate(plH, cvH, &objH, _objId++, parentObjH, xAnchorObjH, yAnchorObjH, objTypeId, flags, x, y, w, h, label, cmGrVExtIsNull(&wext)?NULL:&wext ) != kOkGrPlRC ) { cmErrMsg(&_err,kInsertObjFailRC,"Insert failed on a score event.", cmStringNullGuard(label)); return; } cmGrPlotObjAllocUser(objH,&scObj,sizeof(scObj)); switch( m->type ) { case kBarEvtScId: { unsigned f = _togFl ? (kNorthJsGrFl | kTopJsGrFl) : (kSouthJsGrFl | kBottomJsGrFl); cmGrPlotObjSetLabelAttr( objH, f | kWestJsGrFl | kTopJsGrFl | kRightJsGrFl, 0, kBlueGrId ); cmGrPlotObjSetLineColor( objH, kEnablePlGrId, kYellowGrId ); cmGrPlotObjSetPhysExt(objH, 1, 0, 1, 0 ); _togFl = !_togFl; } break; case kNonEvtScId: cmGrPlotObjSetLineColor( objH, kEnablePlGrId, cmGrPlotObjFillColor(objH,kEnablePlGrId) ); cmGrPlotObjSetFontSize(objH,8); break; case kPedalEvtScId: cmGrPlotObjSetLineColor( objH, kEnablePlGrId, y==64 ? kDarkGreenGrId : kLightGreenGrId ); break; default: break; } if( cmIsFlag(m->flags,kInvalidScFl) ) { cmGrPlotObjSetFillColor(objH, kEnablePlGrId, kRedGrId ); } } void cmGrScFltk::_createMenu( ) { int idx = _menuBar->add("Score",0,NULL,0,FL_SUBMENU); const char* titleArray[] = { "Pitch", "Attributes", "Dynamics", "Location", "Fraction", "Section Even", "Section Dyn", "Section Tempo" }; bool onFl[] = { true, false, false, false, false, false, false, false }; int i; for(i=0; iinsert(idx+1+i,titleArray[i],0,_s_menuCallback, _menuArray + i, FL_MENU_TOGGLE ); if( onFl[i] ) { Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + idx + i + 1; mip->set(); } } } bool cmGrScFltk::_isMenuChecked( int id ) { unsigned i; // locate the menu item assoc'd with id for(i=0; ifind_index("Score")) == -1 ) return false; // The menu items and _menuArray[] were initialized in the same order // therefore the offset from the base of both should be the same. Fl_Menu_Item* mip = (Fl_Menu_Item*)_menuBar->menu() + menuIdx + i + 1; assert( (item_t*)mip->user_data() == _menuArray + i ); return mip->value() != 0; } void cmGrScFltk::_setEventLabels() { enum { kPitchFl=0x01, kAttrFl=0x02, kDynFl=0x04, kLocFl=0x08, kFracFl=0x10 }; cmGrPlH_t plH = plotHandle(); unsigned flags = 0; flags |= _isMenuChecked(kPitchMId) ? kPitchFl : 0; flags |= _isMenuChecked(kAttrMId) ? kAttrFl : 0; flags |= _isMenuChecked(kDynMId) ? kDynFl : 0; flags |= _isMenuChecked(kLocIdxMId) ? kLocFl : 0; flags |= _isMenuChecked(kFracMId) ? kFracFl : 0; unsigned n = cmGrPlotObjectCount(plH); unsigned i; for(i=0; iid==kEventMsgScId && sop->u.ep!=NULL && sop->u.ep->type==kNonEvtScId ) { const cmScoreEvt_t* ep = sop->u.ep; int bufN = 255; cmChar_t buf[ bufN+1 ]; buf[bufN] = 0; buf[0] = 0; if( cmIsFlag(flags,kPitchFl) ) snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",cmMidiToSciPitch(ep->pitch,NULL,0)); if( cmIsFlag(flags,kAttrFl) ) { cmChar_t s[4]; int j=0; if( cmIsFlag(ep->flags,kEvenScFl) ) s[j++] = 'e'; if( cmIsFlag(ep->flags,kDynScFl) ) s[j++] = 'd'; if( cmIsFlag(ep->flags,kTempoScFl) ) s[j++] = 't'; s[j] = 0; snprintf(buf+strlen(buf),bufN-strlen(buf),"%s ",s); } if( cmIsFlag(flags,kDynFl) && cmIsFlag(ep->flags,kDynScFl) ) { snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%i",ep->dynVal); if( ep->perfDynLvl != 0 ) snprintf(buf+strlen(buf),bufN-strlen(buf),"|%i ",ep->perfDynLvl); else snprintf(buf+strlen(buf),bufN-strlen(buf)," "); } if( cmIsFlag(flags,kLocFl) ) snprintf(buf+strlen(buf),bufN-strlen(buf),"loc:%i ",ep->locIdx); if( cmIsFlag(flags,kFracFl) && ep->frac != 0) snprintf(buf+strlen(buf),bufN-strlen(buf),"%5.3f ",ep->frac); cmGrPlotObjSetLabel(poH, buf ); } } } } void cmGrScFltk::_setSectionLabels() { enum { kEvenFl=0x01, kDynFl=0x02, kTempoFl=0x04 }; cmGrPlH_t plH = plotHandle(); unsigned flags = 0; flags |= _isMenuChecked(kSectEvenMId) ? kEvenFl : 0; flags |= _isMenuChecked(kSectDynMId) ? kDynFl : 0; flags |= _isMenuChecked(kSectTempoMId) ? kTempoFl : 0; unsigned n = cmGrPlotObjectCount(plH); unsigned i; for(i=0; iid==kSectionMsgScId && sop->u.sp!=NULL ) { const cmScoreSection_t* sp = sop->u.sp; int bufN = 255; cmChar_t buf[ bufN+1 ]; buf[bufN] = 0; buf[0] = 0; snprintf(buf,bufN,"%s ",sp->label); if( cmIsFlag(flags,kEvenFl) && sp->vars[kEvenVarScId] != DBL_MAX) snprintf(buf+strlen(buf),bufN-strlen(buf),"e:%f ",sp->vars[kEvenVarScId]); if( cmIsFlag(flags,kDynFl) && sp->vars[kDynVarScId] != DBL_MAX) snprintf(buf+strlen(buf),bufN-strlen(buf),"d:%f ",sp->vars[kDynVarScId]); if( cmIsFlag(flags,kTempoFl) && sp->vars[kTempoVarScId] != DBL_MAX) snprintf(buf+strlen(buf),bufN-strlen(buf),"t:%f ",sp->vars[kTempoVarScId]); cmGrPlotObjSetLabel(poH, buf ); } } } } void cmGrScFltk::_s_menuCallback(Fl_Widget* w, void* arg ) { item_t* ip = (item_t*)arg; cmGrScFltk* p = ip->p; unsigned long id = ip->id; switch( id ) { case kPitchMId: case kAttrMId: case kDynMId: case kLocIdxMId: case kFracMId: { p->_setEventLabels(); p->redraw(); } break; case kSectEvenMId: case kSectDynMId: case kSectTempoMId: { p->_setSectionLabels(); p->redraw(); } break; } }