cwIoMidiRecordPlay.h/cpp : Added last_store_index() and save_synced_csv()
This commit is contained in:
parent
abcaa093c7
commit
440c35201a
@ -12,6 +12,7 @@
|
||||
#include "cwMidiFile.h"
|
||||
#include "cwUiDecls.h"
|
||||
#include "cwIo.h"
|
||||
#include "cwScoreFollowerPerf.h"
|
||||
#include "cwIoMidiRecordPlay.h"
|
||||
#include "cwMidiState.h"
|
||||
#include "cwSvgMidi.h"
|
||||
@ -119,6 +120,7 @@ namespace cw
|
||||
unsigned iMsgArrayN; // Count of messages allocated in msgArray.
|
||||
unsigned iMsgArrayInIdx; // Next available space for incoming MIDI messages (also the current count of msgs in msgArray[])
|
||||
|
||||
unsigned lastStoreIndex;
|
||||
|
||||
midi_device_t* midiDevA;
|
||||
unsigned midiDevN;
|
||||
@ -372,6 +374,7 @@ namespace cw
|
||||
}
|
||||
|
||||
p->iMsgArrayN = p->msgArrayN;
|
||||
p->lastStoreIndex = kInvalidIdx;
|
||||
|
||||
if( midiDevL->child_count() > 0 )
|
||||
{
|
||||
@ -487,11 +490,15 @@ namespace cw
|
||||
//if( !midi::isPedal(status,d0) )
|
||||
// printf("MIDI store: %i : ch:%i st:%i d0:%i d1:%i\n",p->iMsgArrayInIdx,ch,status,d0,d1);
|
||||
|
||||
p->lastStoreIndex = kInvalidIdx;
|
||||
|
||||
// verify that space exists in the record buffer
|
||||
if( p->iMsgArrayInIdx < p->iMsgArrayN )
|
||||
{
|
||||
// MAKE THIS ATOMIC
|
||||
unsigned id = p->iMsgArrayInIdx;
|
||||
p->lastStoreIndex = p->iMsgArrayInIdx;
|
||||
|
||||
++p->iMsgArrayInIdx;
|
||||
|
||||
am = p->iMsgArray + id;
|
||||
@ -708,6 +715,8 @@ namespace cw
|
||||
void _set_midi_msg_next_index( midi_record_play_t* p, unsigned next_idx )
|
||||
{
|
||||
p->iMsgArrayInIdx = next_idx;
|
||||
if( next_idx == 0 )
|
||||
p->lastStoreIndex = kInvalidIdx;
|
||||
}
|
||||
|
||||
// Set the next index of the next MIDI message to transmit
|
||||
@ -1006,6 +1015,62 @@ namespace cw
|
||||
}
|
||||
}
|
||||
|
||||
errLabel:
|
||||
file::close(fH);
|
||||
|
||||
cwLogInfo("Saved %i events to '%s'.", p->iMsgArrayInIdx, fn );
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _write_sync_csv( midi_record_play_t* p, const char* fn )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
rc = cwLogError(kOpenFailRC,"Unable to create the file '%s'.",cwStringNullGuard(fn));
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// write the header line
|
||||
file::printf(fH,"meas,index,voice,loc,tick,sec,dur,rval,dots,sci_pitch,dmark,dlevel,status,d0,d1,bar,section,bpm,grace,pedal\n");
|
||||
|
||||
for(unsigned i=0; i<p->iMsgArrayInIdx; ++i)
|
||||
{
|
||||
const am_midi_msg_t* m = p->iMsgArray + i;
|
||||
|
||||
double secs = time::elapsedSecs( p->iMsgArray[0].timestamp, p->iMsgArray[i].timestamp );
|
||||
|
||||
// write the event line
|
||||
if( midi::isNoteOn(m->status,m->d1) )
|
||||
{
|
||||
char sciPitch[ midi::kMidiSciPitchCharCnt + 1 ];
|
||||
unsigned bar = 0;
|
||||
midi::midiToSciPitch( m->d0, sciPitch, midi::kMidiSciPitchCharCnt );
|
||||
rc = file::printf(fH, "%i,%i,%i,%i,0,%f,0.0,0.0,0,%s,,,%i,%i,%i,,,,,\n",
|
||||
bar,i,1,m->loc,secs,sciPitch,m->status,m->d0,m->d1);
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = file::printf(fH, ",%i,,,%i,%f,,,,,,,%i,%i,%i,,,,,\n",i,0,secs,m->status,m->d0,m->d1);
|
||||
}
|
||||
|
||||
if( rc != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Write failed on line:%i", i+1 );
|
||||
goto errLabel;
|
||||
}
|
||||
}
|
||||
|
||||
errLabel:
|
||||
file::close(fH);
|
||||
|
||||
@ -1015,6 +1080,7 @@ namespace cw
|
||||
|
||||
}
|
||||
|
||||
|
||||
rc_t _midi_file_write( const char* fn, const am_midi_msg_t* msgArray, unsigned msgArrayCnt )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
@ -1245,6 +1311,8 @@ namespace cw
|
||||
|
||||
if( midi::isChStatus(mm->status) )
|
||||
{
|
||||
//printf("R:%i %i %i\n",mm->status, mm->d0, mm->d1);
|
||||
|
||||
const am_midi_msg_t* am = _midi_store( p, pkt->devIdx, pkt->portIdx, mm->timeStamp, mm->status & 0x0f, mm->status & 0xf0, mm->d0, mm->d1 );
|
||||
|
||||
if( p->thruFl && am != nullptr )
|
||||
@ -1636,6 +1704,46 @@ cw::rc_t cw::midi_record_play::save_csv( handle_t h, const char* fn )
|
||||
return _write_csv(p,fn);
|
||||
}
|
||||
|
||||
cw::rc_t cw::midi_record_play::save_synced_csv( handle_t h, const char* fn, const score_follower::ssf_note_on_t* syncA, unsigned syncN )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
midi_record_play_t* p = _handleToPtr(h);
|
||||
|
||||
for(unsigned i=0; i<p->iMsgArrayInIdx; ++i)
|
||||
{
|
||||
const am_midi_msg_t* m = p->iMsgArray + i;
|
||||
|
||||
if( midi::isNoteOn(m->status,m->d1) )
|
||||
{
|
||||
for(unsigned j=0; j<syncN; ++j)
|
||||
if( syncA[j].muid == p->iMsgArray[i].id )
|
||||
{
|
||||
if( p->iMsgArray[i].d0 != syncA[j].pitch )
|
||||
{
|
||||
rc = cwLogError(kInvalidStateRC,"MIDI sync failed. Pitch mismatch. i:%i j:%i : %i %i",i,j, p->iMsgArray[i].d0 != syncA[j].pitch);
|
||||
//goto errLabel;
|
||||
continue;
|
||||
}
|
||||
|
||||
p->iMsgArray[i].loc = syncA[j].loc;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if((rc = _write_sync_csv( p, fn )) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"MIDI sync'd CSV write failed.");
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
cw::rc_t cw::midi_record_play::write_svg( handle_t h, const char* fn )
|
||||
{
|
||||
rc_t rc;
|
||||
@ -1786,6 +1894,12 @@ unsigned cw::midi_record_play::event_index( handle_t h )
|
||||
return p->recordFl ? p->iMsgArrayInIdx : p->msgArrayOutIdx;
|
||||
}
|
||||
|
||||
unsigned cw::midi_record_play::last_store_index( handle_t h )
|
||||
{
|
||||
midi_record_play_t* p = _handleToPtr(h);
|
||||
return p->recordFl ? p->lastStoreIndex : kInvalidIdx;
|
||||
}
|
||||
|
||||
unsigned cw::midi_record_play::event_loc( handle_t h )
|
||||
{
|
||||
midi_record_play_t* p = _handleToPtr(h);
|
||||
|
@ -61,6 +61,8 @@ namespace cw
|
||||
|
||||
rc_t save( handle_t h, const char* fn );
|
||||
rc_t save_csv( handle_t h, const char* fn );
|
||||
rc_t save_synced_csv( handle_t h, const char* fn, const score_follower::ssf_note_on_t* syncA, unsigned syncN );
|
||||
|
||||
rc_t write_svg( handle_t h, const char* fn );
|
||||
|
||||
rc_t open( handle_t h, const char* fn );
|
||||
@ -76,6 +78,9 @@ namespace cw
|
||||
unsigned event_index( handle_t h ); // record mode: index of next event to store play mode:index of next event to play
|
||||
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 device_count( handle_t h );
|
||||
|
Loading…
Reference in New Issue
Block a user