Merge branch 'master' of gitea.larke.org:kevin/libcw
This commit is contained in:
commit
c065005ec9
@ -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
|
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
|
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
|
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
|
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
|
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
|
libcwSRC += src/libcw/cwDynRefTbl.cpp src/libcw/cwScoreParse.cpp src/libcw/cwSfScore.cpp
|
||||||
|
42
cwCsv.cpp
42
cwCsv.cpp
@ -310,7 +310,37 @@ namespace cw
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc_t _parse_bool_field( csv_t* p, unsigned colIdx, bool& valRef )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
const char* fieldStr = nullptr;
|
||||||
|
|
||||||
|
if((rc = _get_field_str(p,colIdx,fieldStr)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if( textIsEqualI(fieldStr,"true") )
|
||||||
|
valRef = true;
|
||||||
|
else
|
||||||
|
if( textIsEqualI(fieldStr,"false") )
|
||||||
|
valRef = false;
|
||||||
|
else
|
||||||
|
rc = cwLogError(kSyntaxErrorRC,"The value of a boolean must be either 'true' or 'false'.");
|
||||||
|
}
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc_t _parse_bool_field( csv_t* p, const char* colLabel, bool& valRef )
|
||||||
|
{
|
||||||
|
unsigned colIdx;
|
||||||
|
if((colIdx = _title_to_col_index(p, colLabel)) == kInvalidIdx )
|
||||||
|
return cwLogError(kInvalidArgRC,"The column label '%s' is not valid.",cwStringNullGuard(colLabel));
|
||||||
|
|
||||||
|
return _parse_bool_field(p,colIdx,valRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -496,6 +526,12 @@ cw::rc_t cw::csv::field_char_count( handle_t h, unsigned colIdx, unsigned& charC
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::csv::parse_field( handle_t h, unsigned colIdx, bool& valRef )
|
||||||
|
{
|
||||||
|
csv_t* p = _handleToPtr(h);
|
||||||
|
return _parse_bool_field( p, colIdx, valRef ) ;
|
||||||
|
}
|
||||||
|
|
||||||
cw::rc_t cw::csv::parse_field( handle_t h, unsigned colIdx, uint8_t& valRef )
|
cw::rc_t cw::csv::parse_field( handle_t h, unsigned colIdx, uint8_t& valRef )
|
||||||
{
|
{
|
||||||
csv_t* p = _handleToPtr(h);
|
csv_t* p = _handleToPtr(h);
|
||||||
@ -526,6 +562,12 @@ cw::rc_t cw::csv::parse_field( handle_t h, unsigned colIdx, const char*& valRef
|
|||||||
return _parse_string_field( p, colIdx, valRef );
|
return _parse_string_field( p, colIdx, valRef );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::csv::parse_field( handle_t h, const char* colLabel, bool& valRef )
|
||||||
|
{
|
||||||
|
csv_t* p = _handleToPtr(h);
|
||||||
|
return _parse_bool_field(p, colLabel, valRef );
|
||||||
|
}
|
||||||
|
|
||||||
cw::rc_t cw::csv::parse_field( handle_t h, const char* colLabel, uint8_t& valRef )
|
cw::rc_t cw::csv::parse_field( handle_t h, const char* colLabel, uint8_t& valRef )
|
||||||
{
|
{
|
||||||
csv_t* p = _handleToPtr(h);
|
csv_t* p = _handleToPtr(h);
|
||||||
|
3
cwCsv.h
3
cwCsv.h
@ -43,6 +43,8 @@ namespace cw
|
|||||||
rc_t parse_field( handle_t h, unsigned colIdx, unsigned& valRef );
|
rc_t parse_field( handle_t h, unsigned colIdx, unsigned& valRef );
|
||||||
rc_t parse_field( handle_t h, unsigned colIdx, int& valRef );
|
rc_t parse_field( handle_t h, unsigned colIdx, int& valRef );
|
||||||
rc_t parse_field( handle_t h, unsigned colIdx, double& valRef );
|
rc_t parse_field( handle_t h, unsigned colIdx, double& valRef );
|
||||||
|
rc_t parse_field( handle_t h, unsigned colIdx, bool& valRef );
|
||||||
|
|
||||||
|
|
||||||
// The returned pointer is a pointer into an internal 'line' buffer.
|
// The returned pointer is a pointer into an internal 'line' buffer.
|
||||||
// The reference is therefore only valid until the next call to next_line().
|
// The reference is therefore only valid until the next call to next_line().
|
||||||
@ -52,6 +54,7 @@ namespace cw
|
|||||||
rc_t parse_field( handle_t h, const char* colLabel, unsigned& valRef );
|
rc_t parse_field( handle_t h, const char* colLabel, unsigned& valRef );
|
||||||
rc_t parse_field( handle_t h, const char* colLabel, int& valRef );
|
rc_t parse_field( handle_t h, const char* colLabel, int& valRef );
|
||||||
rc_t parse_field( handle_t h, const char* colLabel, double& valRef );
|
rc_t parse_field( handle_t h, const char* colLabel, double& valRef );
|
||||||
|
rc_t parse_field( handle_t h, const char* colLabel, bool& valRef );
|
||||||
|
|
||||||
// The returned pointer is a pointer into an internal 'line' buffer.
|
// The returned pointer is a pointer into an internal 'line' buffer.
|
||||||
// The reference is therefore only valid until the next call to next_line().
|
// The reference is therefore only valid until the next call to next_line().
|
||||||
|
277
cwGutimReg.cpp
Normal file
277
cwGutimReg.cpp
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
#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<handle_t,struct reg_str>(h); }
|
||||||
|
|
||||||
|
rc_t _destroy( reg_t* p )
|
||||||
|
{
|
||||||
|
for(unsigned i=0; i<p->fileN; ++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<reg_t>();
|
||||||
|
|
||||||
|
// 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<reg_file_t>(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; i<lineAllocN; ++i)
|
||||||
|
{
|
||||||
|
reg_file_t& fr = p->fileA[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 )
|
||||||
|
_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; i<p->fileN; ++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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cw::rc_t cw::gutim::reg::test( const object_t* cfg )
|
||||||
|
{
|
||||||
|
const char* dir = nullptr;
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
handle_t h;
|
||||||
|
|
||||||
|
if((rc = cfg->getv("dir",dir)) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"The arg. parse GUTIM registry test.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rc = create(h,dir)) != kOkRC )
|
||||||
|
{
|
||||||
|
rc = cwLogError(rc,"The GUTIM registry create failed.");
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
report(h);
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
destroy(h);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
39
cwGutimReg.h
Normal file
39
cwGutimReg.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef cwGutimReg_h
|
||||||
|
#define cwGutimReg_h
|
||||||
|
|
||||||
|
namespace cw
|
||||||
|
{
|
||||||
|
namespace gutim
|
||||||
|
{
|
||||||
|
namespace reg
|
||||||
|
{
|
||||||
|
typedef handle<struct reg_str> 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 );
|
||||||
|
rc_t test( const object_t* cfg );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
42
cwIo.cpp
42
cwIo.cpp
@ -2703,6 +2703,48 @@ cw::rc_t cw::io::midiDeviceSend( handle_t h, unsigned devIdx, unsigned portIdx,
|
|||||||
return midi::device::send( p->midiH, devIdx, portIdx, status, d0, d1 );
|
return midi::device::send( p->midiH, devIdx, portIdx, status, d0, d1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::midiOpenMidiFile( handle_t h, unsigned devIdx, unsigned portIdx, const char* fname )
|
||||||
|
{
|
||||||
|
return midi::device::openMidiFile( _handleToPtr(h)->midiH, devIdx, portIdx, fname );
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::midiLoadMsgPacket( handle_t h, const midi::packet_t& pkt )
|
||||||
|
{
|
||||||
|
return midi::device::loadMsgPacket( _handleToPtr(h)->midiH, pkt );
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned cw::io::midiMsgCount( handle_t h, unsigned devIdx, unsigned portIdx )
|
||||||
|
{
|
||||||
|
return midi::device::msgCount( _handleToPtr(h)->midiH, devIdx, portIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::midiSeekToMsg( handle_t h, unsigned devIdx, unsigned portIdx, unsigned msgIdx )
|
||||||
|
{
|
||||||
|
return midi::device::seekToMsg( _handleToPtr(h)->midiH, devIdx, portIdx, msgIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::midiSetEndMsg( handle_t h, unsigned devIdx, unsigned portIdx, unsigned msgIdx )
|
||||||
|
{
|
||||||
|
return midi::device::setEndMsg( _handleToPtr(h)->midiH, devIdx, portIdx, msgIdx );
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::midiFileStart( handle_t h )
|
||||||
|
{
|
||||||
|
return midi::device::start( _handleToPtr(h)->midiH );
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::midiFileStop( handle_t h )
|
||||||
|
{
|
||||||
|
return midi::device::stop( _handleToPtr(h)->midiH );
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::io::midiFilePause( handle_t h, bool pauseFl )
|
||||||
|
{
|
||||||
|
return midi::device::pause( _handleToPtr(h)->midiH, pauseFl );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Audio
|
// Audio
|
||||||
|
9
cwIo.h
9
cwIo.h
@ -228,6 +228,15 @@ namespace cw
|
|||||||
const char* midiDevicePortName( handle_t h, unsigned devIdx, bool inputFl, unsigned portIdx );
|
const char* midiDevicePortName( handle_t h, unsigned devIdx, bool inputFl, unsigned portIdx );
|
||||||
unsigned midiDevicePortIndex( handle_t h, unsigned devIdx, bool inputFl, const char* portName );
|
unsigned midiDevicePortIndex( handle_t h, unsigned devIdx, bool inputFl, const char* portName );
|
||||||
rc_t midiDeviceSend( handle_t h, unsigned devIdx, unsigned portIdx, uint8_t status, uint8_t d0, uint8_t d1 );
|
rc_t midiDeviceSend( handle_t h, unsigned devIdx, unsigned portIdx, uint8_t status, uint8_t d0, uint8_t d1 );
|
||||||
|
|
||||||
|
rc_t midiOpenMidiFile( handle_t h, unsigned devIdx, unsigned portIdx, const char* fname );
|
||||||
|
rc_t midiLoadMsgPacket( handle_t h, const midi::packet_t& pkt ); // Note: Set devIdx/portIdx via pkt.devIdx/pkt.portIdx
|
||||||
|
unsigned midiMsgCount( handle_t h, unsigned devIdx, unsigned portIdx );
|
||||||
|
rc_t midiSeekToMsg( handle_t h, unsigned devIdx, unsigned portIdx, unsigned msgIdx );
|
||||||
|
rc_t midiSetEndMsg( handle_t h, unsigned devIdx, unsigned portidx, unsigned msgIdx );
|
||||||
|
rc_t midiFileStart( handle_t h );
|
||||||
|
rc_t midiFileStop( handle_t h );
|
||||||
|
rc_t midiFilePause( handle_t h, bool pauseFl );
|
||||||
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------------
|
//----------------------------------------------------------------------------------------------------------
|
||||||
|
@ -144,6 +144,9 @@ namespace cw
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: Consider replacing the poll() with epoll_wait2() is apparently
|
||||||
|
// optimized for more accurate time outs.
|
||||||
|
|
||||||
// Block here waiting for ALSA events or timeout when the next file msg should be sent
|
// Block here waiting for ALSA events or timeout when the next file msg should be sent
|
||||||
int sysRC = poll( p->alsaPollfdA, p->alsaPollfdN, sleep_millis );
|
int sysRC = poll( p->alsaPollfdA, p->alsaPollfdN, sleep_millis );
|
||||||
|
|
||||||
@ -511,13 +514,46 @@ cw::rc_t cw::midi::device::openMidiFile( handle_t h, unsigned devIdx, unsigned p
|
|||||||
|
|
||||||
errLabel:
|
errLabel:
|
||||||
return rc;
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cw::rc_t cw::midi::device::loadMsgPacket( handle_t h, const packet_t& pkt )
|
||||||
|
{
|
||||||
|
rc_t rc = kOkRC;
|
||||||
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
|
if( _devIdxToFileDevIdx(p,pkt.devIdx) == kInvalidIdx )
|
||||||
|
{
|
||||||
|
cwLogError(kInvalidArgRC,"The device index %i does not identify a valid file device.",pkt.devIdx);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
if((rc = load_messages( p->fileDevH, pkt.portIdx, pkt.msgArray, pkt.msgCnt)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned cw::midi::device::msgCount( handle_t h, unsigned devIdx, unsigned portIdx )
|
||||||
|
{
|
||||||
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
|
if(_devIdxToFileDevIdx(p,devIdx) == kInvalidIdx )
|
||||||
|
{
|
||||||
|
cwLogError(kInvalidArgRC,"The device index %i does not identify a valid file device.",devIdx);
|
||||||
|
goto errLabel;
|
||||||
|
}
|
||||||
|
|
||||||
|
return msg_count( p->fileDevH, portIdx);
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::seekToMsg( handle_t h, unsigned devIdx, unsigned portIdx, unsigned msgIdx )
|
cw::rc_t cw::midi::device::seekToMsg( handle_t h, unsigned devIdx, unsigned portIdx, unsigned msgIdx )
|
||||||
{
|
{
|
||||||
rc_t rc = kOkRC;
|
rc_t rc = kOkRC;
|
||||||
device_t* p = _handleToPtr(h);
|
device_t* p = _handleToPtr(h);
|
||||||
|
|
||||||
if(_devIdxToFileDevIdx(p,devIdx) == kInvalidIdx )
|
if(_devIdxToFileDevIdx(p,devIdx) == kInvalidIdx )
|
||||||
{
|
{
|
||||||
|
@ -52,6 +52,8 @@ namespace cw
|
|||||||
rc_t sendData( handle_t h, unsigned devIdx, unsigned portIdx, const uint8_t* dataPtr, unsigned byteCnt );
|
rc_t sendData( handle_t h, unsigned devIdx, unsigned portIdx, const uint8_t* dataPtr, unsigned byteCnt );
|
||||||
|
|
||||||
rc_t openMidiFile( handle_t h, unsigned devIdx, unsigned portIdx, const char* fname );
|
rc_t openMidiFile( handle_t h, unsigned devIdx, unsigned portIdx, const char* fname );
|
||||||
|
rc_t loadMsgPacket(handle_t h, const packet_t& pkt ); // Note: Set devIdx/portIdx via pkt.devIdx/pkt.portIdx
|
||||||
|
unsigned msgCount( handle_t h, unsigned devIdx, unsigned portIdx );
|
||||||
rc_t seekToMsg( handle_t h, unsigned devIdx, unsigned portIdx, unsigned msgIdx );
|
rc_t seekToMsg( handle_t h, unsigned devIdx, unsigned portIdx, unsigned msgIdx );
|
||||||
rc_t setEndMsg( handle_t h, unsigned devIdx, unsigned portidx, unsigned msgIdx );
|
rc_t setEndMsg( handle_t h, unsigned devIdx, unsigned portidx, unsigned msgIdx );
|
||||||
|
|
||||||
|
@ -716,6 +716,19 @@ errLabel:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned cw::midi::device::file_dev::msg_count( handle_t h, unsigned file_idx )
|
||||||
|
{
|
||||||
|
file_dev_t* p = _handleToPtr(h);
|
||||||
|
rc_t rc;
|
||||||
|
|
||||||
|
if((rc = _validate_file_existence(p,file_idx)) != kOkRC )
|
||||||
|
goto errLabel;
|
||||||
|
|
||||||
|
return p->msgN;
|
||||||
|
|
||||||
|
errLabel:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
cw::rc_t cw::midi::device::file_dev::seek_to_msg_index( handle_t h, unsigned file_idx, unsigned msg_idx )
|
cw::rc_t cw::midi::device::file_dev::seek_to_msg_index( handle_t h, unsigned file_idx, unsigned msg_idx )
|
||||||
{
|
{
|
||||||
|
@ -66,6 +66,8 @@ namespace cw
|
|||||||
} exec_result_t;
|
} exec_result_t;
|
||||||
|
|
||||||
|
|
||||||
|
unsigned msg_count( handle_t h, unsigned file_idx );
|
||||||
|
|
||||||
// Set the next msg to be returned.
|
// Set the next msg to be returned.
|
||||||
rc_t seek_to_msg_index( handle_t h, unsigned file_idx, unsigned msg_idx );
|
rc_t seek_to_msg_index( handle_t h, unsigned file_idx, unsigned msg_idx );
|
||||||
rc_t set_end_msg_index( handle_t h, unsigned file_idx, unsigned msg_idx );
|
rc_t set_end_msg_index( handle_t h, unsigned file_idx, unsigned msg_idx );
|
||||||
|
65
cwText.cpp
65
cwText.cpp
@ -30,23 +30,6 @@ namespace cw
|
|||||||
|
|
||||||
return eosFl ? s : nullptr;
|
return eosFl ? s : nullptr;
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
unsigned _toText( char* buf, unsigned bufN, unsigned char v )
|
|
||||||
{
|
|
||||||
if( bufN < 1 )
|
|
||||||
return 0;
|
|
||||||
buf[0] = v;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned _toText( char* buf, unsigned bufN, char v )
|
|
||||||
{
|
|
||||||
if( bufN < 1 )
|
|
||||||
return 0;
|
|
||||||
buf[0] = v;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,21 +60,43 @@ const char* cw::textCopy( char* dst, unsigned dstN, const char* src, unsigned sr
|
|||||||
return dst;
|
return dst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cw::textToLower( char* s )
|
||||||
void textToLower( char* s )
|
|
||||||
{
|
{
|
||||||
if( s != nullptr )
|
if( s != nullptr )
|
||||||
for(; *s; ++s)
|
for(; *s; ++s)
|
||||||
*s = std::tolower(*s);
|
*s = std::tolower(*s);
|
||||||
}
|
}
|
||||||
|
|
||||||
void textToUpper( char* s )
|
void cw::textToUpper( char* s )
|
||||||
{
|
{
|
||||||
if( s != nullptr )
|
if( s != nullptr )
|
||||||
for(; *s; ++s)
|
for(; *s; ++s)
|
||||||
*s = std::toupper(*s);
|
*s = std::toupper(*s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cw::textToLower( char* dst, const char* src, unsigned dstN )
|
||||||
|
{
|
||||||
|
if( src != nullptr && dstN>0 )
|
||||||
|
{
|
||||||
|
unsigned sn = std::min(dstN,textLength(src)+1);
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<sn; ++i)
|
||||||
|
dst[i] = std::tolower( src[i] );
|
||||||
|
dst[i-1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void cw::textToUpper( char* dst, const char* src, unsigned dstN )
|
||||||
|
{
|
||||||
|
if( src != nullptr && dstN>0 )
|
||||||
|
{
|
||||||
|
unsigned sn = std::min(dstN,textLength(src)+1);
|
||||||
|
unsigned i;
|
||||||
|
for(i=0; i<sn; ++i)
|
||||||
|
dst[i] = std::toupper( src[i] );
|
||||||
|
dst[i-1] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int cw::textCompare( const char* s0, const char* s1 )
|
int cw::textCompare( const char* s0, const char* s1 )
|
||||||
{
|
{
|
||||||
@ -109,6 +114,26 @@ int cw::textCompare( const char* s0, const char* s1, unsigned n)
|
|||||||
return strncmp(s0,s1,n);
|
return strncmp(s0,s1,n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cw::textCompareI( const char* s0, const char* s1 )
|
||||||
|
{
|
||||||
|
char b0N = textLength(s0)+1;
|
||||||
|
char b1N = textLength(s1)+1;
|
||||||
|
char b0[ b0N ];
|
||||||
|
char b1[ b1N ];
|
||||||
|
textToLower(b0,s0,b0N);
|
||||||
|
textToLower(b1,s1,b1N);
|
||||||
|
return textCompare(b0,b1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int cw::textCompareI( const char* s0, const char* s1, unsigned n )
|
||||||
|
{
|
||||||
|
char b0[ n+1 ];
|
||||||
|
char b1[ n+1 ];
|
||||||
|
textToLower(b0,s0,n+1);
|
||||||
|
textToLower(b1,s1,n+1);
|
||||||
|
return textCompare(b0,b1,n);
|
||||||
|
}
|
||||||
|
|
||||||
const char* cw::nextWhiteChar( const char* s )
|
const char* cw::nextWhiteChar( const char* s )
|
||||||
{ return _nextWhiteChar(s,false); }
|
{ return _nextWhiteChar(s,false); }
|
||||||
|
|
||||||
|
21
cwText.h
21
cwText.h
@ -16,16 +16,33 @@ namespace cw
|
|||||||
|
|
||||||
void textToLower( char* s );
|
void textToLower( char* s );
|
||||||
void textToUpper( char* s );
|
void textToUpper( char* s );
|
||||||
|
|
||||||
|
void textToLower( char* dst, const char* src, unsigned dstN );
|
||||||
|
void textToUpper( char* dst, const char* src, unsigned dstN );
|
||||||
|
|
||||||
// Note: if both s0 and s1 are nullptr then a match is indicated
|
// Note: if both s0 and s1 are nullptr then a match is indicated
|
||||||
int textCompare( const char* s0, const char* s1 );
|
int textCompare( const char* s0, const char* s1 );
|
||||||
int textCompare( const char* s0, const char* s1, unsigned n);
|
int textCompare( const char* s0, const char* s1, unsigned n);
|
||||||
|
|
||||||
|
// Case insensitive compare
|
||||||
|
int textCompareI( const char* s0, const char* s1 );
|
||||||
|
int textCompareI( const char* s0, const char* s1, unsigned n);
|
||||||
|
|
||||||
inline bool textIsEqual( const char* s0, const char* s1 ) { return textCompare(s0,s1) == 0; }
|
inline bool textIsEqual( const char* s0, const char* s1 ) { return textCompare(s0,s1) == 0; }
|
||||||
inline bool textIsEqual( const char* s0, const char* s1, unsigned n ) { return textCompare(s0,s1,n) == 0; }
|
inline bool textIsEqual( const char* s0, const char* s1, unsigned n ) { return textCompare(s0,s1,n) == 0; }
|
||||||
|
|
||||||
|
// Case insensitive is-equal
|
||||||
|
inline bool textIsEqualI( const char* s0, const char* s1 ) { return textCompareI(s0,s1) == 0; }
|
||||||
|
inline bool textIsEqualI( const char* s0, const char* s1, unsigned n ) { return textCompareI(s0,s1,n) == 0; }
|
||||||
|
|
||||||
inline bool textIsNotEqual( const char* s0, const char* s1 ) { return !textIsEqual(s0,s1); }
|
inline bool textIsNotEqual( const char* s0, const char* s1 ) { return !textIsEqual(s0,s1); }
|
||||||
inline bool textIsNotEqual( const char* s0, const char* s1, unsigned n ) { return !textIsEqual(s0,s1,n); }
|
inline bool textIsNotEqual( const char* s0, const char* s1, unsigned n ) { return !textIsEqual(s0,s1,n); }
|
||||||
|
|
||||||
|
// Case insensitive is-not-equal
|
||||||
|
inline bool textIsNotEqualI( const char* s0, const char* s1 ) { return !textIsEqualI(s0,s1); }
|
||||||
|
inline bool textIsNotEqualI( const char* s0, const char* s1, unsigned n ) { return !textIsEqualI(s0,s1,n); }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Return a pointer to the next white space char
|
// Return a pointer to the next white space char
|
||||||
// or nullptr if 's' is null are there are no whitespace char's.
|
// or nullptr if 's' is null are there are no whitespace char's.
|
||||||
|
Loading…
Reference in New Issue
Block a user