diff --git a/Makefile.am b/Makefile.am index b12a5a1..b4a126a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -71,8 +71,8 @@ libcwSRC += src/libcw/cwIo.cpp src/libcw/cwIoTest.cpp src/libcw/cwIoMinTest.cp libcwHDR += src/libcw/cwIoMidiRecordPlay.h src/libcw/cwIoAudioRecordPlay.h src/libcw/cwIoAudioMidiApp.h src/libcw/cwIoFlow.h libcwSRC += src/libcw/cwIoMidiRecordPlay.cpp src/libcw/cwIoAudioRecordPlay.cpp src/libcw/cwIoAudioMidiApp.cpp src/libcw/cwIoFlow.cpp -libcwHDR += src/libcw/cwIoPresetSelApp.h src/libcw/cwPianoScore.h src/libcw/cwPresetSel.h src/libcw/cwVelTableTuner.h -libcwSRC += src/libcw/cwIoPresetSelApp.cpp src/libcw/cwPianoScore.cpp src/libcw/cwPresetSel.cpp src/libcw/cwVelTableTuner.cpp +libcwHDR += src/libcw/cwIoPresetSelApp.h src/libcw/cwPianoScore.h src/libcw/cwPresetSel.h src/libcw/cwVelTableTuner.h src/libcw/cwGutimReg.h +libcwSRC += src/libcw/cwIoPresetSelApp.cpp src/libcw/cwPianoScore.cpp src/libcw/cwPresetSel.cpp src/libcw/cwVelTableTuner.cpp src/libcw/cwGutimReg.cpp libcwHDR += src/libcw/cwDynRefTbl.h src/libcw/cwScoreParse.h src/libcw/cwSfScore.h libcwSRC += src/libcw/cwDynRefTbl.cpp src/libcw/cwScoreParse.cpp src/libcw/cwSfScore.cpp diff --git a/cwGutimReg.cpp b/cwGutimReg.cpp new file mode 100644 index 0000000..47b6e6d --- /dev/null +++ b/cwGutimReg.cpp @@ -0,0 +1,250 @@ +#include "cwCommon.h" +#include "cwLog.h" +#include "cwCommonImpl.h" +#include "cwMem.h" +#include "cwText.h" +#include "cwObject.h" +#include "cwCsv.h" +#include "cwFile.h" +#include "cwFileSys.h" +#include "cwGutimReg.h" + +namespace cw +{ + namespace gutim + { + namespace reg + { + typedef struct reg_file_str + { + char* player_name; + char* take_label; + char* path; + char* midi_fname; + file_t r; + } reg_file_t; + + typedef struct reg_str + { + reg_file_t* fileA; + unsigned fileN; + } reg_t; + + reg_t* _handleToPtr( handle_t h ) + { return handleToPtr(h); } + + rc_t _destroy( reg_t* p ) + { + for(unsigned i=0; ifileN; ++i) + { + mem::release(p->fileA[i].player_name); + mem::release(p->fileA[i].take_label); + mem::release(p->fileA[i].path); + mem::release(p->fileA[i].midi_fname); + } + mem::release(p->fileA); + mem::release(p); + + return kOkRC; + } + + } + } +} + + +cw::rc_t cw::gutim::reg::create( handle_t& hRef, const char* fname ) +{ + rc_t rc = kOkRC; + csv::handle_t csvH; + const char* colLabelA[] = {"player_name","take_label","session_number","take_number","beg_loc","end_loc","skip_score_follow_fl","path" }; + unsigned colLabelN = sizeof(colLabelA)/sizeof(colLabelA[0]); + unsigned lineAllocN = 0; + filesys::pathPart_t* pathPart = nullptr; + + auto cmp_func = [](const reg_file_t& r0, const reg_file_t& r1) + { + int cmp = textCompare(r0.player_name,r1.player_name); + + if( cmp < 0 ) + return true; + if( cmp > 0 ) + return false; + + if( r0.r.session_number < r1.r.session_number ) + return true; + if( r0.r.session_number > r1.r.session_number ) + return false; + + if( r0.r.take_number < r1.r.take_number ) + return true; + if( r0.r.take_number > r1.r.take_number ) + return false; + + return false; + }; + + if((rc = destroy(hRef)) != kOkRC ) + return rc; + + reg_t* p = mem::allocZ(); + + // open the CSV + if((rc = create(csvH,fname,colLabelA,colLabelN)) != kOkRC ) + { + rc = cwLogError(rc,"GUTIM reg CSV file open failed on '%s'.",cwStringNullGuard(fname)); + goto errLabel; + } + + // parse the reg CSV fname + pathPart = filesys::pathParts(fname); + + // get the count of lines in the CSV file + if((rc = line_count(csvH,lineAllocN)) != kOkRC ) + { + rc = cwLogError(rc,"CSV line count failed."); + goto errLabel; + } + + // rewind CSV file + if((rc = rewind(csvH)) != kOkRC ) + { + rc = cwLogError(rc,"GUTIM registry CSV '%s' rewind failed.",cwStringNullGuard(fname)); + goto errLabel; + } + + // verify that that the CSV is not tempy + if( lineAllocN <= 1 ) + { + rc = cwLogError(kInvalidStateRC,"The GUTIM registry CSV '%s' is empty.",cwStringNullGuard(fname)); + goto errLabel; + } + + lineAllocN -= 1; // subtract one to account for column titles + + p->fileA = mem::allocZ(lineAllocN); + + // skip col. labels + if((rc = next_line(csvH)) != kOkRC ) + { + rc = cwLogError(rc,"CSV line advance failed on first line."); + goto errLabel; + } + + for(unsigned i=0; ifileA[i]; + + if((rc = getv( csvH, + "player_name", fr.r.player_name, + "take_label", fr.r.take_label, + "path", fr.r.path, + "session_number", fr.r.session_number, + "take_number", fr.r.take_number, + "beg_loc", fr.r.beg_loc, + "end_loc", fr.r.end_loc, + "skip_score_follow_fl", fr.r.skip_score_follow_fl )) != kOkRC ) + { + rc = cwLogError(rc,"GUTIM registry CSV parse failed."); + goto errLabel; + } + + fr.player_name = mem::duplStr(fr.r.player_name); + fr.r.player_name = fr.player_name; + + fr.take_label = mem::duplStr(fr.r.take_label); + fr.r.take_label = fr.take_label; + + fr.path = mem::duplStr(fr.r.path); + fr.r.path = fr.path; + + fr.midi_fname = filesys::makeFn(pathPart->dirStr, "midi", "mid", fr.r.path, nullptr ); + fr.r.midi_fname = fr.midi_fname; + + p->fileN += 1; + + // advance the current CSV + if((rc = next_line( csvH )) != kOkRC ) + { + if( rc == kEofRC ) + { + rc = kOkRC; + break; + } + + rc = cwLogError(rc,"CSV 'next line' failed on '%s'.",cwStringNullGuard(fname)); + goto errLabel; + } + } + + std::sort(p->fileA,p->fileA+p->fileN,cmp_func); + + hRef.set(p); + +errLabel: + if(rc != kOkRC ) + rc = _destroy(p); + + destroy(csvH); + + mem::release(pathPart); + return rc; +} + +cw::rc_t cw::gutim::reg::destroy( handle_t& hRef ) +{ + rc_t rc = kOkRC; + + if( !hRef.isValid() ) + return rc; + + reg_t* p = _handleToPtr(hRef); + + if((rc = _destroy(p)) != kOkRC ) + { + cwLogError(rc,"Gutim registry destroy failed."); + goto errLabel; + } + + hRef.clear(); + +errLabel: + return rc; +} + +unsigned cw::gutim::reg::file_count( handle_t h ) +{ + reg_t* p = _handleToPtr(h); + return p->fileN; +} + +cw::gutim::reg::file_t cw::gutim::reg::file_record( handle_t h, unsigned file_idx ) +{ + reg_t* p = _handleToPtr(h); + return p->fileA[ file_idx ].r; +} + +void cw::gutim::reg::report( handle_t h ) +{ + reg_t* p = _handleToPtr(h); + + cwLogInfo("performer sess take b-loc e-loc skip path"); + cwLogInfo("---------- ---- ---- ----- ----- ----- -------------------------------------------"); + for(unsigned i=0; ifileN; ++i) + { + const reg_file_t& fr = p->fileA[i]; + const file_t& r = fr.r; + + cwLogInfo("%10s %4i %4i %5i %5i %5s %s %s", + r.player_name, + r.session_number, + r.take_number, + r.beg_loc, + r.end_loc, + r.skip_score_follow_fl?"true":"false", + r.path, + r.midi_fname); + + } + +} diff --git a/cwGutimReg.h b/cwGutimReg.h new file mode 100644 index 0000000..1e79c8a --- /dev/null +++ b/cwGutimReg.h @@ -0,0 +1,39 @@ +#ifndef cwGutimReg_h +#define cwGutimReg_h + +namespace cw +{ + namespace gutim + { + namespace reg + { + typedef handle handle_t; + + typedef struct file_str + { + const char* player_name; + const char* take_label; + const char* path; + const char* midi_fname; + bool skip_score_follow_fl; + unsigned session_number; + unsigned take_number; + unsigned beg_loc; + unsigned end_loc; + } file_t; + + + rc_t create( handle_t& hRef, const char* fname ); + rc_t destroy( handle_t& hRef ); + + unsigned file_count( handle_t h ); + file_t file_record( handle_t h, unsigned file_idx ); + + void report( handle_t h ); + + + } + } +} + +#endif