Merge branch 'master' of klarke.webfactional.com:webapps/git/repos/libcm
This commit is contained in:
commit
a3ce46c35b
@ -635,9 +635,9 @@ cmTlRC_t _cmTlProcMidiFile( _cmTl_t* p, _cmTlObj_t* op, cmMidiFileH_t mfH )
|
|||||||
unsigned mn = cmMidiFileMsgCount(mfH);
|
unsigned mn = cmMidiFileMsgCount(mfH);
|
||||||
const cmMidiTrackMsg_t** mapp = cmMidiFileMsgArray(mfH);
|
const cmMidiTrackMsg_t** mapp = cmMidiFileMsgArray(mfH);
|
||||||
unsigned mi = 0;
|
unsigned mi = 0;
|
||||||
double accum = 0;
|
//double accum = 0;
|
||||||
_cmTlObj_t* refOp = op;
|
_cmTlObj_t* refOp = op;
|
||||||
bool fl = false;
|
//bool fl = false;
|
||||||
unsigned dtick = 0;
|
unsigned dtick = 0;
|
||||||
mfp->noteOnCnt = 0;
|
mfp->noteOnCnt = 0;
|
||||||
|
|
||||||
@ -649,16 +649,16 @@ cmTlRC_t _cmTlProcMidiFile( _cmTl_t* p, _cmTlObj_t* op, cmMidiFileH_t mfH )
|
|||||||
|
|
||||||
dtick = mp->dtick;
|
dtick = mp->dtick;
|
||||||
|
|
||||||
if( fl )
|
//if( fl )
|
||||||
{
|
//{
|
||||||
dtick = 0;
|
// dtick = 0;
|
||||||
fl = mp->dtick == 0;
|
// fl = mp->dtick == 0;
|
||||||
}
|
//}
|
||||||
|
|
||||||
accum += dtick * p->srate / 1000000;
|
//accum += dtick * p->srate / 1000000;
|
||||||
|
|
||||||
//int begSmpIdx = floor(accum_micros * p->srate / 1000000);
|
//int begSmpIdx = floor(accum_micros * p->srate / 1000000);
|
||||||
int begSmpIdx = floor( dtick * p->srate / 1000000 );
|
int begSmpIdx = dtick; //floor( dtick * p->srate / 1000000.0 );
|
||||||
int durSmpCnt = 0;
|
int durSmpCnt = 0;
|
||||||
unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp );
|
unsigned midiTrkMsgByteCnt = cmMidiFilePackTrackMsgBufByteCount( mp );
|
||||||
unsigned recdByteCnt = sizeof(cmTlMidiEvt_t) + midiTrkMsgByteCnt;
|
unsigned recdByteCnt = sizeof(cmTlMidiEvt_t) + midiTrkMsgByteCnt;
|
||||||
@ -669,7 +669,8 @@ cmTlRC_t _cmTlProcMidiFile( _cmTl_t* p, _cmTlObj_t* op, cmMidiFileH_t mfH )
|
|||||||
// count the note-on messages
|
// count the note-on messages
|
||||||
if( mp->status == kNoteOnMdId )
|
if( mp->status == kNoteOnMdId )
|
||||||
{
|
{
|
||||||
durSmpCnt = floor(mp->u.chMsgPtr->durTicks * p->srate / 1000000 );
|
//durSmpCnt = floor(mp->u.chMsgPtr->durTicks * p->srate / 1000000.0 );
|
||||||
|
durSmpCnt = mp->u.chMsgPtr->durTicks;
|
||||||
++mfp->noteOnCnt;
|
++mfp->noteOnCnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -727,7 +728,7 @@ cmTlRC_t _cmTlAllocMidiFileRecd( _cmTl_t* p, const cmChar_t* nameStr, const cmCh
|
|||||||
unsigned durSmpCnt = floor(cmMidiFileDurSecs(mfH)*p->srate);
|
unsigned durSmpCnt = floor(cmMidiFileDurSecs(mfH)*p->srate);
|
||||||
|
|
||||||
// convert the midi file from ticks to microseconds
|
// convert the midi file from ticks to microseconds
|
||||||
cmMidiFileTickToMicros(mfH);
|
cmMidiFileTickToSamples(mfH,p->srate,false);
|
||||||
|
|
||||||
// assign note durations to all note-on msg's
|
// assign note durations to all note-on msg's
|
||||||
cmMidiFileCalcNoteDurations(mfH);
|
cmMidiFileCalcNoteDurations(mfH);
|
||||||
@ -957,6 +958,11 @@ double cmTimeLineSampleRate( cmTlH_t h )
|
|||||||
return p->srate;
|
return p->srate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmTimeLineSeqToLocalSampleIndex( int seqSmpIdx, cmTlObj_t* localObjPtr )
|
||||||
|
{
|
||||||
|
return seqSmpIdx - localObjPtr->seqSmpIdx;
|
||||||
|
}
|
||||||
|
|
||||||
cmTlObj_t* _cmTimeLineIdToObj( _cmTl_t* p, unsigned seqId, unsigned id )
|
cmTlObj_t* _cmTimeLineIdToObj( _cmTl_t* p, unsigned seqId, unsigned id )
|
||||||
{
|
{
|
||||||
assert( seqId < p->seqCnt );
|
assert( seqId < p->seqCnt );
|
||||||
|
@ -111,6 +111,9 @@ extern "C" {
|
|||||||
bool cmTimeLineIsValid( cmTlH_t h );
|
bool cmTimeLineIsValid( cmTlH_t h );
|
||||||
double cmTimeLineSampleRate( cmTlH_t h );
|
double cmTimeLineSampleRate( cmTlH_t h );
|
||||||
|
|
||||||
|
// Convert global (sequence) time to a time relative to an object.
|
||||||
|
int cmTimeLineSeqToLocalSampleIndex( int seqSmpIdx, cmTlObj_t* localObjPtr );
|
||||||
|
|
||||||
// Given cmTlObj_t.uid return a pointer to the associated record.
|
// Given cmTlObj_t.uid return a pointer to the associated record.
|
||||||
// seqId is optional (dflt:cmInvalidId)
|
// seqId is optional (dflt:cmInvalidId)
|
||||||
cmTlObj_t* cmTimeLineIdToObj( cmTlH_t h, unsigned seqId, unsigned uid );
|
cmTlObj_t* cmTimeLineIdToObj( cmTlH_t h, unsigned seqId, unsigned uid );
|
||||||
@ -152,6 +155,12 @@ extern "C" {
|
|||||||
cmTlMidiFile_t* cmTimeLineFindMidiFile( cmTlH_t h, const cmChar_t* fn );
|
cmTlMidiFile_t* cmTimeLineFindMidiFile( cmTlH_t h, const cmChar_t* fn );
|
||||||
|
|
||||||
|
|
||||||
|
cmTlAudioFile_t* cmTimeLineAudioFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
||||||
|
cmTlMidiFile_t* cmTimeLineMidiFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
||||||
|
cmTlMidiEvt_t* cmTimeLineMidiEvtAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
||||||
|
cmTlMarker_t* cmTimeLineMarkerAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
||||||
|
|
||||||
|
|
||||||
cmTlAudioFile_t* cmTimeLineAudioFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
cmTlAudioFile_t* cmTimeLineAudioFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
||||||
cmTlMidiFile_t* cmTimeLineMidiFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
cmTlMidiFile_t* cmTimeLineMidiFileAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
||||||
cmTlMidiEvt_t* cmTimeLineMidiEvtAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
cmTlMidiEvt_t* cmTimeLineMidiEvtAtTime( cmTlH_t h, unsigned seqId, unsigned seqSmpIdx );
|
||||||
|
28
cmGrPlot.c
28
cmGrPlot.c
@ -217,22 +217,32 @@ void _cmGrPlotObjSetFocus( cmGrPlotObj_t* op )
|
|||||||
if( cmIsNotFlag(op->cfgFlags,kNoFocusGrPlFl) && cmIsNotFlag(op->cfgFlags,kNoDrawGrPlFl) )
|
if( cmIsNotFlag(op->cfgFlags,kNoFocusGrPlFl) && cmIsNotFlag(op->cfgFlags,kNoDrawGrPlFl) )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if( op != NULL )
|
// if the focus is changing to a new object
|
||||||
|
if( op != NULL && op->p->fop != op )
|
||||||
{
|
{
|
||||||
if( op->p->fop != NULL )
|
if( op->p->fop != NULL )
|
||||||
{
|
{
|
||||||
// if the application callback returns false then do no release focus from the current object
|
// if the application callback returns false then do no release focus from the current object
|
||||||
if(_cmGrPlotObjCb(op->p->fop, kStateChangeGrPlId, kFocusGrPlFl ) == false )
|
if(_cmGrPlotObjCb(op->p->fop, kPreEventCbSelGrPlId, kFocusGrPlFl ) == false )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
cmGrPlotObj_t* fop = op->p->fop;
|
||||||
|
|
||||||
op->p->fop = NULL;
|
op->p->fop = NULL;
|
||||||
|
|
||||||
|
// notify focus loser
|
||||||
|
_cmGrPlotObjCb(fop, kStateChangeGrPlId, kFocusGrPlFl );
|
||||||
}
|
}
|
||||||
|
|
||||||
// if the application callback returns false then do not give focus to the selected object
|
// if the application callback returns false then do not give focus to the selected object
|
||||||
if(_cmGrPlotObjCb(op, kStateChangeGrPlId, kFocusGrPlFl ) == false )
|
if(_cmGrPlotObjCb(op, kPreEventCbSelGrPlId, kFocusGrPlFl ) == false )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
op->p->fop = op;
|
op->p->fop = op;
|
||||||
|
|
||||||
|
// notify focus winner
|
||||||
|
_cmGrPlotObjCb(op, kStateChangeGrPlId, kFocusGrPlFl );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -246,7 +256,7 @@ void _cmGrPlotObjSetSelect( cmGrPlotObj_t* op, bool clearFl )
|
|||||||
unsigned stateFlags = op->stateFlags;
|
unsigned stateFlags = op->stateFlags;
|
||||||
|
|
||||||
// if the application callback returns false then do change the select state of the object
|
// if the application callback returns false then do change the select state of the object
|
||||||
if(_cmGrPlotObjCb(op, kStateChangeGrPlId, kSelectGrPlFl ) == false )
|
if(_cmGrPlotObjCb(op, kPreEventCbSelGrPlId, kSelectGrPlFl ) == false )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( clearFl )
|
if( clearFl )
|
||||||
@ -262,6 +272,8 @@ void _cmGrPlotObjSetSelect( cmGrPlotObj_t* op, bool clearFl )
|
|||||||
|
|
||||||
op->stateFlags = cmTogFlag(stateFlags,kSelectGrPlFl);
|
op->stateFlags = cmTogFlag(stateFlags,kSelectGrPlFl);
|
||||||
|
|
||||||
|
// notify state change
|
||||||
|
_cmGrPlotObjCb(op, kStateChangeGrPlId, kSelectGrPlFl );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -914,18 +926,22 @@ void cmGrPlotObjSetStateFlags( cmGrPlObjH_t oh, unsigned flags )
|
|||||||
|
|
||||||
if( cmIsFlag(flags,kVisibleGrPlFl) != _cmGrPlotObjIsVisible(op) )
|
if( cmIsFlag(flags,kVisibleGrPlFl) != _cmGrPlotObjIsVisible(op) )
|
||||||
{
|
{
|
||||||
if( _cmGrPlotObjCb(op, kStateChangeGrPlId, kVisibleGrPlFl ) == false )
|
if( _cmGrPlotObjCb(op, kPreEventCbSelGrPlId, kVisibleGrPlFl ) == false )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
op->cfgFlags = cmTogFlag(op->cfgFlags,kNoDrawGrPlFl);
|
op->cfgFlags = cmTogFlag(op->cfgFlags,kNoDrawGrPlFl);
|
||||||
|
|
||||||
|
_cmGrPlotObjCb(op, kStateChangeGrPlId, kVisibleGrPlFl );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( cmIsFlag(flags,kEnabledGrPlFl) != _cmGrPlotObjIsEnabled(op) )
|
if( cmIsFlag(flags,kEnabledGrPlFl) != _cmGrPlotObjIsEnabled(op) )
|
||||||
{
|
{
|
||||||
if( _cmGrPlotObjCb(op, kStateChangeGrPlId, kEnabledGrPlFl ) == false )
|
if( _cmGrPlotObjCb(op, kPreEventCbSelGrPlId, kEnabledGrPlFl ) == false )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
op->stateFlags = cmTogFlag(op->cfgFlags,kEnabledGrPlFl);
|
op->stateFlags = cmTogFlag(op->cfgFlags,kEnabledGrPlFl);
|
||||||
|
|
||||||
|
_cmGrPlotObjCb(op, kStateChangeGrPlId, kEnabledGrPlFl );
|
||||||
}
|
}
|
||||||
|
|
||||||
bool fl;
|
bool fl;
|
||||||
|
24
cmMidiFile.c
24
cmMidiFile.c
@ -796,6 +796,30 @@ void cmMidiFileTickToMicros( cmMidiFileH_t h )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cmMidiFileTickToSamples( cmMidiFileH_t h, double srate, bool absFl )
|
||||||
|
{
|
||||||
|
_cmMidiFile_t* p;
|
||||||
|
unsigned mi;
|
||||||
|
//bool fl = true;
|
||||||
|
|
||||||
|
if((p = _cmMidiFileHandleToPtr(h)) == NULL )
|
||||||
|
return;
|
||||||
|
|
||||||
|
cmMidiFileTickToMicros(h);
|
||||||
|
|
||||||
|
unsigned absSmp = 0;
|
||||||
|
|
||||||
|
for(mi=0; mi<p->msgN; ++mi)
|
||||||
|
{
|
||||||
|
cmMidiTrackMsg_t* mp = p->msgV[mi];
|
||||||
|
unsigned delta = floor((mp->dtick*srate)/1000000.0);
|
||||||
|
|
||||||
|
mp->dtick = absFl ? absSmp : delta;
|
||||||
|
|
||||||
|
absSmp += delta;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct _cmMidiVoice_str
|
typedef struct _cmMidiVoice_str
|
||||||
{
|
{
|
||||||
const cmMidiTrackMsg_t* mp;
|
const cmMidiTrackMsg_t* mp;
|
||||||
|
278
cmMidiFile.h
278
cmMidiFile.h
@ -5,168 +5,172 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// MIDI file timing:
|
// MIDI file timing:
|
||||||
// Messages in the MIDI file are time tagged with a delta offset in 'ticks'
|
// Messages in the MIDI file are time tagged with a delta offset in 'ticks'
|
||||||
// from the previous message in the same track.
|
// from the previous message in the same track.
|
||||||
//
|
//
|
||||||
// A 'tick' can be converted to microsends as follows:
|
// A 'tick' can be converted to microsends as follows:
|
||||||
//
|
//
|
||||||
// microsecond per tick = micros per quarter note / ticks per quarter note
|
// microsecond per tick = micros per quarter note / ticks per quarter note
|
||||||
//
|
//
|
||||||
// MpT = MpQN / TpQN
|
// MpT = MpQN / TpQN
|
||||||
//
|
//
|
||||||
// TpQN is given as a constant in the MIDI file header.
|
// TpQN is given as a constant in the MIDI file header.
|
||||||
// MpQN is given as the value of the MIDI file tempo message.
|
// MpQN is given as the value of the MIDI file tempo message.
|
||||||
//
|
//
|
||||||
// See cmMidiFileSeekUSecs() for an example of converting ticks to milliseconds.
|
// See cmMidiFileSeekUSecs() for an example of converting ticks to milliseconds.
|
||||||
//
|
//
|
||||||
// As part of the file reading process, the status byte of note-on messages
|
// As part of the file reading process, the status byte of note-on messages
|
||||||
// with velocity=0 are is changed to a note-off message. See _cmMidiFileReadChannelMsg().
|
// with velocity=0 are is changed to a note-off message. See _cmMidiFileReadChannelMsg().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef cmHandle_t cmMidiFileH_t;
|
typedef cmHandle_t cmMidiFileH_t;
|
||||||
typedef unsigned cmMfRC_t;
|
typedef unsigned cmMfRC_t;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
|
||||||
cmMidiByte_t hr;
|
|
||||||
cmMidiByte_t min;
|
|
||||||
cmMidiByte_t sec;
|
|
||||||
cmMidiByte_t frm;
|
|
||||||
cmMidiByte_t sfr;
|
|
||||||
} cmMidiSmpte_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
cmMidiByte_t num;
|
|
||||||
cmMidiByte_t den;
|
|
||||||
cmMidiByte_t metro;
|
|
||||||
cmMidiByte_t th2s;
|
|
||||||
} cmMidiTimeSig_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
cmMidiByte_t key;
|
|
||||||
cmMidiByte_t scale;
|
|
||||||
} cmMidiKeySig_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
cmMidiByte_t ch;
|
|
||||||
cmMidiByte_t d0;
|
|
||||||
cmMidiByte_t d1;
|
|
||||||
unsigned durTicks; // note duration calc'd by
|
|
||||||
} cmMidiChMsg_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct cmMidiTrackMsg_str
|
|
||||||
{
|
|
||||||
unsigned dtick; // delta ticks
|
|
||||||
cmMidiByte_t status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch)
|
|
||||||
cmMidiByte_t metaId; //
|
|
||||||
unsigned short trkIdx; //
|
|
||||||
unsigned byteCnt; // length of data pointed to by u.voidPtr (or any other pointer in the union)
|
|
||||||
struct cmMidiTrackMsg_str* link; // link to next record in this track
|
|
||||||
|
|
||||||
union
|
|
||||||
{
|
{
|
||||||
cmMidiByte_t bVal;
|
cmMidiByte_t hr;
|
||||||
unsigned iVal;
|
cmMidiByte_t min;
|
||||||
unsigned short sVal;
|
cmMidiByte_t sec;
|
||||||
const char* text;
|
cmMidiByte_t frm;
|
||||||
const void* voidPtr;
|
cmMidiByte_t sfr;
|
||||||
const cmMidiSmpte_t* smptePtr;
|
} cmMidiSmpte_t;
|
||||||
const cmMidiTimeSig_t* timeSigPtr;
|
|
||||||
const cmMidiKeySig_t* keySigPtr;
|
|
||||||
const cmMidiChMsg_t* chMsgPtr;
|
|
||||||
const cmMidiByte_t* sysExPtr;
|
|
||||||
} u;
|
|
||||||
} cmMidiTrackMsg_t;
|
|
||||||
|
|
||||||
enum
|
typedef struct
|
||||||
{
|
{
|
||||||
kOkMfRC = cmOkRC, // 0
|
cmMidiByte_t num;
|
||||||
kSysFopenFailMfRC, // 1
|
cmMidiByte_t den;
|
||||||
kSysFreadFailMfRC, // 2
|
cmMidiByte_t metro;
|
||||||
kSysFseekFailMfRC, // 3
|
cmMidiByte_t th2s;
|
||||||
kSysFtellFailMfRC, // 4
|
} cmMidiTimeSig_t;
|
||||||
kSysFcloseFailMfRC, // 5
|
|
||||||
kNotAMidiFileMfRC, // 6
|
|
||||||
kMemAllocFailMfRC, // 7
|
|
||||||
kFileCorruptMfRC, // 8
|
|
||||||
kMissingEoxMfRC, // 9
|
|
||||||
kUnknownMetaIdMfRC, // 10
|
|
||||||
kInvalidHandleMfRC, // 11
|
|
||||||
kMissingNoteOffMfRC, // 12
|
|
||||||
kInvalidStatusMfRC // 13
|
|
||||||
};
|
|
||||||
|
|
||||||
extern cmMidiFileH_t cmMidiFileNullHandle;
|
typedef struct
|
||||||
|
{
|
||||||
|
cmMidiByte_t key;
|
||||||
|
cmMidiByte_t scale;
|
||||||
|
} cmMidiKeySig_t;
|
||||||
|
|
||||||
cmMfRC_t cmMidiFileOpen( const char* fn, cmMidiFileH_t* hPtr, cmCtx_t* ctx );
|
typedef struct
|
||||||
cmMfRC_t cmMidiFileClose( cmMidiFileH_t* hp );
|
{
|
||||||
|
cmMidiByte_t ch;
|
||||||
|
cmMidiByte_t d0;
|
||||||
|
cmMidiByte_t d1;
|
||||||
|
unsigned durTicks; // note duration calc'd by
|
||||||
|
} cmMidiChMsg_t;
|
||||||
|
|
||||||
// Returns track count or kInvalidCnt if 'h' is invalid.
|
|
||||||
unsigned cmMidiFileTrackCount( cmMidiFileH_t h );
|
|
||||||
|
|
||||||
// Return midi file format id (0,1,2) or kInvalidId if 'h' is invalid.
|
typedef struct cmMidiTrackMsg_str
|
||||||
unsigned cmMidiFileType( cmMidiFileH_t h );
|
{
|
||||||
|
unsigned dtick; // delta ticks
|
||||||
|
cmMidiByte_t status; // ch msg's have the channel value removed (it is stored in u.chMsgPtr->ch)
|
||||||
|
cmMidiByte_t metaId; //
|
||||||
|
unsigned short trkIdx; //
|
||||||
|
unsigned byteCnt; // length of data pointed to by u.voidPtr (or any other pointer in the union)
|
||||||
|
struct cmMidiTrackMsg_str* link; // link to next record in this track
|
||||||
|
|
||||||
// Returns ticks per quarter note or kInvalidMidiByte if 'h' is invalid or 0 if file uses SMPTE ticks per frame time base.
|
union
|
||||||
unsigned cmMidiFileTicksPerQN( cmMidiFileH_t h );
|
{
|
||||||
|
cmMidiByte_t bVal;
|
||||||
|
unsigned iVal;
|
||||||
|
unsigned short sVal;
|
||||||
|
const char* text;
|
||||||
|
const void* voidPtr;
|
||||||
|
const cmMidiSmpte_t* smptePtr;
|
||||||
|
const cmMidiTimeSig_t* timeSigPtr;
|
||||||
|
const cmMidiKeySig_t* keySigPtr;
|
||||||
|
const cmMidiChMsg_t* chMsgPtr;
|
||||||
|
const cmMidiByte_t* sysExPtr;
|
||||||
|
} u;
|
||||||
|
} cmMidiTrackMsg_t;
|
||||||
|
|
||||||
// The file name used in an earlier call to midiFileOpen() or NULL if this
|
enum
|
||||||
// midi file did not originate from an actual file.
|
{
|
||||||
const char* cmMidiFileName( cmMidiFileH_t h );
|
kOkMfRC = cmOkRC, // 0
|
||||||
|
kSysFopenFailMfRC, // 1
|
||||||
|
kSysFreadFailMfRC, // 2
|
||||||
|
kSysFseekFailMfRC, // 3
|
||||||
|
kSysFtellFailMfRC, // 4
|
||||||
|
kSysFcloseFailMfRC, // 5
|
||||||
|
kNotAMidiFileMfRC, // 6
|
||||||
|
kMemAllocFailMfRC, // 7
|
||||||
|
kFileCorruptMfRC, // 8
|
||||||
|
kMissingEoxMfRC, // 9
|
||||||
|
kUnknownMetaIdMfRC, // 10
|
||||||
|
kInvalidHandleMfRC, // 11
|
||||||
|
kMissingNoteOffMfRC, // 12
|
||||||
|
kInvalidStatusMfRC // 13
|
||||||
|
};
|
||||||
|
|
||||||
// Returns SMPTE ticks per frame or kInvalidMidiByte if 'h' is invalid or 0 if file uses ticks per quarter note time base.
|
extern cmMidiFileH_t cmMidiFileNullHandle;
|
||||||
cmMidiByte_t cmMidiFileTicksPerSmpteFrame( cmMidiFileH_t h );
|
|
||||||
|
|
||||||
// Returns SMPTE format or kInvalidMidiByte if 'h' is invalid or 0 if file uses ticks per quarter note time base.
|
cmMfRC_t cmMidiFileOpen( const char* fn, cmMidiFileH_t* hPtr, cmCtx_t* ctx );
|
||||||
cmMidiByte_t cmMidiFileSmpteFormatId( cmMidiFileH_t h );
|
cmMfRC_t cmMidiFileClose( cmMidiFileH_t* hp );
|
||||||
|
|
||||||
// Returns count of records in track 'trackIdx' or kInvalidCnt if 'h' is invalid.
|
// Returns track count or kInvalidCnt if 'h' is invalid.
|
||||||
unsigned cmMidiFileTrackMsgCount( cmMidiFileH_t h, unsigned trackIdx );
|
unsigned cmMidiFileTrackCount( cmMidiFileH_t h );
|
||||||
|
|
||||||
// Returns base of record chain from track 'trackIdx' or NULL if 'h' is invalid.
|
// Return midi file format id (0,1,2) or kInvalidId if 'h' is invalid.
|
||||||
const cmMidiTrackMsg_t* cmMidiFileTrackMsg( cmMidiFileH_t h, unsigned trackIdx );
|
unsigned cmMidiFileType( cmMidiFileH_t h );
|
||||||
|
|
||||||
// Returns the total count of records in the midi file and the number in the array returned by cmMidiFileMsgArray().
|
// Returns ticks per quarter note or kInvalidMidiByte if 'h' is invalid or 0 if file uses SMPTE ticks per frame time base.
|
||||||
// Return kInvalidCnt if 'h' is invalid.
|
unsigned cmMidiFileTicksPerQN( cmMidiFileH_t h );
|
||||||
unsigned cmMidiFileMsgCount( cmMidiFileH_t h );
|
|
||||||
|
|
||||||
// Returns a pointer to the base of an array of pointers to each record in the file sorted in ascending time order.
|
// The file name used in an earlier call to midiFileOpen() or NULL if this
|
||||||
// Returns NULL if 'h' is invalid.
|
// midi file did not originate from an actual file.
|
||||||
const cmMidiTrackMsg_t** cmMidiFileMsgArray( cmMidiFileH_t h );
|
const char* cmMidiFileName( cmMidiFileH_t h );
|
||||||
|
|
||||||
// Return a pointer to the first msg at or after 'usecsOffs' or kInvalidIdx if no
|
// Returns SMPTE ticks per frame or kInvalidMidiByte if 'h' is invalid or 0 if file uses ticks per quarter note time base.
|
||||||
// msg exists after 'usecsOffs'. Note that 'usecOffs' is an offset from the beginning
|
cmMidiByte_t cmMidiFileTicksPerSmpteFrame( cmMidiFileH_t h );
|
||||||
// of the file.
|
|
||||||
// On return *'msgUsecsPtr' is set to the actual time of the msg.
|
|
||||||
// (which will be equal to or greater than 'usecsOffs').
|
|
||||||
unsigned cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned usecsOffs, unsigned* msgUsecsPtr, unsigned* newMicrosPerTickPtr );
|
|
||||||
|
|
||||||
double cmMidiFileDurSecs( cmMidiFileH_t h );
|
// Returns SMPTE format or kInvalidMidiByte if 'h' is invalid or 0 if file uses ticks per quarter note time base.
|
||||||
|
cmMidiByte_t cmMidiFileSmpteFormatId( cmMidiFileH_t h );
|
||||||
|
|
||||||
// Convert the track message 'dtick' field to delta-microseconds.
|
// Returns count of records in track 'trackIdx' or kInvalidCnt if 'h' is invalid.
|
||||||
void cmMidiFileTickToMicros( cmMidiFileH_t h );
|
unsigned cmMidiFileTrackMsgCount( cmMidiFileH_t h, unsigned trackIdx );
|
||||||
|
|
||||||
// Calculate Note Duration
|
// Returns base of record chain from track 'trackIdx' or NULL if 'h' is invalid.
|
||||||
void cmMidiFileCalcNoteDurations( cmMidiFileH_t h );
|
const cmMidiTrackMsg_t* cmMidiFileTrackMsg( cmMidiFileH_t h, unsigned trackIdx );
|
||||||
|
|
||||||
// Set the delay prior to the first non-zero msg.
|
// Returns the total count of records in the midi file and the number in the array returned by cmMidiFileMsgArray().
|
||||||
void cmMidiFileSetDelay( cmMidiFileH_t h, unsigned ticks );
|
// Return kInvalidCnt if 'h' is invalid.
|
||||||
|
unsigned cmMidiFileMsgCount( cmMidiFileH_t h );
|
||||||
|
|
||||||
// This function packs a track msg into a single consecutive
|
// Returns a pointer to the base of an array of pointers to each record in the file sorted in ascending time order.
|
||||||
// block of memory buf[ bufByteCnt ]. Call cmMidiFilePackTracMsgBufByteCount()
|
// Returns NULL if 'h' is invalid.
|
||||||
// to get the required buffer length for any given cmMidiTrackMsg_t instance.
|
const cmMidiTrackMsg_t** cmMidiFileMsgArray( cmMidiFileH_t h );
|
||||||
cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* buf, unsigned bufByteCnt );
|
|
||||||
unsigned cmMidiFilePackTrackMsgBufByteCount( const cmMidiTrackMsg_t* m );
|
|
||||||
|
|
||||||
void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
|
// Return a pointer to the first msg at or after 'usecsOffs' or kInvalidIdx if no
|
||||||
bool cmMidiFileIsNull( cmMidiFileH_t h );
|
// msg exists after 'usecsOffs'. Note that 'usecOffs' is an offset from the beginning
|
||||||
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
// of the file.
|
||||||
|
// On return *'msgUsecsPtr' is set to the actual time of the msg.
|
||||||
|
// (which will be equal to or greater than 'usecsOffs').
|
||||||
|
unsigned cmMidiFileSeekUsecs( cmMidiFileH_t h, unsigned usecsOffs, unsigned* msgUsecsPtr, unsigned* newMicrosPerTickPtr );
|
||||||
|
|
||||||
|
double cmMidiFileDurSecs( cmMidiFileH_t h );
|
||||||
|
|
||||||
|
// Convert the track message 'dtick' field to delta-microseconds.
|
||||||
|
void cmMidiFileTickToMicros( cmMidiFileH_t h );
|
||||||
|
|
||||||
|
// Convert the track message 'dtick' field to samples.
|
||||||
|
// If the absFl is set then the delta times are converted to absolute time.
|
||||||
|
void cmMidiFileTickToSamples( cmMidiFileH_t h, double srate, bool absFl );
|
||||||
|
|
||||||
|
// Calculate Note Duration
|
||||||
|
void cmMidiFileCalcNoteDurations( cmMidiFileH_t h );
|
||||||
|
|
||||||
|
// Set the delay prior to the first non-zero msg.
|
||||||
|
void cmMidiFileSetDelay( cmMidiFileH_t h, unsigned ticks );
|
||||||
|
|
||||||
|
// This function packs a track msg into a single consecutive
|
||||||
|
// block of memory buf[ bufByteCnt ]. Call cmMidiFilePackTracMsgBufByteCount()
|
||||||
|
// to get the required buffer length for any given cmMidiTrackMsg_t instance.
|
||||||
|
cmMidiTrackMsg_t* cmMidiFilePackTrackMsg( const cmMidiTrackMsg_t* m, void* buf, unsigned bufByteCnt );
|
||||||
|
unsigned cmMidiFilePackTrackMsgBufByteCount( const cmMidiTrackMsg_t* m );
|
||||||
|
|
||||||
|
void cmMidiFilePrint( cmMidiFileH_t h, unsigned trkIdx, cmRpt_t* rpt );
|
||||||
|
bool cmMidiFileIsNull( cmMidiFileH_t h );
|
||||||
|
void cmMidiFileTest( const char* fn, cmCtx_t* ctx );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -1534,8 +1534,6 @@ cmDspInst_t* _cmDspTextAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned
|
|||||||
|
|
||||||
cmDspText_t* p = cmDspInstAlloc(cmDspText_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
|
cmDspText_t* p = cmDspInstAlloc(cmDspText_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// create the UI control
|
// create the UI control
|
||||||
cmDspUiTextCreate(ctx,&p->inst,kValTxId,kLblTxId);
|
cmDspUiTextCreate(ctx,&p->inst,kValTxId,kLblTxId);
|
||||||
|
|
||||||
@ -4993,6 +4991,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
|
|||||||
cmSegLineClassCons,
|
cmSegLineClassCons,
|
||||||
|
|
||||||
cmTimeLineClassCons,
|
cmTimeLineClassCons,
|
||||||
|
cmMidiFilePlayClassCons,
|
||||||
|
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
@ -392,7 +392,7 @@ extern "C" {
|
|||||||
cmDspRC_t cmDspUiMeterCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned minVarId, unsigned maxVarId, unsigned valVarId, unsigned lblVarId );
|
cmDspRC_t cmDspUiMeterCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned minVarId, unsigned maxVarId, unsigned valVarId, unsigned lblVarId );
|
||||||
cmDspRC_t cmDspUiButtonCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned typeDuiId, unsigned outVarId, unsigned lblVarId );
|
cmDspRC_t cmDspUiButtonCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned typeDuiId, unsigned outVarId, unsigned lblVarId );
|
||||||
cmDspRC_t cmDspUiLabelCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned lblVarId, unsigned alignVarId );
|
cmDspRC_t cmDspUiLabelCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned lblVarId, unsigned alignVarId );
|
||||||
cmDspRC_t cmDspUiTimeLineCreate(cmDspCtx_t* ctx,cmDspInst_t* inst, unsigned valVarId, unsigned lblVarId, unsigned tlFileId, unsigned audPathId );
|
cmDspRC_t cmDspUiTimeLineCreate(cmDspCtx_t* ctx,cmDspInst_t* inst, unsigned tlFileVarId, unsigned audPathVarId, unsigned selVarId );
|
||||||
|
|
||||||
cmDspRC_t cmDspUiNewColumn( cmDspCtx_t* ctx, unsigned colW );
|
cmDspRC_t cmDspUiNewColumn( cmDspCtx_t* ctx, unsigned colW );
|
||||||
cmDspRC_t cmDspUiInsertHorzBorder( cmDspCtx_t* ctx );
|
cmDspRC_t cmDspUiInsertHorzBorder( cmDspCtx_t* ctx );
|
||||||
|
446
dsp/cmDspKr.c
446
dsp/cmDspKr.c
@ -24,6 +24,7 @@
|
|||||||
#include "cmOp.h"
|
#include "cmOp.h"
|
||||||
#include "cmMath.h"
|
#include "cmMath.h"
|
||||||
|
|
||||||
|
|
||||||
#include "cmAudioFile.h"
|
#include "cmAudioFile.h"
|
||||||
#include "cmFileSys.h"
|
#include "cmFileSys.h"
|
||||||
#include "cmProcObj.h"
|
#include "cmProcObj.h"
|
||||||
@ -33,6 +34,12 @@
|
|||||||
#include "cmProc2.h"
|
#include "cmProc2.h"
|
||||||
#include "cmVectOpsTemplateMain.h"
|
#include "cmVectOpsTemplateMain.h"
|
||||||
|
|
||||||
|
#include "cmAudioFile.h"
|
||||||
|
#include "cmMidiFile.h"
|
||||||
|
#include "cmTimeLine.h"
|
||||||
|
#include "cmScore.h"
|
||||||
|
#include "cmProc4.h"
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kWndSmpCntKrId,
|
kWndSmpCntKrId,
|
||||||
@ -227,12 +234,20 @@ struct cmDspClass_str* cmKrClassCons( cmDspCtx_t* ctx )
|
|||||||
|
|
||||||
|
|
||||||
//==========================================================================================================================================
|
//==========================================================================================================================================
|
||||||
|
// Time Line UI Object
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
kValTlId,
|
|
||||||
kLblTlId,
|
|
||||||
kTlFileTlId,
|
kTlFileTlId,
|
||||||
kAudPathTlId
|
kAudPathTlId,
|
||||||
|
kSelTlId,
|
||||||
|
kAudFnTlId,
|
||||||
|
kMidiFnTlId,
|
||||||
|
kBegAudSmpIdxTlId,
|
||||||
|
kEndAudSmpIdxTlId,
|
||||||
|
kBegMidiSmpIdxTlId,
|
||||||
|
kEndMidiSmpIdxTlId
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
cmDspClass_t _cmTimeLineDC;
|
cmDspClass_t _cmTimeLineDC;
|
||||||
@ -240,38 +255,113 @@ cmDspClass_t _cmTimeLineDC;
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
cmDspInst_t inst;
|
cmDspInst_t inst;
|
||||||
|
cmTlH_t tlH;
|
||||||
} cmDspTimeLine_t;
|
} cmDspTimeLine_t;
|
||||||
|
|
||||||
cmDspInst_t* _cmDspTimeLineAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
cmDspInst_t* _cmDspTimeLineAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
||||||
{
|
{
|
||||||
cmDspVarArg_t args[] =
|
cmDspVarArg_t args[] =
|
||||||
{
|
{
|
||||||
{ "val", kValTlId, 0, 0, kInDsvFl | kOutDsvFl | kStrzDsvFl | kReqArgDsvFl | kSendDfltDsvFl, "Current string"},
|
{ "tlfile", kTlFileTlId, 0, 0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Time line file." },
|
||||||
{ "lbl", kLblTlId, 0, 0, kStrzDsvFl | kOptArgDsvFl, "Label"},
|
{ "path", kAudPathTlId, 0, 0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Audio path" },
|
||||||
|
{ "sel", kSelTlId, 0, 0, kInDsvFl | kInDsvFl | kOutDsvFl | kUIntDsvFl, "Selected marker id."},
|
||||||
|
{ "afn", kAudFnTlId, 0, 0, kOutDsvFl | kStrzDsvFl, "Selected Audio file." },
|
||||||
|
{ "mfn", kMidiFnTlId, 0, 0, kOutDsvFl | kStrzDsvFl, "Selected MIDI file." },
|
||||||
|
{ "absi", kBegAudSmpIdxTlId, 0, 0, kOutDsvFl | kIntDsvFl, "Begin audio sample index."},
|
||||||
|
{ "aesi", kEndAudSmpIdxTlId, 0, 0, kOutDsvFl | kIntDsvFl, "End audio sample index."},
|
||||||
|
{ "mbsi", kBegMidiSmpIdxTlId, 0, 0, kOutDsvFl | kIntDsvFl, "Begin MIDI sample index."},
|
||||||
|
{ "mesi", kEndMidiSmpIdxTlId, 0, 0, kOutDsvFl | kIntDsvFl, "End MIDI sample index."},
|
||||||
{ NULL, 0, 0, 0, 0 }
|
{ NULL, 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
cmDspTimeLine_t* p = cmDspInstAlloc(cmDspTimeLine_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
|
cmDspTimeLine_t* p = cmDspInstAlloc(cmDspTimeLine_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
|
||||||
|
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kSelTlId, 0, cmInvalidId);
|
||||||
|
cmDspSetDefaultStrcz(ctx, &p->inst, kAudFnTlId, NULL, "");
|
||||||
|
cmDspSetDefaultStrcz(ctx, &p->inst, kMidiFnTlId, NULL, "");
|
||||||
|
cmDspSetDefaultInt( ctx, &p->inst, kBegAudSmpIdxTlId, 0, cmInvalidIdx);
|
||||||
|
cmDspSetDefaultInt( ctx, &p->inst, kEndAudSmpIdxTlId, 0, cmInvalidIdx);
|
||||||
|
cmDspSetDefaultInt( ctx, &p->inst, kBegMidiSmpIdxTlId, 0, cmInvalidIdx);
|
||||||
|
cmDspSetDefaultInt( ctx, &p->inst, kEndMidiSmpIdxTlId, 0, cmInvalidIdx);
|
||||||
|
|
||||||
// create the UI control
|
// create the UI control
|
||||||
cmDspUiTimeLineCreate(ctx,&p->inst,kValTlId,kLblTlId,kTlFileTlId,kAudPathTlId);
|
cmDspUiTimeLineCreate(ctx,&p->inst,kTlFileTlId,kAudPathTlId,kSelTlId);
|
||||||
|
|
||||||
|
p->tlH = cmTimeLineNullHandle;
|
||||||
|
|
||||||
return &p->inst;
|
return &p->inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspTimeLineFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
cmDspTimeLine_t* p = (cmDspTimeLine_t*)inst;
|
||||||
|
|
||||||
|
if( cmTimeLineFinalize(&p->tlH) != kOkTlRC )
|
||||||
|
return cmErrMsg(&inst->classPtr->err, kInstFinalFailDspRC, "Time-line finalize failed.");
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
cmDspRC_t _cmDspTimeLineReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
cmDspRC_t _cmDspTimeLineReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
{
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
cmDspTimeLine_t* p = (cmDspTimeLine_t*)inst;
|
||||||
|
|
||||||
cmDspApplyAllDefaults(ctx,inst);
|
cmDspApplyAllDefaults(ctx,inst);
|
||||||
return kOkDspRC;
|
|
||||||
|
const cmChar_t* tlFn;
|
||||||
|
if((tlFn = cmDspStrcz(inst, kTlFileTlId )) != NULL )
|
||||||
|
if( cmTimeLineInitializeFromFile(ctx->cmCtx, &p->tlH, NULL, NULL, tlFn ) != kOkTlRC )
|
||||||
|
rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "Time-line file open failed.");
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmDspRC_t _cmDspTimeLineRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
cmDspRC_t _cmDspTimeLineRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
{
|
{
|
||||||
|
cmDspTimeLine_t* p = (cmDspTimeLine_t*)inst;
|
||||||
|
|
||||||
switch( evt->dstVarId )
|
switch( evt->dstVarId )
|
||||||
{
|
{
|
||||||
case kValTlId:
|
case kSelTlId:
|
||||||
cmDspSetEvent(ctx,inst,evt);
|
{
|
||||||
|
unsigned markerId;
|
||||||
|
cmDspSetEvent(ctx,inst,evt);
|
||||||
|
|
||||||
|
// get the id of the selected marker
|
||||||
|
if((markerId = cmDspUInt(inst,kSelTlId)) != cmInvalidId )
|
||||||
|
{
|
||||||
|
// get the marker object
|
||||||
|
cmTlObj_t* op;
|
||||||
|
if((op = cmTimeLineIdToObj(p->tlH, cmInvalidId, markerId )) != NULL )
|
||||||
|
{
|
||||||
|
assert(op->typeId == kMarkerTlId);
|
||||||
|
|
||||||
|
cmDspSetInt(ctx, inst, kBegAudSmpIdxTlId, op->begSmpIdx );
|
||||||
|
cmDspSetInt(ctx, inst, kEndAudSmpIdxTlId, op->begSmpIdx + op->durSmpCnt );
|
||||||
|
|
||||||
|
// locate the audio file assoc'd with the marker
|
||||||
|
cmTlAudioFile_t* afp;
|
||||||
|
if((afp = cmTimeLineAudioFileAtTime(p->tlH,op->seqId,op->seqSmpIdx)) != NULL)
|
||||||
|
cmDspSetStrcz(ctx, inst, kAudFnTlId, afp->fn );
|
||||||
|
|
||||||
|
// locate the midi file assoc'd with the marker
|
||||||
|
cmTlMidiFile_t* mfp;
|
||||||
|
if((mfp = cmTimeLineMidiFileAtTime(p->tlH,op->seqId,op->seqSmpIdx)) != NULL )
|
||||||
|
{
|
||||||
|
cmDspSetInt(ctx, inst, kBegMidiSmpIdxTlId, op->seqSmpIdx - mfp->obj.seqSmpIdx );
|
||||||
|
cmDspSetInt(ctx, inst, kEndMidiSmpIdxTlId, op->seqSmpIdx + op->durSmpCnt - mfp->obj.seqSmpIdx );
|
||||||
|
|
||||||
|
cmDspSetStrcz(ctx, inst, kMidiFnTlId, mfp->fn );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -286,7 +376,7 @@ struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx )
|
|||||||
cmDspClassSetup(&_cmTimeLineDC,ctx,"TimeLine",
|
cmDspClassSetup(&_cmTimeLineDC,ctx,"TimeLine",
|
||||||
NULL,
|
NULL,
|
||||||
_cmDspTimeLineAlloc,
|
_cmDspTimeLineAlloc,
|
||||||
NULL,
|
_cmDspTimeLineFree,
|
||||||
_cmDspTimeLineReset,
|
_cmDspTimeLineReset,
|
||||||
NULL,
|
NULL,
|
||||||
_cmDspTimeLineRecv,
|
_cmDspTimeLineRecv,
|
||||||
@ -296,3 +386,339 @@ struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx )
|
|||||||
return &_cmTimeLineDC;
|
return &_cmTimeLineDC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//==========================================================================================================================================
|
||||||
|
// MIDI File Player
|
||||||
|
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kFnMfId,
|
||||||
|
kSelMfId,
|
||||||
|
kBsiMfId,
|
||||||
|
kEsiMfId,
|
||||||
|
kStatusMfId,
|
||||||
|
kD0MfId,
|
||||||
|
kD1MfId
|
||||||
|
};
|
||||||
|
|
||||||
|
cmDspClass_t _cmMidiFilePlayDC;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmDspInst_t inst;
|
||||||
|
cmMidiFileH_t mfH;
|
||||||
|
unsigned curMsgIdx; // current midi file msg index
|
||||||
|
int csi; // current sample index
|
||||||
|
int bsi; // starting sample index
|
||||||
|
int esi; // ending sample index
|
||||||
|
unsigned startSymId;
|
||||||
|
unsigned stopSymId;
|
||||||
|
unsigned contSymId;
|
||||||
|
} cmDspMidiFilePlay_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
'bsi' and 'esi' give the starting and ending sample for MIDI file playback.
|
||||||
|
These indexes are relative to the start of the file.
|
||||||
|
When the player recieves a 'start' msg it sets the current sample index
|
||||||
|
'si' to 'bsi' and begins scanning for the next note to play.
|
||||||
|
On each call to the _cmDspMidiFilePlayExec() msgs that fall in the interval
|
||||||
|
si:si+sPc-1 will be transmitted. (where sPc are the number of samples per DSP cycle).
|
||||||
|
*/
|
||||||
|
|
||||||
|
cmDspInst_t* _cmDspMidiFilePlayAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
||||||
|
{
|
||||||
|
cmDspVarArg_t args[] =
|
||||||
|
{
|
||||||
|
{ "fn", kFnMfId, 0, 0, kInDsvFl | kStrzDsvFl, "File name"},
|
||||||
|
{ "sel", kSelMfId, 0, 0, kInDsvFl | kSymDsvFl, "start | stop | continue" },
|
||||||
|
{ "bsi", kBsiMfId, 0, 0, kInDsvFl | kIntDsvFl, "Starting sample." },
|
||||||
|
{ "esi", kEsiMfId, 0, 0, kInDsvFl | kIntDsvFl, "Ending sample."},
|
||||||
|
{ "status", kStatusMfId, 0, 0, kOutDsvFl | kIntDsvFl, "Status value output" },
|
||||||
|
{ "d0", kD0MfId, 0, 0, kOutDsvFl | kUIntDsvFl, "Data byte 0" },
|
||||||
|
{ "d1", kD1MfId, 0, 0, kOutDsvFl | kUIntDsvFl, "Data byte 1" },
|
||||||
|
{ NULL, 0, 0, 0, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
cmDspMidiFilePlay_t* p = cmDspInstAlloc(cmDspMidiFilePlay_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
|
||||||
|
|
||||||
|
p->startSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"start");
|
||||||
|
p->stopSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"stop");
|
||||||
|
p->contSymId = cmSymTblRegisterStaticSymbol(ctx->stH,"continue");
|
||||||
|
p->mfH = cmMidiFileNullHandle;
|
||||||
|
|
||||||
|
cmDspSetDefaultStrcz( ctx, &p->inst, kFnMfId, NULL, "");
|
||||||
|
cmDspSetDefaultSymbol(ctx, &p->inst, kSelMfId, p->stopSymId);
|
||||||
|
cmDspSetDefaultInt( ctx, &p->inst, kBsiMfId, 0, 0);
|
||||||
|
cmDspSetDefaultInt( ctx, &p->inst, kEsiMfId, 0, 0);
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kStatusMfId, 0, 0);
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kD0MfId, 0, 0);
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kD1MfId, 0, 0);
|
||||||
|
|
||||||
|
return &p->inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspMidiFilePlayFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspMidiFilePlay_t* p = (cmDspMidiFilePlay_t*)inst;
|
||||||
|
if( cmMidiFileClose(&p->mfH) )
|
||||||
|
return cmErrMsg(&inst->classPtr->err, kInstFinalFailDspRC, "MIDI file close failed.");
|
||||||
|
return kOkDspRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the index of the msg following smpIdx
|
||||||
|
unsigned _cmDspMidiFilePlaySeekMsgIdx( cmDspCtx_t* ctx, cmDspMidiFilePlay_t* p, unsigned smpIdx )
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
unsigned n = cmMidiFileMsgCount(p->mfH);
|
||||||
|
const cmMidiTrackMsg_t** a = cmMidiFileMsgArray(p->mfH);
|
||||||
|
|
||||||
|
for(i=0; i<n; ++i)
|
||||||
|
if( a[i]->dtick > smpIdx )
|
||||||
|
break;
|
||||||
|
|
||||||
|
return i==n ? cmInvalidIdx : i;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspMidiFilePlayOpen(cmDspCtx_t* ctx, cmDspInst_t* inst )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
const cmChar_t* fn = cmDspStrcz(inst,kFnMfId);
|
||||||
|
cmDspMidiFilePlay_t* p = (cmDspMidiFilePlay_t*)inst;
|
||||||
|
|
||||||
|
if( fn==NULL || strlen(fn)==0 )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if( cmMidiFileOpen( fn, &p->mfH, ctx->cmCtx ) != kOkFileRC )
|
||||||
|
rc = cmErrMsg(&inst->classPtr->err, kInstResetFailDspRC, "MIDI file open failed.");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p->curMsgIdx = 0;
|
||||||
|
p->bsi = cmDspInt(inst,kBsiMfId);
|
||||||
|
p->esi = cmDspInt(inst,kEsiMfId);
|
||||||
|
p->csi = 0;
|
||||||
|
|
||||||
|
// force the first msg to occurr one quarter note into the file
|
||||||
|
cmMidiFileSetDelay(p->mfH, cmMidiFileTicksPerQN(p->mfH) );
|
||||||
|
|
||||||
|
// convert midi msg times to absolute time in samples
|
||||||
|
cmMidiFileTickToSamples(p->mfH,cmDspSampleRate(ctx),true);
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspMidiFilePlayReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspApplyAllDefaults(ctx,inst);
|
||||||
|
|
||||||
|
return _cmDspMidiFilePlayOpen(ctx,inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspMidiFilePlayExec(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
cmDspMidiFilePlay_t* p = (cmDspMidiFilePlay_t*)inst;
|
||||||
|
unsigned sPc = cmDspSamplesPerCycle(ctx);
|
||||||
|
|
||||||
|
if( cmDspSymbol(inst,kSelMfId) != p->stopSymId )
|
||||||
|
{
|
||||||
|
const cmMidiTrackMsg_t** mpp = cmMidiFileMsgArray(p->mfH);
|
||||||
|
unsigned msgN = cmMidiFileMsgCount(p->mfH);
|
||||||
|
|
||||||
|
for(; p->curMsgIdx < msgN && p->csi <= mpp[p->curMsgIdx]->dtick && mpp[p->curMsgIdx]->dtick < (p->csi + sPc); ++p->curMsgIdx )
|
||||||
|
{
|
||||||
|
const cmMidiTrackMsg_t* mp = mpp[p->curMsgIdx];
|
||||||
|
switch( mp->status )
|
||||||
|
{
|
||||||
|
case kNoteOnMdId:
|
||||||
|
case kCtlMdId:
|
||||||
|
cmDspSetUInt(ctx,inst, kD1MfId, mp->u.chMsgPtr->d1);
|
||||||
|
cmDspSetUInt(ctx,inst, kD0MfId, mp->u.chMsgPtr->d0);
|
||||||
|
cmDspSetUInt(ctx,inst, kStatusMfId, mp->status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
p->csi += sPc;
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspMidiFilePlayRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspMidiFilePlay_t* p = (cmDspMidiFilePlay_t*)inst;
|
||||||
|
|
||||||
|
cmDspSetEvent(ctx,inst,evt);
|
||||||
|
|
||||||
|
switch(evt->dstVarId)
|
||||||
|
{
|
||||||
|
case kFnMfId:
|
||||||
|
_cmDspMidiFilePlayOpen(ctx, inst );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kSelMfId:
|
||||||
|
{
|
||||||
|
if( cmDspSymbol(inst,kSelMfId)==p->startSymId )
|
||||||
|
{
|
||||||
|
p->csi = cmDspInt(inst,kBsiMfId);
|
||||||
|
p->curMsgIdx = _cmDspMidiFilePlaySeekMsgIdx(ctx, p, p->csi );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return kOkDspRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx )
|
||||||
|
{
|
||||||
|
cmDspClassSetup(&_cmMidiFilePlayDC,ctx,"MidiFilePlay",
|
||||||
|
NULL,
|
||||||
|
_cmDspMidiFilePlayAlloc,
|
||||||
|
_cmDspMidiFilePlayFree,
|
||||||
|
_cmDspMidiFilePlayReset,
|
||||||
|
_cmDspMidiFilePlayExec,
|
||||||
|
_cmDspMidiFilePlayRecv,
|
||||||
|
NULL,NULL,
|
||||||
|
"Time tagged text file.");
|
||||||
|
|
||||||
|
return &_cmMidiFilePlayDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
//==========================================================================================================================================
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
kFnSfId,
|
||||||
|
kWndCntSfId,
|
||||||
|
kWndMsSfId,
|
||||||
|
kIndexSfId,
|
||||||
|
kStatusSfId,
|
||||||
|
kD0SfId,
|
||||||
|
kD1SfId,
|
||||||
|
kOutSfId
|
||||||
|
};
|
||||||
|
|
||||||
|
cmDspClass_t _cmScFolDC;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
cmDspInst_t inst;
|
||||||
|
cmScFol* sfp;
|
||||||
|
cmScH_t scH;
|
||||||
|
} cmDspScFol_t;
|
||||||
|
|
||||||
|
cmDspInst_t* _cmDspScFolAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
|
||||||
|
{
|
||||||
|
cmDspVarArg_t args[] =
|
||||||
|
{
|
||||||
|
{ "fn", kFnSfId, 0, 0, kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "Score file." },
|
||||||
|
{ "wndcnt",kWndCntSfId, 0, 0, kInDsvFl | kUIntDsvFl, "Event window element count." },
|
||||||
|
{ "wndms", kWndMsSfId, 0, 0, kInDsvFl | kUIntDsvFl, "Event window length milliseconds."},
|
||||||
|
{ "index", kIndexSfId, 0, 0, kInDsvFl | kUIntDsvFl, "Tracking start location."},
|
||||||
|
{ "status",kStatusSfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI status byte"},
|
||||||
|
{ "d0", kD0SfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI data byte 0"},
|
||||||
|
{ "d1", kD1SfId, 0, 0, kInDsvFl | kUIntDsvFl, "MIDI data byte 1"},
|
||||||
|
{ "out", kOutSfId, 0, 0, kOutDsvFl| kUIntDsvFl, "Current score index."},
|
||||||
|
{ NULL, 0, 0, 0, 0, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
cmDspScFol_t* p;
|
||||||
|
|
||||||
|
if((p = cmDspInstAlloc(cmDspScFol_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl)) == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
|
||||||
|
p->sfp = cmScFolAlloc(ctx->cmProcCtx, NULL, 0, 0, 0, cmScNullHandle );
|
||||||
|
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kWndCntSfId, 0, 10);
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kWndMsSfId, 0, 5000);
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kIndexSfId, 0, 0);
|
||||||
|
cmDspSetDefaultUInt( ctx, &p->inst, kOutSfId, 0, 0);
|
||||||
|
|
||||||
|
return &p->inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspScFolFree(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspScFol_t* p = (cmDspScFol_t*)inst;
|
||||||
|
cmScFolFree(&p->sfp);
|
||||||
|
cmScoreFinalize(&p->scH);
|
||||||
|
return kOkDspRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspScFolOpenScore( cmDspCtx_t* ctx, cmDspInst_t* inst )
|
||||||
|
{
|
||||||
|
const cmChar_t* fn;
|
||||||
|
cmDspScFol_t* p = (cmDspScFol_t*)inst;
|
||||||
|
|
||||||
|
if((fn = cmDspStrcz(inst,kFnSfId)) == NULL || strlen(fn)==0 )
|
||||||
|
return cmErrMsg(&inst->classPtr->err, kInvalidArgDspRC, "No score file name supplied.");
|
||||||
|
|
||||||
|
if( cmScoreInitialize(ctx->cmCtx, &p->scH, fn, NULL, NULL ) != kOkScRC )
|
||||||
|
return cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Unable to open the score '%s'.",fn);
|
||||||
|
|
||||||
|
return kOkDspRC;
|
||||||
|
}
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspScFolReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
cmDspScFol_t* p = (cmDspScFol_t*)inst;
|
||||||
|
rc = cmDspApplyAllDefaults(ctx,inst);
|
||||||
|
|
||||||
|
if((rc = _cmDspScFolOpenScore(ctx,inst)) != kOkDspRC )
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if( cmScoreIsValid(p->scH) )
|
||||||
|
if( cmScFolInit(p->sfp, cmDspSampleRate(ctx), cmDspUInt(inst,kWndCntSfId), cmDspUInt(inst,kWndMsSfId), p->scH) != cmOkRC )
|
||||||
|
rc = cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Internal score follower allocation failed.");
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
cmDspRC_t _cmDspScFolRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
|
||||||
|
{
|
||||||
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
cmDspScFol_t* p = (cmDspScFol_t*)inst;
|
||||||
|
|
||||||
|
if((rc = cmDspSetEvent(ctx,inst,evt)) == kOkDspRC && p->sfp != NULL )
|
||||||
|
{
|
||||||
|
switch( evt->dstVarId )
|
||||||
|
{
|
||||||
|
case kIndexSfId:
|
||||||
|
if( cmScFolReset( p->sfp, cmDspUInt(inst,kIndexSfId) ) != cmOkRC )
|
||||||
|
cmErrMsg(&inst->classPtr->err, kSubSysFailDspRC, "Score follower reset to score index '%i' failed.");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kStatusSfId:
|
||||||
|
{
|
||||||
|
unsigned idx = cmScFolExec(p->sfp, ctx->cycleCnt, cmDspUInt(inst,kStatusSfId), cmDspUInt(inst,kD0SfId), cmDspUInt(inst,kD1SfId));
|
||||||
|
if( idx != cmInvalidIdx )
|
||||||
|
cmDspSetUInt(ctx,inst,kOutSfId,idx);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case kFnSfId:
|
||||||
|
_cmDspScFolOpenScore(ctx,inst);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct cmDspClass_str* cmScFolClassCons( cmDspCtx_t* ctx )
|
||||||
|
{
|
||||||
|
cmDspClassSetup(&_cmScFolDC,ctx,"ScFol",
|
||||||
|
NULL,
|
||||||
|
_cmDspScFolAlloc,
|
||||||
|
_cmDspScFolFree,
|
||||||
|
_cmDspScFolReset,
|
||||||
|
NULL,
|
||||||
|
_cmDspScFolRecv,
|
||||||
|
NULL,NULL,
|
||||||
|
"Score Follower");
|
||||||
|
|
||||||
|
return &_cmScFolDC;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@ extern "C" {
|
|||||||
|
|
||||||
struct cmDspClass_str* cmKrClassCons( cmDspCtx_t* ctx );
|
struct cmDspClass_str* cmKrClassCons( cmDspCtx_t* ctx );
|
||||||
struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx );
|
struct cmDspClass_str* cmTimeLineClassCons( cmDspCtx_t* ctx );
|
||||||
|
struct cmDspClass_str* cmMidiFilePlayClassCons( cmDspCtx_t* ctx );
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -36,16 +36,53 @@
|
|||||||
|
|
||||||
cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
cmDspRC_t _cmDspSysPgm_TimeLine(cmDspSysH_t h, void** userPtrPtr )
|
||||||
{
|
{
|
||||||
cmDspRC_t rc = kOkDspRC;
|
cmDspRC_t rc = kOkDspRC;
|
||||||
|
const cmChar_t* tlFn = "/home/kevin/src/cmgv/src/gv/data/tl7.js";
|
||||||
|
const cmChar_t* audPath = "/home/kevin/media/audio/20110723-Kriesberg/Audio Files";
|
||||||
|
const cmChar_t* scFn = "/home/kevin/src/cmgv/src/gv/data/mod2.csv";
|
||||||
|
|
||||||
|
cmDspInst_t* sci = cmDspSysAllocInst(h,"Scalar", "ScIdx", 5, kNumberDuiId, 0.0, 10000.0, 1.0, 0.0);
|
||||||
|
|
||||||
|
cmDspInst_t* tlp = cmDspSysAllocInst(h,"TimeLine", "tl", 2, tlFn, audPath );
|
||||||
|
cmDspInst_t* php = cmDspSysAllocInst(h,"Phasor", NULL, 0 );
|
||||||
|
cmDspInst_t* wtp = cmDspSysAllocInst(h,"WaveTable", NULL, 2, cmDspSysSampleRate(h), 0 );
|
||||||
|
cmDspInst_t* pts = cmDspSysAllocInst(h,"PortToSym", NULL, 1, "start" );
|
||||||
|
cmDspInst_t* mfp = cmDspSysAllocInst(h,"MidiFilePlay",NULL, 0 );
|
||||||
|
cmDspInst_t* sfp = cmDspSysAllocInst(h,"ScFol", NULL, 1, scFn );
|
||||||
|
cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 0 );
|
||||||
|
cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut", NULL, 1, 1 );
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
cmDspInst_t* tlp = cmDspSysAllocInst(h,"TimeLine", "text", 1, "Hello" );
|
|
||||||
cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL, 1, ">" );
|
cmDspInst_t* prp = cmDspSysAllocInst(h,"Printer", NULL, 1, ">" );
|
||||||
|
|
||||||
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
if((rc = cmDspSysLastRC(h)) != kOkDspRC )
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
|
cmDspSysConnectAudio(h, php, "out", wtp, "phs" ); // phs -> wt
|
||||||
|
cmDspSysConnectAudio(h, wtp, "out", ao0p, "in" ); // wt -> aout0
|
||||||
|
cmDspSysConnectAudio(h, wtp, "out", ao1p, "in" ); // wt -> aout1
|
||||||
|
|
||||||
|
|
||||||
cmDspSysInstallCb(h, tlp, "val", prp, "in", NULL );
|
cmDspSysInstallCb(h, tlp, "afn", prp, "in", NULL );
|
||||||
|
cmDspSysInstallCb(h, tlp, "mfn", prp, "in", NULL );
|
||||||
|
cmDspSysInstallCb(h, tlp, "sel", prp, "in", NULL );
|
||||||
|
|
||||||
|
cmDspSysInstallCb(h, tlp, "absi", wtp, "beg", NULL );
|
||||||
|
cmDspSysInstallCb(h, tlp, "aesi", wtp, "end", NULL );
|
||||||
|
cmDspSysInstallCb(h, tlp, "afn", wtp, "fn", NULL );
|
||||||
|
|
||||||
|
cmDspSysInstallCb(h, tlp, "mbsi", mfp, "bsi", NULL );
|
||||||
|
cmDspSysInstallCb(h, tlp, "mesi", mfp, "esi", NULL );
|
||||||
|
cmDspSysInstallCb(h, tlp, "mfn", mfp, "fn", NULL );
|
||||||
|
cmDspSysInstallCb(h, tlp, "mfn", pts, "start", NULL );
|
||||||
|
cmDspSysInstallCb(h, pts, "out", mfp, "sel", NULL );
|
||||||
|
|
||||||
|
cmDspSysInstallCb(h, mfp, "status", sfp, "status", NULL );
|
||||||
|
cmDspSysInstallCb(h, mfp, "d0", sfp, "d0", NULL );
|
||||||
|
cmDspSysInstallCb(h, mfp, "d1", sfp, "d1", NULL );
|
||||||
|
cmDspSysInstallCb(h, sci, "val", sfp, "index", NULL );
|
||||||
|
cmDspSysInstallCb(h, sfp, "out", prp, "in", NULL );
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -361,10 +361,10 @@ cmDspRC_t cmDspUiLabelCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned lbl
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
cmDspRC_t cmDspUiTimeLineCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned valVarId, unsigned lblVarId, unsigned tlFileVarId, unsigned audPathVarId )
|
cmDspRC_t cmDspUiTimeLineCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned tlFileVarId, unsigned audPathVarId, unsigned selVarId )
|
||||||
{
|
{
|
||||||
cmDspRC_t rc;
|
cmDspRC_t rc;
|
||||||
unsigned arr[] = { valVarId, lblVarId, tlFileVarId, audPathVarId };
|
unsigned arr[] = { tlFileVarId, audPathVarId, selVarId };
|
||||||
cmDspValue_t v;
|
cmDspValue_t v;
|
||||||
unsigned vn = sizeof(arr)/sizeof(arr[0]);
|
unsigned vn = sizeof(arr)/sizeof(arr[0]);
|
||||||
cmDsvSetUIntMtx(&v,arr,vn,1);
|
cmDsvSetUIntMtx(&v,arr,vn,1);
|
||||||
@ -374,14 +374,14 @@ cmDspRC_t cmDspUiTimeLineCreate( cmDspCtx_t* ctx, cmDspInst_t* inst, unsigned
|
|||||||
return cmDspInstErr(ctx,inst,kUiEleCreateFailDspRC,"Time Line UI element create failed.");
|
return cmDspInstErr(ctx,inst,kUiEleCreateFailDspRC,"Time Line UI element create failed.");
|
||||||
|
|
||||||
// use instance symbol as default label
|
// use instance symbol as default label
|
||||||
if((rc = _cmDspUiUseInstSymbolAsLabel(ctx, inst, lblVarId, "TimeLine")) != kOkDspRC )
|
//if((rc = _cmDspUiUseInstSymbolAsLabel(ctx, inst, lblVarId, "TimeLine")) != kOkDspRC )
|
||||||
return rc;
|
// return rc;
|
||||||
|
|
||||||
// Set the kUiDsvFl on the variables used for the min/max/def/val for this scalar
|
// Set the kUiDsvFl on the variables used for the min/max/def/val for this scalar
|
||||||
// Setting this flag will cause their values to be sent to the UI whenever they change.
|
// Setting this flag will cause their values to be sent to the UI whenever they change.
|
||||||
cmDspInstVarSetFlags( ctx, inst, valVarId, kUiDsvFl );
|
|
||||||
cmDspInstVarSetFlags( ctx, inst, tlFileVarId, kUiDsvFl );
|
cmDspInstVarSetFlags( ctx, inst, tlFileVarId, kUiDsvFl );
|
||||||
cmDspInstVarSetFlags( ctx, inst, audPathVarId, kUiDsvFl );
|
cmDspInstVarSetFlags( ctx, inst, audPathVarId, kUiDsvFl );
|
||||||
|
cmDspInstVarSetFlags( ctx, inst, selVarId, kUiDsvFl );
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user