From f158026c1dde467141d23d994d06b41471c6e945 Mon Sep 17 00:00:00 2001 From: kevin Date: Sun, 26 Nov 2023 15:29:46 -0500 Subject: [PATCH] cwSfScore.h/cpp : Added 'endEvtIndex' to section_t. Add bar_to_event() and event_index_to_section(). --- cwSfScore.cpp | 117 +++++++++++++++++++++++++++++++++++++------------- cwSfScore.h | 13 ++++-- 2 files changed, 96 insertions(+), 34 deletions(-) diff --git a/cwSfScore.cpp b/cwSfScore.cpp index 30210c1..efc15ad 100644 --- a/cwSfScore.cpp +++ b/cwSfScore.cpp @@ -4,6 +4,7 @@ #include "cwMem.h" #include "cwText.h" #include "cwObject.h" +#include "cwFile.h" #include "cwMidi.h" #include "cwFileSys.h" #include "cwDynRefTbl.h" @@ -89,8 +90,10 @@ namespace cw for(unsigned i=0; ieventN; ++i) + { + mem::release(p->eventA[i].sciPitch); mem::release(p->eventA[i].varA); - + } mem::release(p->eventA); if( p->deleteParserH_Fl ) @@ -161,8 +164,10 @@ namespace cw e->line = pe->csvRowNumb; e->parseEvtIdx = pe->index; e->hash = pe->hash; + e->sciPitch = pe->sciPitch == nullptr ? nullptr : mem::duplStr(pe->sciPitch); e->bpm = pe->bpm; e->bpm_rval = pe->bpm_rval; + e->varN = std::count_if( pe->varA, pe->varA + score_parse::kVarCnt, [](const score_parse::event_var_t& x){ return x.flags!=0; }); e->varA = mem::allocZ(e->varN); @@ -266,25 +271,39 @@ namespace cw const score_parse::event_t* eventA = event_array( p->parserH ); unsigned eventN = event_count( p->parserH ); event_t* begEvt = nullptr; - - // advance to the first onset event - for(unsigned i = beg_evt_idx; i<=end_evt_idx && ilabel),ps->begEvent->hash); goto errLabel; } - + + if( endEvt == nullptr ) + { + rc = cwLogError(kInvalidStateRC,"The section '%s' does not have an 'end' event with hash:%x.",cwStringNullGuard(ps->label),ps->endEvent->hash); + goto errLabel; + } + section->label = mem::duplStr(ps->label); section->index = i; section->begEvtIndex = begEvt->index; + section->endEvtIndex = endEvt->index; section->locPtr = p->locA + p->eventA[begEvt->index].oLocId; section->locPtr->begSectPtr = section; @@ -433,7 +452,7 @@ namespace cw // Get the min BPM auto min_evt = std::min_element(eventA,eventA+eventN,[](auto& x0, auto& x1){ return x0.bpmbpm,min_evt->csvRowNumb); + cwLogInfo("min tempo:%i at CSV row:%i",min_evt->bpm,min_evt->csvRowNumb); if( min_evt->bpm == 0 ) { @@ -787,7 +806,7 @@ namespace cw } - void _report_print( sfscore_t* p, rpt_event_t* rptA, unsigned rptN ) + void _report_print( sfscore_t* p, rpt_event_t* rptA, unsigned rptN, file::handle_t fH ) { unsigned bar0 = 0; const char* sec0 = nullptr; @@ -795,25 +814,28 @@ namespace cw const char* sec_str = "S:"; const char* bar_str = "B:"; - printf("e idx oloc secs bpm b_rval rtmpo op sectn sdx bar bdx scip vel frac g\n"); - printf("----- ----- ------- --- ------ ----- --- ------ --- ----- --- ---- --- ----- -\n"); for(rpt_event_t* r=rptA; revent; const section_t* section = r->section; - - const char* d_bar_str = bar0 != e->barNumb ? bar_str : blank_str; - const char* d_sec_str = textIsEqual(sec0,section->label) ? blank_str : sec_str; - - char sciPitch[5]; - midi::midiToSciPitch( e->pitch, sciPitch, 5 ); + bool new_bar_fl = bar0 != e->barNumb; + const char* d_bar_str = new_bar_fl ? bar_str : blank_str; + const char* d_sec_str = textIsEqual(sec0,section->label) ? blank_str : sec_str; + + if( r==rptA || new_bar_fl ) + { + printf(fH,"%i :\n",e->barNumb); + printf(fH,"e idx oloc secs bpm b_rval rtmpo op sectn sdx bar bdx scip vel frac g hash \n"); + printf(fH,"----- ----- ------- --- ------ ----- --- ------ --- ----- --- ---- --- ----- - ----------\n"); + } + bar0 = e->barNumb; sec0 = section->label; - printf("%5i %5i %7.3f %3i %6.4f %5.3f %3s %2s%4s %3i %2s%3i %3i %4s %3i %5.3f %c ", + printf(fH,"%5i %5i %7.3f %3i %6.4f %5.3f %3s %2s%4s %3i %2s%3i %3i %4s %3i %5.3f %c 0x%x ", e->index, e->oLocId, e->secs, @@ -827,10 +849,11 @@ namespace cw d_bar_str, e->barNumb, e->barNoteIdx, - sciPitch, + e->sciPitch, e->vel, e->frac, - cwIsFlag(e->flags,score_parse::kGraceFl) ? 'g' : ' '); + cwIsFlag(e->flags,score_parse::kGraceFl) ? 'g' : ' ', + e->hash); // for each possible var type for(unsigned vi=0; vi= e->varA+e->varN ) - printf(" "); + printf(fH," "); else { const char* sect_label = var->set->sectArray[0]==nullptr ? "****" : var->set->sectArray[0]->label; - printf("%s-%03i-%s ",score_parse::var_flags_to_char(var->flags), var->set->id, sect_label); + printf(fH,"%s-%03i-%s ",score_parse::var_flags_to_char(var->flags), var->set->id, sect_label); } } - printf("\n"); + printf(fH,"\n"); } } - rpt_event_t* _report_create( sfscore_t* p ) + rpt_event_t* + _report_create( sfscore_t* p ) { rpt_event_t* rptA = mem::allocZ( p->eventN ); unsigned curSectionIdx = 0; @@ -889,7 +913,7 @@ namespace cw return rptA; } - rc_t _report( sfscore_t* p ) + rc_t _report( sfscore_t* p, const char* fname ) { rc_t rc = kOkRC; @@ -897,8 +921,18 @@ namespace cw if((rptA = _report_create(p)) != nullptr ) { + file::handle_t fH; - _report_print(p,rptA,p->eventN); + if((rc = file::open(fH,fname,file::kWriteFl)) != kOkRC ) + { + rc = cwLogError(rc,"Score report file open failed on '%s'.",cwStringNullGuard(fname)); + goto errLabel; + } + + _report_print(p,rptA,p->eventN, fH); + + errLabel: + close(fH); mem::release(rptA); } @@ -1060,12 +1094,23 @@ const cw::sfscore::event_t* cw::sfscore::event( handle_t h, unsigned idx ) const cw::sfscore::event_t* cw::sfscore::hash_to_event( handle_t h, unsigned hash ) { sfscore_t* p = _handleToPtr(h); - for(unsigned i=0; p->eventN; ++i) + for(unsigned i=0; ieventN; ++i) if( p->eventA[i].hash == hash ) return p->eventA + i; + + return nullptr; +} + +const cw::sfscore::event_t* cw::sfscore::bar_to_event( handle_t h, unsigned barNumb ) +{ + sfscore_t* p = _handleToPtr(h); + for(unsigned i=0; ieventN; ++i) + if( p->eventA[i].barNumb == barNumb ) + return p->eventA + i; return nullptr; } + unsigned cw::sfscore::loc_count( handle_t h ) { sfscore_t* p = _handleToPtr(h); @@ -1102,10 +1147,20 @@ const cw::sfscore::section_t* cw::sfscore::section_base( handle_t h ) return p->sectionA; } +const cw::sfscore::section_t* cw::sfscore::event_index_to_section( handle_t h, unsigned event_idx ) +{ + sfscore_t * p = _handleToPtr(h); + for(unsigned i=0; isectionN; ++i) + if( p->sectionA[i].begEvtIndex <= event_idx && event_idx <= p->sectionA[i].endEvtIndex ) + return p->sectionA + i; + return nullptr; +} + + void cw::sfscore::report( handle_t h, const char* out_fname ) { sfscore_t* p = _handleToPtr(h); printf("Score Report\n"); - _report(p); + _report(p,out_fname); } diff --git a/cwSfScore.h b/cwSfScore.h index e0906bf..8ce1467 100644 --- a/cwSfScore.h +++ b/cwSfScore.h @@ -16,7 +16,8 @@ namespace cw unsigned index; // index of this record in the internal section array struct loc_str* measLocPtr; // last location of last set to be applied to this section struct loc_str* locPtr; // location where this section starts - unsigned begEvtIndex; // score element index where this section starts + unsigned begEvtIndex; // score element index where this section starts + unsigned endEvtIndex; // last element in this section unsigned setCnt; // Count of elements in setArray[] struct set_str** setArray; // Ptrs to sets which are applied to this section. @@ -37,7 +38,7 @@ namespace cw double durSecs; // Duration in seconds unsigned index; // Index of this event in the event array. unsigned oLocId; // Index of the onset location (oloc) containing this event - midi::byte_t pitch; // MIDI pitch of this note or the MIDI pedal id of pedal down/up msg (64=sustain 65=sostenuto 66=soft) + midi::byte_t pitch; // MIDI pictch of this note or the MIDI pedal id of pedal down/up msg (64=sustain 65=sostenuto 66=soft) midi::byte_t vel; // MIDI velocity of this note unsigned flags; // Attribute flags for this event unsigned dynLevel; // Dynamcis value pppp to ffff (1 to 11) for this note. @@ -48,6 +49,7 @@ namespace cw unsigned line; // Line number of this event in the score file. unsigned parseEvtIdx; // Index of event from score_parse event index. unsigned hash; // unique hash id for this note + char* sciPitch; // Sci. pitch of this note var_t* varA; // varA[varN] set's this event belongs to unsigned varN; // Length of varA[] @@ -67,7 +69,7 @@ namespace cw } event_t; // A 'set' is a collection of events that are grouped in time and all marked with a given attribute. - // (e.g. eveness, tempo, dynamcs ... )o + // (e.g. eveness, tempo, dynamcs ... ) typedef struct set_str { unsigned id; // Unique id for this set @@ -128,6 +130,9 @@ namespace cw const event_t* event( handle_t h, unsigned idx ); const event_t* hash_to_event( handle_t h, unsigned hash ); + + // Return the first event in the bar. + const event_t* bar_to_event( handle_t h, unsigned barNumb ); unsigned loc_count( handle_t h ); const loc_t* loc_base( handle_t h ); @@ -138,6 +143,8 @@ namespace cw unsigned section_count( handle_t h ); const section_t* section_base( handle_t h ); + const section_t* event_index_to_section( handle_t h, unsigned event_idx ); + void report( handle_t h, const char* out_fname=nullptr );