Browse Source

cmDspSys.c: Incoming MIDI messages are now dispatched to DSP objects via

broadcast message mechanism.

cmDspBuiltIn.c:Added _cmMidiInDC and _cmMidiOutDC.

cmDspPgm.c: Added _cmDspSysPgm_Test_Midi().
master
kevin 11 years ago
parent
commit
f4448e99b6
3 changed files with 298 additions and 6 deletions
  1. 240
    3
      dsp/cmDspBuiltIn.c
  2. 36
    1
      dsp/cmDspPgm.c
  3. 22
    2
      dsp/cmDspSys.c

+ 240
- 3
dsp/cmDspBuiltIn.c View File

@@ -40,6 +40,7 @@
40 40
 #include "cmMidi.h"
41 41
 #include "cmProc2.h"
42 42
 #include "cmVectOpsTemplateMain.h"
43
+#include "cmMidiPort.h"
43 44
 
44 45
 /*
45 46
 About variables:
@@ -982,6 +983,239 @@ struct cmDspClass_str* cmSigGenClassCons( cmDspCtx_t* ctx )
982 983
 //==========================================================================================================================================
983 984
 enum
984 985
 {
986
+  kDeviceMiId,
987
+  kPortMiId,
988
+  kSmpIdxMiId,
989
+  kStatusMiId,
990
+  kD0MiId,
991
+  kD1MiId
992
+};
993
+
994
+
995
+cmDspClass_t _cmMidiInDC;
996
+
997
+typedef struct
998
+{
999
+  cmDspInst_t inst;
1000
+  unsigned midiSymId;
1001
+  unsigned prevSmpIdx;
1002
+} cmDspMidiIn_t;
1003
+
1004
+cmDspInst_t*  _cmDspMidiInAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
1005
+{
1006
+  cmDspVarArg_t args[] =
1007
+  {
1008
+    { "device", kDeviceMiId, 0,  0,  kOutDsvFl | kUIntDsvFl, "MIDI device" },
1009
+    { "port",   kPortMiId,   0,  0,  kOutDsvFl | kUIntDsvFl, "MIDI device port"},
1010
+    { "smpidx", kSmpIdxMiId, 0,  0,  kOutDsvFl | kUIntDsvFl, "Message time tag as sample index."},
1011
+    { "status", kStatusMiId, 0,  0,  kOutDsvFl | kUIntDsvFl, "MIDI status" },
1012
+    { "d0",     kD0MiId,     0,  0,  kOutDsvFl | kUIntDsvFl, "MIDI channel message d0" },
1013
+    { "d1",     kD1MiId,     0,  0,  kOutDsvFl | kUIntDsvFl, "MIDI channel message d1" },
1014
+    { NULL, 0, 0, 0, 0 }
1015
+  };
1016
+
1017
+  cmDspMidiIn_t* p = cmDspInstAlloc(cmDspMidiIn_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
1018
+
1019
+ p->midiSymId =  cmDspSysAssignInstAttrSymbolStr( ctx->dspH, &p->inst, "_midi" );
1020
+
1021
+  return &p->inst;
1022
+}
1023
+
1024
+cmDspRC_t _cmDspMidiInReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1025
+{
1026
+  cmDspRC_t      rc = kOkDspRC;
1027
+  cmDspMidiIn_t* p  = (cmDspMidiIn_t*)inst;
1028
+  cmDspApplyAllDefaults(ctx,inst);
1029
+  p->prevSmpIdx = 0;
1030
+  return rc;
1031
+} 
1032
+
1033
+cmDspRC_t  _cmDspMidiInRecvFunc(   cmDspCtx_t* ctx, struct cmDspInst_str* inst,  unsigned attrSymId, const cmDspValue_t* value )
1034
+{
1035
+  cmDspMidiIn_t* p = (cmDspMidiIn_t*)inst;
1036
+
1037
+  if( attrSymId == p->midiSymId )
1038
+  {
1039
+    cmMidiPacket_t* pkt = (cmMidiPacket_t*)(value->u.m.u.vp);
1040
+    unsigned i;
1041
+
1042
+    cmDspSetUInt(ctx, inst, kDeviceMiId, pkt->devIdx);
1043
+    cmDspSetUInt(ctx, inst, kPortMiId,   pkt->portIdx); 
1044
+
1045
+    for(i=0; i<pkt->msgCnt; ++i)
1046
+    {
1047
+      cmMidiMsg* m = pkt->msgArray + i;
1048
+      unsigned   deltaSmpCnt = floor((m->deltaUs * cmDspSampleRate(ctx)) / 1000000.0);
1049
+
1050
+      if( p->prevSmpIdx == 0 )
1051
+        p->prevSmpIdx = ctx->cycleCnt * cmDspSamplesPerCycle(ctx);
1052
+      else
1053
+        p->prevSmpIdx += deltaSmpCnt;
1054
+
1055
+      cmDspSetUInt(ctx, inst, kSmpIdxMiId, p->prevSmpIdx );
1056
+      cmDspSetUInt(ctx, inst, kD1MiId,     m->d1 );
1057
+      cmDspSetUInt(ctx, inst, kD0MiId,     m->d0 );
1058
+      cmDspSetUInt(ctx, inst, kStatusMiId, m->status );
1059
+    }
1060
+  }
1061
+
1062
+  return kOkDspRC;
1063
+}
1064
+
1065
+struct cmDspClass_str* cmMidiInClassCons( cmDspCtx_t* ctx )
1066
+{
1067
+  cmDspClassSetup(&_cmMidiInDC,ctx,"MidiIn",
1068
+    NULL,
1069
+    _cmDspMidiInAlloc,
1070
+    NULL,
1071
+    _cmDspMidiInReset,
1072
+    NULL,
1073
+    NULL,
1074
+    NULL,
1075
+    _cmDspMidiInRecvFunc,
1076
+    "Midi input port");
1077
+
1078
+  return &_cmMidiInDC;
1079
+}
1080
+
1081
+//==========================================================================================================================================
1082
+enum
1083
+{
1084
+  kDeviceMoId,
1085
+  kPortMoId,
1086
+  kStatusMoId,
1087
+  kD0MoId,
1088
+  kD1MoId
1089
+};
1090
+
1091
+cmDspClass_t _cmMidiOutDC;
1092
+
1093
+typedef struct
1094
+{
1095
+  cmDspInst_t inst;
1096
+  unsigned    devIdx;
1097
+  unsigned    portIdx;
1098
+} cmDspMidiOut_t;
1099
+
1100
+cmDspRC_t _cmDspMidiOutSetDevice( cmDspCtx_t* ctx, cmDspMidiOut_t* p, const cmChar_t* deviceStr )
1101
+{
1102
+  cmDspRC_t rc = kOkDspRC;
1103
+
1104
+  if( deviceStr != NULL )
1105
+    if((p->devIdx = cmMpDeviceNameToIndex(deviceStr)) == cmInvalidIdx )
1106
+      rc = cmDspInstErr(ctx,&p->inst,kInvalidArgDspRC,"The MIDI device '%s' could not be found.",cmStringNullGuard(deviceStr));
1107
+
1108
+  return rc;
1109
+}
1110
+
1111
+cmDspRC_t _cmDspMidiOutSetPort( cmDspCtx_t* ctx, cmDspMidiOut_t* p, const cmChar_t* portStr )
1112
+{
1113
+  cmDspRC_t rc = kOkDspRC;
1114
+
1115
+  if( portStr == NULL )
1116
+    return rc;
1117
+
1118
+  if( p->devIdx == cmInvalidIdx )
1119
+    rc = cmDspInstErr(ctx,&p->inst,kInvalidArgDspRC,"The MIDI port cannot be set until the MIDI device is set.");
1120
+  else
1121
+  {
1122
+    if((p->portIdx = cmMpDevicePortNameToIndex(p->devIdx,kOutMpFl,portStr)) == cmInvalidIdx )
1123
+      rc = cmDspInstErr(ctx,&p->inst,kInvalidArgDspRC,"The MIDI port '%s' could not be found on device '%s'.",cmStringNullGuard(portStr),cmStringNullGuard(cmMpDeviceName(p->devIdx)));
1124
+  }
1125
+
1126
+  return rc;
1127
+}
1128
+
1129
+cmDspInst_t*  _cmDspMidiOutAlloc(cmDspCtx_t* ctx, cmDspClass_t* classPtr, unsigned storeSymId, unsigned instSymId, unsigned id, unsigned va_cnt, va_list vl )
1130
+{
1131
+  cmDspVarArg_t args[] =
1132
+  {
1133
+    { "device", kDeviceMoId, 0,  0,  kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "MIDI device name"},
1134
+    { "port",   kPortMoId,   0,  0,  kInDsvFl | kStrzDsvFl | kReqArgDsvFl, "MIDI port name"},
1135
+    { "status", kStatusMoId, 0,  0,  kInDsvFl | kUIntDsvFl, "MIDI status" },
1136
+    { "d0",     kD0MoId,     0,  0,  kInDsvFl | kUIntDsvFl, "MIDI channel message d0" },
1137
+    { "d1",     kD1MoId,     0,  0,  kInDsvFl | kUIntDsvFl, "MIDI channel message d1" },
1138
+    { NULL, 0, 0, 0, 0 }
1139
+  };
1140
+
1141
+  cmDspMidiOut_t* p = cmDspInstAlloc(cmDspMidiOut_t,ctx,classPtr,args,instSymId,id,storeSymId,va_cnt,vl);
1142
+
1143
+  p->devIdx  = cmInvalidIdx;
1144
+  p->portIdx = cmInvalidIdx;
1145
+
1146
+	cmDspSetDefaultUInt(ctx,&p->inst, kStatusMoId, 0, 0 );
1147
+  cmDspSetDefaultUInt(ctx,&p->inst, kD0MoId,     0, 0 );
1148
+  cmDspSetDefaultUInt(ctx,&p->inst, kD1MoId,     0, 0 );
1149
+  
1150
+  return &p->inst;
1151
+}
1152
+
1153
+cmDspRC_t _cmDspMidiOutReset(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1154
+{
1155
+  cmDspRC_t      rc = kOkDspRC;
1156
+  cmDspMidiOut_t* p = (cmDspMidiOut_t*)inst;
1157
+
1158
+  cmDspApplyAllDefaults(ctx,inst);
1159
+
1160
+  _cmDspMidiOutSetDevice(ctx,p,cmDspStrcz(inst,kDeviceMoId));
1161
+  _cmDspMidiOutSetPort(  ctx,p,cmDspStrcz(inst,kPortMoId));
1162
+
1163
+  return rc;
1164
+} 
1165
+
1166
+cmDspRC_t _cmDspMidiOutRecv(cmDspCtx_t* ctx, cmDspInst_t* inst, const cmDspEvt_t* evt )
1167
+{
1168
+  cmDspMidiOut_t* p = (cmDspMidiOut_t*)inst;
1169
+
1170
+  switch( evt->dstVarId )
1171
+  {
1172
+    case kDeviceMoId:      
1173
+      _cmDspMidiOutSetDevice(ctx, p, cmDsvStrcz(evt->valuePtr) );
1174
+      break;
1175
+
1176
+    case kPortMoId:
1177
+      _cmDspMidiOutSetPort(ctx, p, cmDsvStrcz(evt->valuePtr) );
1178
+      break;
1179
+
1180
+    case kStatusMoId:
1181
+      if( p->devIdx != cmInvalidIdx && p->portIdx != cmInvalidIdx )
1182
+      {
1183
+        unsigned status = cmDsvGetUInt(evt->valuePtr);
1184
+        unsigned d0     = cmDspUInt(inst,kD0MoId);
1185
+        unsigned d1     = cmDspUInt(inst,kD1MoId);
1186
+        if( cmMpDeviceSend( p->devIdx, p->portIdx, status, d0, d1 ) != kOkMpRC )
1187
+          cmDspInstErr(ctx,inst,kInvalidArgDspRC,"MIDI send failed.");
1188
+      }
1189
+      break;
1190
+
1191
+    default:
1192
+      cmDspSetEvent(ctx,inst,evt);
1193
+      break;
1194
+  }
1195
+
1196
+
1197
+  return kOkDspRC;
1198
+}
1199
+
1200
+struct cmDspClass_str* cmMidiOutClassCons( cmDspCtx_t* ctx )
1201
+{
1202
+  cmDspClassSetup(&_cmMidiOutDC,ctx,"MidiOut",
1203
+    NULL,
1204
+    _cmDspMidiOutAlloc,
1205
+    NULL,
1206
+    _cmDspMidiOutReset,
1207
+    NULL,
1208
+    _cmDspMidiOutRecv,
1209
+    NULL,
1210
+    NULL,
1211
+    "Midi input port");
1212
+
1213
+  return &_cmMidiOutDC;
1214
+}
1215
+
1216
+//==========================================================================================================================================
1217
+enum
1218
+{
985 1219
   kChAiId,
986 1220
   kGainAiId,
987 1221
   kOutAiId
@@ -2980,7 +3214,7 @@ cmDspRC_t _cmDspWaveTableReadAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p, un
2980 3214
 
2981 3215
 cmDspRC_t _cmDspWaveTableInitAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p )
2982 3216
 {
2983
-  cmDspRC_t         rc;
3217
+  cmDspRC_t         rc = kOkDspRC;
2984 3218
   cmAudioFileH_t    afH;
2985 3219
   cmRC_t            afRC;
2986 3220
   cmAudioFileInfo_t afInfo;
@@ -2992,7 +3226,7 @@ cmDspRC_t _cmDspWaveTableInitAudioFile( cmDspCtx_t* ctx, cmDspWaveTable_t* p )
2992 3226
   // if the file name is valid
2993 3227
   if( fn == NULL || strlen(fn)==0 )
2994 3228
   {
2995
-     cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"Audio file loading was requested for the wave table but no file name was given.");
3229
+     rc = cmDspInstErr(ctx,&p->inst,kVarNotValidDspRC,"Audio file loading was requested for the wave table but no file name was given.");
2996 3230
      goto errLabel;
2997 3231
   }
2998 3232
 
@@ -3468,7 +3702,7 @@ cmDspRC_t _cmSprintfGetInputTypes( cmDspCtx_t* ctx, cmDspClass_t* classPtr, cons
3468 3702
         snprintf(fmtArray[j].label,kSprintfLabelCharCnt,"in-%i",j);
3469 3703
 
3470 3704
         fmtArray[j].label[kSprintfLabelCharCnt]=0;
3471
-        fmtArray[j].label[kSprintfDocCharCnt] = 0;
3705
+        fmtArray[j].doc[kSprintfDocCharCnt] = 0;
3472 3706
 
3473 3707
         switch( fmt[ i + fn - 1 ] )
3474 3708
         {
@@ -4942,6 +5176,8 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
4942 5176
   cmCounterClassCons,
4943 5177
 
4944 5178
   cmPhasorClassCons,
5179
+  cmMidiOutClassCons,
5180
+  cmMidiInClassCons,
4945 5181
   cmAudioInClassCons,
4946 5182
   cmAudioOutClassCons,
4947 5183
   cmAudioFileOutClassCons,
@@ -5018,6 +5254,7 @@ cmDspClassConsFunc_t _cmDspClassBuiltInArray[] =
5018 5254
   cmScFolClassCons,
5019 5255
   cmScModClassCons,
5020 5256
   cmGSwitchClassCons,
5257
+  cmScaleRangeClassCons,
5021 5258
 
5022 5259
   NULL,
5023 5260
 };

+ 36
- 1
dsp/cmDspPgm.c View File

@@ -25,6 +25,40 @@
25 25
 #include "cmDspPgmPP.h"
26 26
 #include "cmDspPgmKr.h"
27 27
 
28
+cmDspRC_t _cmDspSysPgm_Test_Midi( cmDspSysH_t h, void** userPtrPtr )
29
+{
30
+  cmDspRC_t rc = kOkDspRC;
31
+
32
+  cmDspInst_t* sendBtn = cmDspSysAllocInst( h,"Button", "Send",    2, kButtonDuiId, 0.0 );
33
+  cmDspInst_t* status  = cmDspSysAllocInst( h,"Scalar", "Status",  5, kNumberDuiId, 0.0,  127.0, 1.0,  144.0);
34
+  cmDspInst_t* d0      = cmDspSysAllocInst( h,"Scalar", "D0",      5, kNumberDuiId, 0.0,  127.0, 1.0,  64.0);
35
+  cmDspInst_t* d1      = cmDspSysAllocInst( h,"Scalar", "D1",      5, kNumberDuiId, 0.0,  127.0, 1.0,  64.0);
36
+  cmDspInst_t* midiOut = cmDspSysAllocInst( h,"MidiOut", NULL,     2, "Fastlane", "Fastlane MIDI A");
37
+  cmDspInst_t* midiIn  = cmDspSysAllocInst( h,"MidiIn",  NULL,     0 );
38
+  cmDspInst_t* printer = cmDspSysAllocInst( h,"Printer", NULL,     1, ">" );
39
+
40
+  // check for allocation errors
41
+  if((rc = cmDspSysLastRC(h)) != kOkDspRC )
42
+    goto errLabel;
43
+
44
+  cmDspSysInstallCb(   h, sendBtn, "out", d1,      "send", NULL);
45
+  cmDspSysInstallCb(   h, sendBtn, "out", d0,      "send", NULL);
46
+  cmDspSysInstallCb(   h, sendBtn, "out", status,  "send", NULL);
47
+
48
+  cmDspSysInstallCb(   h, status,  "val", midiOut, "status",NULL);
49
+  cmDspSysInstallCb(   h, d0,      "val", midiOut, "d0",    NULL);
50
+  cmDspSysInstallCb(   h, d1,      "val", midiOut, "d1",    NULL);
51
+
52
+  cmDspSysInstallCb(   h, midiIn,  "status", printer, "in", NULL);
53
+  cmDspSysInstallCb(   h, midiIn,  "d0",     printer, "in", NULL);
54
+  cmDspSysInstallCb(   h, midiIn,  "d1",     printer, "in", NULL);
55
+  cmDspSysInstallCb(   h, midiIn,  "smpidx", printer, "in", NULL);
56
+
57
+ errLabel:
58
+  return rc;
59
+  
60
+}
61
+
28 62
 cmDspRC_t _cmDspSysPgm_Stereo_Through( cmDspSysH_t h, void** userPtrPtr )
29 63
 {
30 64
   bool useBuiltInFl = true;
@@ -2332,7 +2366,7 @@ cmDspRC_t _cmDspSysPgm_AvailCh( cmDspSysH_t h, void** userPtrPtr )
2332 2366
   cmDspInst_t* fwtp  =  cmDspSysAllocInst( h, "WaveTable", NULL,   5, ((int)cmDspSysSampleRate(h)), 1, fn, -1, 7000000 );
2333 2367
   cmDspInst_t* fad0  =  cmDspSysAllocInst( h, "Xfader",    NULL,   3, xfadeChCnt,  xfadeMs, xfadeInitFl ); 
2334 2368
 
2335
-  cmDspInst_t*  prp  = cmDspSysAllocInst(  h, "Printer",  NULL, 1, ">" );
2369
+  //cmDspInst_t*  prp  = cmDspSysAllocInst(  h, "Printer",  NULL, 1, ">" );
2336 2370
 
2337 2371
   cmDspInst_t* ao0p = cmDspSysAllocInst(h,"AudioOut",  NULL,   1, 0 );
2338 2372
   cmDspInst_t* ao1p = cmDspSysAllocInst(h,"AudioOut",  NULL,   1, 1 );
@@ -2389,6 +2423,7 @@ _cmDspSysPgm_t _cmDspSysPgmArray[] =
2389 2423
   { "pickup tails", _cmDspSysPgm_NoiseTails,    NULL, NULL },
2390 2424
   { "tails_2",      _cmDspSysPgm_NoiseTails2,   NULL, NULL },
2391 2425
   { "pickups",     _cmDspSysPgm_Pickups0,       NULL, NULL },
2426
+  { "midi_test",   _cmDspSysPgm_Test_Midi,      NULL, NULL },
2392 2427
   { "2_thru",      _cmDspSysPgm_Stereo_Through, NULL, NULL },
2393 2428
   { "guitar",      _cmDspSysPgmGuitar,          NULL, NULL },
2394 2429
   { "2_fx",        _cmDspSysPgm_Stereo_Fx,      NULL, NULL },

+ 22
- 2
dsp/cmDspSys.c View File

@@ -10,6 +10,7 @@
10 10
 #include "cmText.h"
11 11
 #include "cmFileSys.h"
12 12
 #include "cmSymTbl.h"
13
+#include "cmMidi.h"
13 14
 #include "cmJson.h"
14 15
 #include "cmPrefs.h"
15 16
 #include "cmDspValue.h"
@@ -619,10 +620,13 @@ cmDspRC_t cmDspSysRcvMsg(    cmDspSysH_t h, cmAudioSysCtx_t* asCtx, const void*
619 620
   }
620 621
   else
621 622
   {
623
+    unsigned* hdr = (unsigned*)msgPtr;
624
+
622 625
     // the msg selector is the second field in the data packet (following the audio system sub-system id)
623
-    const unsigned msgTypeSelId = ((const unsigned*)msgPtr)[1];
626
+    //const unsigned msgTypeSelId = ((const unsigned*)msgPtr)[1];
627
+    
624 628
 
625
-    switch( msgTypeSelId )
629
+    switch( hdr[1] )
626 630
     {
627 631
       case kUiSelAsId:
628 632
         _cmDspSysHandleUiMsg(p,ip,msgPtr,msgByteCnt);
@@ -633,11 +637,27 @@ cmDspRC_t cmDspSysRcvMsg(    cmDspSysH_t h, cmAudioSysCtx_t* asCtx, const void*
633 637
         break;
634 638
 
635 639
       case kMidiMsgArraySelAsId:
640
+        {
641
+          cmMidiPacket_t pkt;
642
+          cmDspValue_t   v;
643
+
644
+          pkt.cbDataPtr = NULL;
645
+          pkt.devIdx    = hdr[2];
646
+          pkt.portIdx   = hdr[3];
647
+          pkt.msgCnt    = hdr[4];
648
+          pkt.msgArray  = (cmMidiMsg*)(hdr + 5);
649
+          unsigned     midiSymId = cmDspSysRegisterStaticSymbol(h,"_midi");
650
+
651
+          v.u.m.u.vp = &pkt;
652
+          cmDspSysBroadcastValue(h, midiSymId, &v);
653
+
654
+          
636 655
         /*
637 656
         // data format for MIDI messages
638 657
         { kMidiMsgArraytSelAsId, devIdx, portIdx, msgCnt, msgArray[msgCnt] }
639 658
         where each msgArray[] record is a cmMidiMsg record.
640 659
         */
660
+        }
641 661
         break;
642 662
 
643 663
     }

Loading…
Cancel
Save