|
@@ -1918,6 +1918,31 @@ struct cmDspClass_str* cmActiveMeasClassCons( cmDspCtx_t* ctx )
|
1918
|
1918
|
|
1919
|
1919
|
//==========================================================================================================================================
|
1920
|
1920
|
// Audio MIDI Sync
|
|
1921
|
+/*
|
|
1922
|
+ Usage:
|
|
1923
|
+ 1) In the program resource file setup a list of sync points.
|
|
1924
|
+ 'asmp' refers to a sample offset into the audio file 'af'
|
|
1925
|
+ which should match to the midi event index 'mid' in the
|
|
1926
|
+ midi file 'mf'.
|
|
1927
|
+
|
|
1928
|
+ amSync :
|
|
1929
|
+ [
|
|
1930
|
+ { af:"af-16" asmp:34735276 mf:"mf-10" mid:350 }
|
|
1931
|
+ { af:"af-16" asmp:71802194 mf:"mf-10" mid:787 }
|
|
1932
|
+ ]
|
|
1933
|
+
|
|
1934
|
+ 2) Feed the 'fidx' output from a wave table loaded with 'af' into the 'asmp' input port of this amSync object.
|
|
1935
|
+ Feed the 'id' output from the MIDI file player loaded with 'mf' into the 'mid' input port of this amSync object.
|
|
1936
|
+
|
|
1937
|
+ 3) Run the players.
|
|
1938
|
+ 4) When the run is complete send any message to the 'sel' port of this amSync object.
|
|
1939
|
+ The 'frm:' field of the printed output gives the difference in samples between
|
|
1940
|
+ MIDI and audio sync points.
|
|
1941
|
+
|
|
1942
|
+ If the value is positive then the MIDI point is after the Audio point.
|
|
1943
|
+ If the value is negative then the MIDI point is before the audio point.
|
|
1944
|
+
|
|
1945
|
+*/
|
1921
|
1946
|
|
1922
|
1947
|
enum
|
1923
|
1948
|
{
|
|
@@ -1944,8 +1969,8 @@ typedef struct cmDspAmSyncEntry_str
|
1944
|
1969
|
const cmChar_t* mfn; // midi file name
|
1945
|
1970
|
unsigned asmp; // Audio sample index to sync to MIDI event
|
1946
|
1971
|
unsigned mid; // MIDI event unique id (cmMidiTrackMsg_t.uid)
|
1947
|
|
- int afi; //
|
1948
|
|
- int mfi;
|
|
1972
|
+ int afi; // closest DSP system cycle index to the reference audio sample index (asmp).
|
|
1973
|
+ int mfi; // DSP system cycle on which the reference MIDI event (mid) arrived.
|
1949
|
1974
|
unsigned state; // as incoming msg match this record the state is updated with kXXXAmFl flags
|
1950
|
1975
|
} cmDspAmSyncEntry_t;
|
1951
|
1976
|
|
|
@@ -2093,7 +2118,7 @@ cmDspRC_t _cmDspAmSyncRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
2093
|
2118
|
|
2094
|
2119
|
case kMFnAmId:
|
2095
|
2120
|
{
|
2096
|
|
- // an midi file name just arrived - set p->mcur to point to it
|
|
2121
|
+ // a midi file name just arrived - set p->mcur to point to it
|
2097
|
2122
|
const cmChar_t* fn = cmDspStrcz(inst, kMFnAmId );
|
2098
|
2123
|
for(i=0; i<p->arrayCnt; ++i)
|
2099
|
2124
|
if( strcmp(fn,p->array[i].mfn) == 0 )
|
|
@@ -2113,6 +2138,9 @@ cmDspRC_t _cmDspAmSyncRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
2113
|
2138
|
if( p->acur != NULL )
|
2114
|
2139
|
for(i=0; i<p->arrayCnt; ++i)
|
2115
|
2140
|
{
|
|
2141
|
+ // if the audio sync point is before or on the new audio file sample index then
|
|
2142
|
+ // this is the closest audio file index to the audio sync point - record the
|
|
2143
|
+ // associated cycleCnt
|
2116
|
2144
|
cmDspAmSyncEntry_t* r = p->array + i;
|
2117
|
2145
|
if( cmIsNotFlag(r->state,kAsmpAmFl) && r->asmp <= v && strcmp(p->acur->afn,r->afn)==0 )
|
2118
|
2146
|
{
|
|
@@ -2126,10 +2154,13 @@ cmDspRC_t _cmDspAmSyncRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t*
|
2126
|
2154
|
|
2127
|
2155
|
case kMIdAmId:
|
2128
|
2156
|
{
|
|
2157
|
+ // a new MIDI event was received
|
2129
|
2158
|
int v = cmDspInt(inst,kMIdAmId);
|
2130
|
2159
|
if( p->mcur != NULL )
|
2131
|
2160
|
for(i=0; i<p->arrayCnt; ++i)
|
2132
|
2161
|
{
|
|
2162
|
+ // if the new MIDI event matched the MIDI sync point then record the
|
|
2163
|
+ // current cycleCnt.
|
2133
|
2164
|
cmDspAmSyncEntry_t* r = p->array + i;
|
2134
|
2165
|
if( cmIsNotFlag(r->state,kMidAmFl) && r->mid == v && strcmp(p->mcur->mfn,r->mfn)==0 )
|
2135
|
2166
|
{
|