cwPianoScore.h/cpp : Read dyn/even/tempo/cost from score CSV.

This commit is contained in:
kevin 2023-11-26 15:26:17 -05:00
parent 29dd0af4da
commit e6c70090fa
2 changed files with 106 additions and 24 deletions

View File

@ -2,6 +2,7 @@
#include "cwLog.h" #include "cwLog.h"
#include "cwCommonImpl.h" #include "cwCommonImpl.h"
#include "cwMem.h" #include "cwMem.h"
#include "cwText.h"
#include "cwObject.h" #include "cwObject.h"
#include "cwPianoScore.h" #include "cwPianoScore.h"
#include "cwMidi.h" #include "cwMidi.h"
@ -10,6 +11,8 @@
#include "cwCsv.h" #include "cwCsv.h"
#include "cwVectOps.h" #include "cwVectOps.h"
#define INVALID_PERF_MEAS (-1)
namespace cw namespace cw
{ {
namespace perf_score namespace perf_score
@ -87,6 +90,14 @@ namespace cw
return buf_idx; return buf_idx;
} }
rc_t _parse_csv_string( const char* lineBuf, unsigned bfi, unsigned efi, char* val, unsigned valCharN )
{
unsigned n = std::min(efi-bfi,valCharN);
strncpy(val,lineBuf+bfi,n);
val[std::min(n,valCharN-1)] = 0;
return kOkRC;
}
rc_t _parse_csv_double( const char* lineBuf, unsigned bfi, unsigned efi, double &valueRef ) rc_t _parse_csv_double( const char* lineBuf, unsigned bfi, unsigned efi, double &valueRef )
{ {
errno = 0; errno = 0;
@ -130,9 +141,10 @@ namespace cw
kBpm_FIdx, kBpm_FIdx,
kGrace_FIdx, kGrace_FIdx,
kPedal_FIdx, kPedal_FIdx,
kDyn_FIdx,
kEven_FIdx, kEven_FIdx,
kDyn_FIdx,
kTempo_FIdx, kTempo_FIdx,
kCost_FIdx,
kMax_FIdx kMax_FIdx
}; };
@ -185,6 +197,34 @@ namespace cw
case kSection_FIdx: case kSection_FIdx:
rc = _parse_csv_unsigned( line_buf, bfi, efi, e->section ); rc = _parse_csv_unsigned( line_buf, bfi, efi, e->section );
break; break;
case kSPitch_FIdx:
rc = _parse_csv_string( line_buf, bfi, efi, e->sci_pitch, sizeof(e->sci_pitch) );
break;
case kEven_FIdx:
e->even = INVALID_PERF_MEAS;
if( efi > bfi+1 )
rc = _parse_csv_double( line_buf, bfi, efi, e->even );
break;
case kDyn_FIdx:
e->dyn = INVALID_PERF_MEAS;
if( efi > bfi+1 )
rc = _parse_csv_double( line_buf, bfi, efi, e->dyn );
break;
case kTempo_FIdx:
e->tempo = INVALID_PERF_MEAS;
if( efi > bfi+1 )
rc = _parse_csv_double( line_buf, bfi, efi, e->tempo );
break;
case kCost_FIdx:
e->cost = INVALID_PERF_MEAS;
if( efi > bfi+1 )
rc = _parse_csv_double( line_buf, bfi, efi, e->cost );
break;
default: default:
break; break;
@ -201,6 +241,28 @@ namespace cw
return rc; return rc;
} }
bool _does_file_have_loc_info( const char* fn )
{
rc_t rc = kOkRC;
bool has_loc_info_fl = false;
csv::handle_t csvH;
if((rc = create( csvH, fn)) != kOkRC )
goto errLabel;
for(unsigned i=0; i<col_count(csvH); ++i)
if( textIsEqual( col_title(csvH,i), "loc") )
{
has_loc_info_fl = true;
break;
}
destroy(csvH);
errLabel:
return has_loc_info_fl;
}
rc_t _parse_csv( score_t* p, const char* fn ) rc_t _parse_csv( score_t* p, const char* fn )
{ {
@ -227,15 +289,20 @@ namespace cw
p->uid_mapN = 0; p->uid_mapN = 0;
for(unsigned line=0; line<line_count; ++line) for(unsigned line=0; line<line_count; ++line)
{
if((rc = getLineAuto( fH, &lineBufPtr, &lineBufCharCnt )) != kOkRC )
{
if( rc != kEofRC )
rc = cwLogError( rc, "Line read failed on '%s' line number '%i'.",cwStringNullGuard(fn),line+1);
else
rc = kOkRC;
goto errLabel;
}
if( line > 0 ) // skip column title line if( line > 0 ) // skip column title line
{ {
if((rc = getLineAuto( fH, &lineBufPtr, &lineBufCharCnt )) != kOkRC )
{
rc = cwLogError( rc, "Line read failed on '%s' line number '%i'.",cwStringNullGuard(fn),line+1);
goto errLabel;
}
e = mem::allocZ<event_t>(); e = mem::allocZ<event_t>();
if((rc = _parse_csv_line( p, e, lineBufPtr, lineBufCharCnt )) != kOkRC ) if((rc = _parse_csv_line( p, e, lineBufPtr, lineBufCharCnt )) != kOkRC )
@ -266,7 +333,7 @@ namespace cw
p->uid_mapN += 1; p->uid_mapN += 1;
} }
}
errLabel: errLabel:
mem::release(lineBufPtr); mem::release(lineBufPtr);
@ -444,20 +511,36 @@ cw::rc_t cw::perf_score::create( handle_t& hRef, const char* fn )
return rc; return rc;
p = mem::allocZ< score_t >(); p = mem::allocZ< score_t >();
rc = _parse_csv(p,fn);
_set_bar_pitch_index(p); if( _does_file_have_loc_info(fn) )
{
if((rc = _parse_csv(p,fn)) != kOkRC )
goto errLabel;
_set_bar_pitch_index(p);
p->has_locs_fl = true;
}
else
{
if((rc = _parse_midi_csv(p, fn)) != kOkRC )
goto errLabel;
p->has_locs_fl = false;
}
hRef.set(p); hRef.set(p);
p->has_locs_fl = true; errLabel:
if( cfg != nullptr ) if( cfg != nullptr )
cfg->free(); cfg->free();
if( rc != kOkRC ) if( rc != kOkRC )
{
destroy(hRef); destroy(hRef);
rc = cwLogError(rc,"Performance score create failed on '%s'.",fn);
}
return rc; return rc;
} }
@ -566,12 +649,6 @@ const cw::perf_score::event_t* cw::perf_score::loc_to_event( handle_t h, unsigne
return _loc_to_event(p,loc); return _loc_to_event(p,loc);
} }
void cw::perf_score::loc_to_pitch_context( handle_t h, uint8_t* preNoteCtxA, uint8_t* postNoteCtxA, unsigned ctxN )
{
score_t* p = _handleToPtr(h);
}
cw::rc_t cw::perf_score::event_to_string( handle_t h, unsigned uid, char* buf, unsigned buf_byte_cnt ) cw::rc_t cw::perf_score::event_to_string( handle_t h, unsigned uid, char* buf, unsigned buf_byte_cnt )
{ {

View File

@ -16,7 +16,7 @@ namespace cw
unsigned tick; // event tick location unsigned tick; // event tick location
double sec; // event absolute time in seconds double sec; // event absolute time in seconds
double rval; // event rythmic value 2=1/2 1/4 .5=2 or 0 double rval; // event rythmic value 2=1/2 1/4 .5=2 or 0
char sci_pitch[4]; // scientific pitch char sci_pitch[5]; // scientific pitch
char dmark[6]; // dynamic mark (e.g. "pp","mf","fff") char dmark[6]; // dynamic mark (e.g. "pp","mf","fff")
unsigned dlevel; // dynamic level as an integer associated with dyn. mark unsigned dlevel; // dynamic level as an integer associated with dyn. mark
unsigned status; // MIDI status < type | channel > or 0 unsigned status; // MIDI status < type | channel > or 0
@ -25,12 +25,18 @@ namespace cw
unsigned bpm; // tempo BPM or 0 unsigned bpm; // tempo BPM or 0
char grace_mark[4]; // grace mark or 0 char grace_mark[4]; // grace mark or 0
unsigned bar; // bar number or 0 unsigned bar; // bar number or 0
unsigned barPitchIdx; // bar pitch index unsigned barPitchIdx; // bar pitch index or 0
unsigned section; // section number or 0 unsigned section; // section number or 0
double even;
double dyn;
double tempo;
double cost;
struct event_str* link; // list link struct event_str* link; // list link
} event_t; } event_t;
rc_t create( handle_t& hRef, const char* fn ); rc_t create( handle_t& hRef, const char* csv_fname );
rc_t create( handle_t& hRef, const object_t* cfg ); rc_t create( handle_t& hRef, const object_t* cfg );
// Read a CSV as written by cwIoMidiRecordPlay.save_csv(). // Read a CSV as written by cwIoMidiRecordPlay.save_csv().
@ -45,7 +51,6 @@ namespace cw
const event_t* base_event( handle_t h ); const event_t* base_event( handle_t h );
const event_t* loc_to_event( handle_t h, unsigned loc ); const event_t* loc_to_event( handle_t h, unsigned loc );
void loc_to_pitch_context( handle_t h, uint8_t* preNoteCtxA, uint8_t* postNoteCtxA, unsigned ctxN );
// Format the event as a string for printing. // Format the event as a string for printing.
rc_t event_to_string( handle_t h, unsigned uid, char* buf, unsigned buf_byte_cnt ); rc_t event_to_string( handle_t h, unsigned uid, char* buf, unsigned buf_byte_cnt );