From 733080691399dec6c362ca6af93636dff1b25f14 Mon Sep 17 00:00:00 2001 From: kevin Date: Sun, 19 Nov 2023 14:06:37 -0500 Subject: [PATCH] cwIoMidiRecordPlay.h/cpp : am_to_midi_file() now write a CSV equivalent to the .mid file and a meta file containing the beg/end loc of the MIDI file. --- cwIoMidiRecordPlay.cpp | 126 +++++++++++++++++++++++++++++------------ cwIoMidiRecordPlay.h | 11 ++-- 2 files changed, 94 insertions(+), 43 deletions(-) diff --git a/cwIoMidiRecordPlay.cpp b/cwIoMidiRecordPlay.cpp index 3ea399c..aa57b0c 100644 --- a/cwIoMidiRecordPlay.cpp +++ b/cwIoMidiRecordPlay.cpp @@ -824,19 +824,19 @@ namespace cw } // if the output msg array was not allocated - then allocate it here - if( msgArrayCntRef == 0 || msgArrayRef == nullptr ) - { - alloc_fl = true; - msgArrayRef = mem::allocZ(recordN); - } - else // if the msg array was allocated but is too small - then decrease the count of records to be read from the file - { - if( recordN > msgArrayCntRef ) - { - cwLogWarning("The count of message in Audio-MIDI file '%s' reduced from %i to %i.", fn, recordN, msgArrayCntRef ); - recordN = msgArrayCntRef; - } - } + if( msgArrayCntRef == 0 || msgArrayRef == nullptr ) + { + alloc_fl = true; + msgArrayRef = mem::allocZ(recordN); + } + else // if the msg array was allocated but is too small - then decrease the count of records to be read from the file + { + if( recordN > msgArrayCntRef ) + { + cwLogWarning("The count of message in Audio-MIDI file '%s' reduced from %i to %i.", fn, recordN, msgArrayCntRef ); + recordN = msgArrayCntRef; + } + } if( version == 0 ) { @@ -978,17 +978,11 @@ namespace cw return rc; } - rc_t _write_csv( midi_record_play_t* p, const char* fn ) + rc_t _write_msgs_to_csv( const char* fn, const am_midi_msg_t* msgArray, unsigned msgArrayCnt ) { - rc_t rc = kOkRC; + rc_t rc = kOkRC; file::handle_t fH; - if( p->iMsgArrayInIdx == 0 ) - { - cwLogWarning("Nothing to write."); - return rc; - } - // open the file if((rc = file::open(fH,fn,file::kWriteFl)) != kOkRC ) { @@ -998,11 +992,11 @@ namespace cw file::printf(fH,"dev,port,microsec,id,sec,ch,status,sci_pitch,d0,d1\n"); - for(unsigned i=0; iiMsgArrayInIdx; ++i) + for(unsigned i=0; iiMsgArray + i; + const am_midi_msg_t* m = msgArray + i; - double secs = time::elapsedSecs( p->iMsgArray[0].timestamp, p->iMsgArray[i].timestamp ); + double secs = time::elapsedSecs( msgArray[0].timestamp, msgArray[i].timestamp ); char sciPitch[ midi::kMidiSciPitchCharCnt + 1 ]; if( m->status == midi::kNoteOnMdId ) @@ -1022,8 +1016,29 @@ namespace cw errLabel: file::close(fH); - cwLogInfo("Saved %i events to '%s'.", p->iMsgArrayInIdx, fn ); + return rc; + + } + rc_t _write_csv( midi_record_play_t* p, const char* fn ) + { + rc_t rc = kOkRC; + + if( p->iMsgArrayInIdx == 0 ) + { + cwLogWarning("Nothing to write."); + return rc; + } + + if((rc = _write_msgs_to_csv( fn, p->iMsgArray, p->iMsgArrayInIdx )) != kOkRC ) + goto errLabel; + + cwLogInfo("Saved %i events to '%s'.", p->iMsgArrayInIdx, fn ); + + errLabel: + if(rc != kOkRC ) + rc = cwLogError(rc,"Write to '%s' failed.", fn ); + return rc; } @@ -1084,6 +1099,28 @@ namespace cw } + rc_t _write_midi_meta_file(const char* meta_fn, unsigned beg_loc, unsigned end_loc) + { + rc_t rc = kOkRC; + const unsigned bufCharN = 256; + char buf[ bufCharN+1 ]; + int bN; + + if((bN = snprintf(buf,bufCharN,"{ begLoc:%i, endLoc:%i }",beg_loc,end_loc)) == 0) + { + rc = cwLogError(kOpFailRC,"The meta data buffer formation failed."); + goto errLabel; + } + + if((rc = file::fnWrite(meta_fn,buf,bN)) != kOkRC ) + goto errLabel; + + errLabel: + if( rc != kOkRC ) + rc = cwLogError(rc,"MIDI meta file write failed on '%s'.",cwStringNullGuard(meta_fn)); + + return rc; + } rc_t _midi_file_write( const char* fn, const am_midi_msg_t* msgArray, unsigned msgArrayCnt ) { @@ -1926,7 +1963,7 @@ void cw::midi_record_play::half_pedal_params( handle_t h, unsigned noteDelayMs, } -cw::rc_t cw::midi_record_play::am_to_midi_file( const char* am_filename, const char* midi_filename ) +cw::rc_t cw::midi_record_play::am_to_midi_file( const char* am_filename, const char* midi_filename, const char* csv_filename ) { rc_t rc = kOkRC; unsigned msgArrayCnt = 0; @@ -1944,11 +1981,19 @@ cw::rc_t cw::midi_record_play::am_to_midi_file( const char* am_filename, const c goto errLabel; } - if((rc = _midi_file_write( midi_filename, msgArray, msgArrayCnt )) != kOkRC ) - { - rc = cwLogError(rc,"Unable to write AM file '%s' to '%s'.", cwStringNullGuard(am_filename),cwStringNullGuard(midi_filename)); - goto errLabel; - } + if( midi_filename != nullptr ) + if((rc = _midi_file_write( midi_filename, msgArray, msgArrayCnt )) != kOkRC ) + { + rc = cwLogError(rc,"Unable to write AM file '%s' to '%s'.", cwStringNullGuard(am_filename),cwStringNullGuard(midi_filename)); + goto errLabel; + } + + if( csv_filename != nullptr ) + if((rc = _write_msgs_to_csv( csv_filename, msgArray, msgArrayCnt )) != kOkRC ) + { + rc = cwLogError(rc,"Unable to write AM file '%s' to '%s'.", cwStringNullGuard(am_filename),cwStringNullGuard(csv_filename)); + goto errLabel; + } errLabel: mem::release(msgArray); @@ -1957,7 +2002,7 @@ cw::rc_t cw::midi_record_play::am_to_midi_file( const char* am_filename, const c } -cw::rc_t cw::midi_record_play::am_to_midi_dir( const char* inDir ) +cw::rc_t cw::midi_record_play::am_to_midi_dir( const char* inDir, unsigned beg_loc, unsigned end_loc ) { rc_t rc = kOkRC; filesys::dirEntry_t* dirEntryArray = nullptr; @@ -1969,11 +2014,17 @@ cw::rc_t cw::midi_record_play::am_to_midi_dir( const char* inDir ) for(unsigned i=0; igetv("inDir",inDir)) != kOkRC ) + if((rc = cfg->getv("inDir",inDir,"beg_loc",beg_loc,"end_loc",end_loc)) != kOkRC ) { rc = cwLogError(rc,"AM to MIDI file: Unable to parse input arg's."); goto errLabel; } // - if((rc = am_to_midi_dir(inDir)) != kOkRC ) + if((rc = am_to_midi_dir(inDir,beg_loc,end_loc)) != kOkRC ) { rc = cwLogError(rc,"AM to MIDI file conversion on directory:'%s' failed.", cwStringNullGuard(inDir)); goto errLabel; diff --git a/cwIoMidiRecordPlay.h b/cwIoMidiRecordPlay.h index df4bb54..4d4b175 100644 --- a/cwIoMidiRecordPlay.h +++ b/cwIoMidiRecordPlay.h @@ -79,14 +79,11 @@ namespace cw unsigned event_loc( handle_t h ); // play mode: loc of next event to play record mode:kInvalidId unsigned last_store_index( handle_t h ); - rc_t exec( handle_t h, const io::msg_t& msg ); unsigned label_to_device_index( handle_t h, const char* devLabel ); const char* device_index_to_label( handle_t h, unsigned devIdx ); - - unsigned device_count( handle_t h ); bool is_device_enabled( handle_t h, unsigned devIdx ); @@ -95,10 +92,10 @@ namespace cw void half_pedal_params( handle_t h, unsigned noteDelayMs, unsigned pitch, unsigned vel, unsigned pedal_vel, unsigned noteDurMs, unsigned downDelayMs ); - // Convert an audio-midi file to a MIDI file - rc_t am_to_midi_file( const char* am_filename, const char* midi_filename ); - rc_t am_to_midi_dir( const char* inDir ); - rc_t am_to_midi_file( const object_t* cfg ); + // Convert an audio-midi file to a MIDI file and/or a CSV file + rc_t am_to_midi_file( const char* am_filename, const char* midi_filename = nullptr, const char* csv_filename = nullptr ); + rc_t am_to_midi_dir( const char* inDir, unsigned beg_loc, unsigned end_loc ); + rc_t am_to_midi_file( const object_t* cfg ); // See main.cfg: 'am_to_midi_file' unsigned dev_count( handle_t h );