|
@@ -15,8 +15,8 @@
|
15
|
15
|
#include "cmAudioPort.h"
|
16
|
16
|
#include "cmUdpPort.h"
|
17
|
17
|
#include "cmUdpNet.h"
|
18
|
|
-#include "cmAudioSysMsg.h"
|
19
|
|
-#include "cmAudioSys.h"
|
|
18
|
+#include "cmRtSysMsg.h"
|
|
19
|
+#include "cmRtSys.h"
|
20
|
20
|
|
21
|
21
|
#include "cmDevCfg.h"
|
22
|
22
|
|
|
@@ -146,6 +146,8 @@ void _cmDcmDuplNet( cmDcmNet_t* d, const cmDcmNet_t* s )
|
146
|
146
|
{
|
147
|
147
|
d->sockAddr = cmMemAllocStr(s->sockAddr);
|
148
|
148
|
d->portNumber = s->portNumber;
|
|
149
|
+ d->localFl = s->localFl;
|
|
150
|
+ d->activeFl = s->activeFl;
|
149
|
151
|
}
|
150
|
152
|
|
151
|
153
|
|
|
@@ -446,11 +448,11 @@ unsigned cmDevCfgLabelToIndex( cmDevCfgH_t h, cmTypeDcmId_t typeId, const cmChar
|
446
|
448
|
if( cp->typeId == typeId )
|
447
|
449
|
{
|
448
|
450
|
if( strcmp(cp->dcLabelStr,label)==0 )
|
449
|
|
- break;
|
|
451
|
+ return n;
|
450
|
452
|
++n;
|
451
|
453
|
}
|
452
|
454
|
|
453
|
|
- return n;
|
|
455
|
+ return cmInvalidIdx;
|
454
|
456
|
}
|
455
|
457
|
|
456
|
458
|
cmDcmCfg_t* _cmDcmFindOrCreateCfg( cmDcm_t* p, cmTypeDcmId_t typeId, const cmChar_t* dcLabelStr )
|
|
@@ -676,6 +678,27 @@ const cmDcmMidi_t* cmDevCfgMidiDevMap( cmDevCfgH_t h, unsigned usrAppId, unsigne
|
676
|
678
|
return &mp->cfg->u.m;
|
677
|
679
|
}
|
678
|
680
|
|
|
681
|
+const cmDcmMidi_t* cmDevCfgMidiCfgFromLabel( cmDevCfgH_t h, const cmChar_t* cfgLabel )
|
|
682
|
+{
|
|
683
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
684
|
+ const cmDcmMidi_t* c;
|
|
685
|
+ unsigned idx;
|
|
686
|
+
|
|
687
|
+ if((idx = cmDevCfgLabelToIndex(h, kMidiDcmTId, cfgLabel )) == cmInvalidIdx )
|
|
688
|
+ {
|
|
689
|
+ cmErrMsg(&p->err,kLabelNotFoundDcRC,"The MIDI cfg. '%s' was not found.",cmStringNullGuard(cfgLabel));
|
|
690
|
+ return NULL;
|
|
691
|
+ }
|
|
692
|
+
|
|
693
|
+ if((c = cmDevCfgMidiCfg(h,idx)) == NULL )
|
|
694
|
+ {
|
|
695
|
+ cmErrMsg(&p->err,kInvalidCfgIdxDcRC,"The MIDI cfg. index %i is invalid.",idx);
|
|
696
|
+ return NULL;
|
|
697
|
+ }
|
|
698
|
+
|
|
699
|
+ return c;
|
|
700
|
+}
|
|
701
|
+
|
679
|
702
|
|
680
|
703
|
cmDcRC_t cmDevCfgNameAudioPort(
|
681
|
704
|
cmDevCfgH_t h,
|
|
@@ -687,24 +710,27 @@ cmDcRC_t cmDevCfgNameAudioPort(
|
687
|
710
|
unsigned devFramesPerCycle,
|
688
|
711
|
unsigned dspFramesPerCycle,
|
689
|
712
|
unsigned audioBufCnt,
|
690
|
|
- double srate )
|
|
713
|
+ double srate,
|
|
714
|
+ bool activeFl )
|
691
|
715
|
{
|
692
|
716
|
cmDcm_t* p = _cmDcmHandleToPtr(h);
|
693
|
717
|
cmDcmCfg_t* cp;
|
694
|
|
- unsigned inDevIdx;
|
695
|
|
- unsigned outDevIdx;
|
|
718
|
+ unsigned inDevIdx = cmInvalidIdx;
|
|
719
|
+ unsigned outDevIdx = cmInvalidIdx;
|
696
|
720
|
|
697
|
721
|
// validate the label
|
698
|
722
|
if((dcLabelStr = _cmDcmTrimLabel(p,dcLabelStr,"Audio cfg")) == NULL)
|
699
|
723
|
return cmErrLastRC(&p->err);
|
700
|
724
|
|
701
|
725
|
// validate the input device
|
702
|
|
- if(( inDevIdx = cmApDeviceLabelToIndex(inDevNameStr)) == cmInvalidIdx )
|
703
|
|
- return cmErrMsg(&p->err, kInvalidArgDcRC,"The input audio device name '%s' is not valid.",cmStringNullGuard(inDevNameStr));
|
|
726
|
+ if( inDevNameStr != NULL )
|
|
727
|
+ if(( inDevIdx = cmApDeviceLabelToIndex(inDevNameStr)) == cmInvalidIdx )
|
|
728
|
+ return cmErrMsg(&p->err, kInvalidArgDcRC,"The input audio device name '%s' is not valid.",cmStringNullGuard(inDevNameStr));
|
704
|
729
|
|
705
|
730
|
// validate the output device
|
706
|
|
- if(( outDevIdx = cmApDeviceLabelToIndex(outDevNameStr)) == cmInvalidIdx )
|
707
|
|
- return cmErrMsg(&p->err, kInvalidArgDcRC,"The output audio device name '%s' is not valid.",cmStringNullGuard(outDevNameStr));
|
|
731
|
+ if( outDevNameStr != NULL )
|
|
732
|
+ if(( outDevIdx = cmApDeviceLabelToIndex(outDevNameStr)) == cmInvalidIdx )
|
|
733
|
+ return cmErrMsg(&p->err, kInvalidArgDcRC,"The output audio device name '%s' is not valid.",cmStringNullGuard(outDevNameStr));
|
708
|
734
|
|
709
|
735
|
// validate the msg byte cnt
|
710
|
736
|
if( msgQueueByteCnt == 0 )
|
|
@@ -730,8 +756,9 @@ cmDcRC_t cmDevCfgNameAudioPort(
|
730
|
756
|
unsigned inChCnt = cmApDeviceChannelCount( inDevIdx, true );
|
731
|
757
|
unsigned outChCnt = cmApDeviceChannelCount( outDevIdx, false );
|
732
|
758
|
|
733
|
|
- cp->u.a.inDevLabelStr = cmMemAllocStr(inDevNameStr);
|
734
|
|
- cp->u.a.outDevLabelStr = cmMemAllocStr(outDevNameStr);
|
|
759
|
+ cp->u.a.inDevLabelStr = cmMemAllocStr(inDevNameStr==NULL?"":inDevNameStr);
|
|
760
|
+ cp->u.a.outDevLabelStr = cmMemAllocStr(outDevNameStr==NULL?"":outDevNameStr);
|
|
761
|
+ cp->u.a.activeFl = activeFl;
|
735
|
762
|
cp->u.a.audioSysArgs.rpt = p->err.rpt;
|
736
|
763
|
cp->u.a.audioSysArgs.inDevIdx = inDevIdx;
|
737
|
764
|
cp->u.a.audioSysArgs.outDevIdx = outDevIdx;
|
|
@@ -741,7 +768,7 @@ cmDcRC_t cmDevCfgNameAudioPort(
|
741
|
768
|
cp->u.a.audioSysArgs.dspFramesPerCycle = dspFramesPerCycle;
|
742
|
769
|
cp->u.a.audioSysArgs.audioBufCnt = audioBufCnt;
|
743
|
770
|
cp->u.a.audioSysArgs.srate = srate;
|
744
|
|
- cp->descStr = cmTsPrintfP(cp->descStr,"In: Chs:%i %s\nOut: Chs:%i %s",inChCnt,inDevNameStr,outChCnt,outDevNameStr);
|
|
771
|
+ cp->descStr = cmTsPrintfP(cp->descStr,"%sIn: Chs:%i %s\nOut: Chs:%i %s",activeFl?"":"INACTIVE ",inChCnt,cp->u.a.inDevLabelStr,outChCnt,cp->u.a.outDevLabelStr);
|
745
|
772
|
return kOkDcRC;
|
746
|
773
|
}
|
747
|
774
|
|
|
@@ -794,6 +821,115 @@ unsigned cmDevCfgAudioGetDefaultCfgIndex( cmDevCfgH_t h )
|
794
|
821
|
return cmInvalidIdx;
|
795
|
822
|
}
|
796
|
823
|
|
|
824
|
+bool cmDevCfgAudioIsDeviceActive( cmDevCfgH_t h, const cmChar_t* devNameStr, bool inputFl )
|
|
825
|
+{
|
|
826
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
827
|
+
|
|
828
|
+ assert( p->clp != NULL );
|
|
829
|
+
|
|
830
|
+ cmDcmCfg_t* cp = p->clp->cfg;
|
|
831
|
+ unsigned i;
|
|
832
|
+
|
|
833
|
+ for(i=0; cp!=NULL; cp=cp->next)
|
|
834
|
+ if( cp->typeId == kAudioDcmTId )
|
|
835
|
+ {
|
|
836
|
+ bool fl;
|
|
837
|
+
|
|
838
|
+ if( inputFl )
|
|
839
|
+ fl = strcmp(devNameStr,cp->u.a.inDevLabelStr)==0;
|
|
840
|
+ else
|
|
841
|
+ fl = strcmp(devNameStr,cp->u.a.outDevLabelStr)==0;
|
|
842
|
+
|
|
843
|
+ if( fl )
|
|
844
|
+ return cp->u.a.activeFl;
|
|
845
|
+
|
|
846
|
+ ++i;
|
|
847
|
+ }
|
|
848
|
+
|
|
849
|
+ return false;
|
|
850
|
+}
|
|
851
|
+
|
|
852
|
+unsigned cmDevCfgAudioActiveCount( cmDevCfgH_t h )
|
|
853
|
+{
|
|
854
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
855
|
+
|
|
856
|
+ assert( p->clp != NULL );
|
|
857
|
+
|
|
858
|
+ cmDcmCfg_t* cp = p->clp->cfg;
|
|
859
|
+ unsigned n;
|
|
860
|
+
|
|
861
|
+ for(n=0; cp!=NULL; cp=cp->next)
|
|
862
|
+ if( cp->typeId == kAudioDcmTId && cp->u.a.activeFl )
|
|
863
|
+ ++n;
|
|
864
|
+
|
|
865
|
+ return n;
|
|
866
|
+}
|
|
867
|
+
|
|
868
|
+const cmChar_t* cmDevCfgAudioActiveLabel( cmDevCfgH_t h, unsigned idx )
|
|
869
|
+{
|
|
870
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
871
|
+
|
|
872
|
+ assert( p->clp != NULL );
|
|
873
|
+
|
|
874
|
+ cmDcmCfg_t* cp = p->clp->cfg;
|
|
875
|
+ unsigned i;
|
|
876
|
+
|
|
877
|
+ for(i=0; cp!=NULL; cp=cp->next)
|
|
878
|
+ if( cp->typeId == kAudioDcmTId && cp->u.a.activeFl )
|
|
879
|
+ {
|
|
880
|
+ if( i == idx )
|
|
881
|
+ return cp->dcLabelStr;
|
|
882
|
+ ++i;
|
|
883
|
+ }
|
|
884
|
+
|
|
885
|
+ assert(0);
|
|
886
|
+ return NULL;
|
|
887
|
+}
|
|
888
|
+
|
|
889
|
+const cmDcmAudio_t* cmDevCfgAudioActiveCfg( cmDevCfgH_t h, unsigned idx )
|
|
890
|
+{
|
|
891
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
892
|
+
|
|
893
|
+ assert( p->clp != NULL );
|
|
894
|
+
|
|
895
|
+ cmDcmCfg_t* cp = p->clp->cfg;
|
|
896
|
+ unsigned i;
|
|
897
|
+
|
|
898
|
+ for(i=0; cp!=NULL; cp=cp->next)
|
|
899
|
+ if( cp->typeId == kAudioDcmTId && cp->u.a.activeFl )
|
|
900
|
+ {
|
|
901
|
+ if( i == idx )
|
|
902
|
+ return &cp->u.a;
|
|
903
|
+ ++i;
|
|
904
|
+ }
|
|
905
|
+
|
|
906
|
+ assert(0);
|
|
907
|
+ return NULL;
|
|
908
|
+}
|
|
909
|
+
|
|
910
|
+unsigned cmDevCfgAudioActiveIndex( cmDevCfgH_t h, const cmChar_t* cfgLabel )
|
|
911
|
+{
|
|
912
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
913
|
+
|
|
914
|
+ if( cfgLabel == NULL )
|
|
915
|
+ return cmInvalidIdx;
|
|
916
|
+
|
|
917
|
+ assert( p->clp != NULL );
|
|
918
|
+
|
|
919
|
+ cmDcmCfg_t* cp = p->clp->cfg;
|
|
920
|
+ unsigned i;
|
|
921
|
+
|
|
922
|
+ for(i=0; cp!=NULL; cp=cp->next)
|
|
923
|
+ if( cp->typeId == kAudioDcmTId && cp->u.a.activeFl)
|
|
924
|
+ {
|
|
925
|
+ if( cp->dcLabelStr!=NULL && strcmp(cp->dcLabelStr,cfgLabel) == 0 )
|
|
926
|
+ return i;
|
|
927
|
+ ++i;
|
|
928
|
+ }
|
|
929
|
+
|
|
930
|
+ return cmInvalidIdx;
|
|
931
|
+}
|
|
932
|
+
|
797
|
933
|
|
798
|
934
|
const cmDcmAudio_t* cmDevCfgAudioCfg( cmDevCfgH_t h, unsigned cfgIdx )
|
799
|
935
|
{
|
|
@@ -822,7 +958,9 @@ cmDcRC_t cmDevCfgNameNetPort(
|
822
|
958
|
cmDevCfgH_t h,
|
823
|
959
|
const cmChar_t* dcLabelStr,
|
824
|
960
|
const cmChar_t* sockAddr,
|
825
|
|
- unsigned portNumber )
|
|
961
|
+ unsigned portNumber,
|
|
962
|
+ bool localFl,
|
|
963
|
+ bool activeFl)
|
826
|
964
|
{
|
827
|
965
|
|
828
|
966
|
cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
@@ -832,7 +970,7 @@ cmDcRC_t cmDevCfgNameNetPort(
|
832
|
970
|
return cmErrMsg(&p->err,kInvalidArgDcRC,"The network port number %i is invalid. The valid IP port number range is:0-0xffff.");
|
833
|
971
|
|
834
|
972
|
// validate the label
|
835
|
|
- if((dcLabelStr = _cmDcmTrimLabel(p,dcLabelStr,"MIDI cfg")) == NULL)
|
|
973
|
+ if((dcLabelStr = _cmDcmTrimLabel(p,dcLabelStr,"Net cfg")) == NULL)
|
836
|
974
|
return cmErrLastRC(&p->err);
|
837
|
975
|
|
838
|
976
|
// if dcLabelStr is already in use for this location and type then update
|
|
@@ -840,14 +978,54 @@ cmDcRC_t cmDevCfgNameNetPort(
|
840
|
978
|
if((cp = _cmDcmFindOrCreateCfg(p,kNetDcmTId, dcLabelStr)) == NULL )
|
841
|
979
|
return cmErrLastRC(&p->err);
|
842
|
980
|
|
843
|
|
- cp->u.n.sockAddr = cmMemAllocStr(sockAddr);
|
|
981
|
+ cp->u.n.sockAddr = cmMemAllocStr(sockAddr);
|
844
|
982
|
cp->u.n.portNumber = portNumber;
|
845
|
|
- cp->descStr = cmTsPrintfP(cp->descStr,"%s:%i",sockAddr,portNumber);
|
|
983
|
+ cp->u.n.localFl = localFl;
|
|
984
|
+ cp->u.n.activeFl = activeFl;
|
|
985
|
+ cp->descStr = cmTsPrintfP(cp->descStr,"%s %s %s:%i",activeFl?"":"INACTIVE",localFl?"local":"remote",sockAddr,portNumber);
|
846
|
986
|
|
847
|
987
|
|
848
|
988
|
return kOkDcRC;
|
849
|
989
|
}
|
850
|
990
|
|
|
991
|
+unsigned cmDevCfgNetActiveCount( cmDevCfgH_t h )
|
|
992
|
+{
|
|
993
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
994
|
+
|
|
995
|
+ assert( p->clp != NULL );
|
|
996
|
+
|
|
997
|
+ cmDcmCfg_t* cp = p->clp->cfg;
|
|
998
|
+ unsigned n;
|
|
999
|
+
|
|
1000
|
+ for(n=0; cp!=NULL; cp=cp->next)
|
|
1001
|
+ if( cp->typeId == kNetDcmTId && cp->u.a.activeFl )
|
|
1002
|
+ ++n;
|
|
1003
|
+
|
|
1004
|
+ return n;
|
|
1005
|
+}
|
|
1006
|
+
|
|
1007
|
+const cmDcmNet_t* cmDevCfgNetActiveCfg( cmDevCfgH_t h, unsigned idx )
|
|
1008
|
+{
|
|
1009
|
+ cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
1010
|
+
|
|
1011
|
+ assert( p->clp != NULL );
|
|
1012
|
+
|
|
1013
|
+ cmDcmCfg_t* cp = p->clp->cfg;
|
|
1014
|
+ unsigned i;
|
|
1015
|
+
|
|
1016
|
+ for(i=0; cp!=NULL; cp=cp->next)
|
|
1017
|
+ if( cp->typeId == kNetDcmTId && cp->u.a.activeFl )
|
|
1018
|
+ {
|
|
1019
|
+ if( i == idx )
|
|
1020
|
+ return &cp->u.n;
|
|
1021
|
+ ++i;
|
|
1022
|
+ }
|
|
1023
|
+
|
|
1024
|
+ assert(0);
|
|
1025
|
+ return NULL;
|
|
1026
|
+}
|
|
1027
|
+
|
|
1028
|
+
|
851
|
1029
|
const cmDcmNet_t* cmDevCfgNetCfg( cmDevCfgH_t h, unsigned cfgIdx )
|
852
|
1030
|
{
|
853
|
1031
|
cmDcm_t* p = _cmDcmHandleToPtr(h);
|
|
@@ -1159,6 +1337,7 @@ cmDcRC_t _cmDevCfgRead( cmDcm_t* p, cmJsonH_t jsH, const cmJsonNode_t* rootObjPt
|
1159
|
1337
|
"dspFramesPerCycle", kIntTId, &a.audioSysArgs.dspFramesPerCycle,
|
1160
|
1338
|
"audioBufCnt", kIntTId, &a.audioSysArgs.audioBufCnt,
|
1161
|
1339
|
"srate", kRealTId, &a.audioSysArgs.srate,
|
|
1340
|
+ "active", kBoolTId, &a.activeFl,
|
1162
|
1341
|
NULL ) != kOkJsRC )
|
1163
|
1342
|
{
|
1164
|
1343
|
rc = _cmDcmJsonSyntaxErr(p,errLabelPtr);
|
|
@@ -1171,7 +1350,8 @@ cmDcRC_t _cmDevCfgRead( cmDcm_t* p, cmJsonH_t jsH, const cmJsonNode_t* rootObjPt
|
1171
|
1350
|
a.audioSysArgs.devFramesPerCycle,
|
1172
|
1351
|
a.audioSysArgs.dspFramesPerCycle,
|
1173
|
1352
|
a.audioSysArgs.audioBufCnt,
|
1174
|
|
- a.audioSysArgs.srate )) != kOkDcRC )
|
|
1353
|
+ a.audioSysArgs.srate,
|
|
1354
|
+ a.activeFl)) != kOkDcRC )
|
1175
|
1355
|
{
|
1176
|
1356
|
goto errLabel;
|
1177
|
1357
|
}
|
|
@@ -1182,13 +1362,15 @@ cmDcRC_t _cmDevCfgRead( cmDcm_t* p, cmJsonH_t jsH, const cmJsonNode_t* rootObjPt
|
1182
|
1362
|
if( cmJsonMemberValues( cfgObjNp, &errLabelPtr,
|
1183
|
1363
|
"sockAddr", kStringTId, &n.sockAddr,
|
1184
|
1364
|
"portNumber", kIntTId, &n.portNumber,
|
|
1365
|
+ "localFl", kBoolTId, &n.localFl,
|
|
1366
|
+ "activeFl", kBoolTId, &n.activeFl,
|
1185
|
1367
|
NULL ) != kOkJsRC )
|
1186
|
1368
|
{
|
1187
|
1369
|
rc = _cmDcmJsonSyntaxErr(p,errLabelPtr);
|
1188
|
1370
|
goto errLabel;
|
1189
|
1371
|
}
|
1190
|
1372
|
|
1191
|
|
- if((rc = cmDevCfgNameNetPort(h,dcLabelStr,n.sockAddr,n.portNumber)) != kOkDcRC )
|
|
1373
|
+ if((rc = cmDevCfgNameNetPort(h,dcLabelStr,n.sockAddr,n.portNumber,n.localFl,n.activeFl)) != kOkDcRC )
|
1192
|
1374
|
goto errLabel;
|
1193
|
1375
|
|
1194
|
1376
|
break;
|
|
@@ -1287,6 +1469,7 @@ cmDcRC_t _cmDevCfgWrite( cmDcm_t* p, cmJsonH_t jsH, cmJsonNode_t* rootObjPtr )
|
1287
|
1469
|
"dspFramesPerCycle", kIntTId, cp->u.a.audioSysArgs.dspFramesPerCycle,
|
1288
|
1470
|
"audioBufCnt", kIntTId, cp->u.a.audioSysArgs.audioBufCnt,
|
1289
|
1471
|
"srate", kRealTId, cp->u.a.audioSysArgs.srate,
|
|
1472
|
+ "active", kBoolTId, cp->u.a.activeFl,
|
1290
|
1473
|
NULL );
|
1291
|
1474
|
break;
|
1292
|
1475
|
|
|
@@ -1294,6 +1477,8 @@ cmDcRC_t _cmDevCfgWrite( cmDcm_t* p, cmJsonH_t jsH, cmJsonNode_t* rootObjPtr )
|
1294
|
1477
|
cmJsonInsertPairs(jsH, cfgObjNp,
|
1295
|
1478
|
"sockAddr", kStringTId, cp->u.n.sockAddr,
|
1296
|
1479
|
"portNumber",kIntTId, cp->u.n.portNumber,
|
|
1480
|
+ "localFl", kBoolTId, cp->u.n.localFl,
|
|
1481
|
+ "activeFl", kBoolTId, cp->u.n.activeFl,
|
1297
|
1482
|
NULL );
|
1298
|
1483
|
break;
|
1299
|
1484
|
|