Browse Source

cmDevCfg.h/c: Many changes and additions to complete implementation.

master
kevin 11 years ago
parent
commit
646f65222e
2 changed files with 257 additions and 55 deletions
  1. 233
    49
      cmDevCfg.c
  2. 24
    6
      cmDevCfg.h

+ 233
- 49
cmDevCfg.c View File

@@ -6,6 +6,7 @@
6 6
 #include "cmMem.h"
7 7
 #include "cmMallocDebug.h"
8 8
 #include "cmLinkedHeap.h"
9
+#include "cmFileSys.h"
9 10
 #include "cmJson.h"
10 11
 #include "cmText.h"
11 12
 #include "cmThread.h"
@@ -24,10 +25,13 @@ cmDevCfgH_t cmDevCfgNullHandle = cmSTATIC_NULL_HANDLE;
24 25
 
25 26
 typedef struct cmDcmCfg_str
26 27
 {
27
-  cmChar_t*     dcLabelStr;
28
+  cmChar_t*     dcLabelStr;   // the cfg label 
28 29
   unsigned      cfgId;        // unique among all cfg's assigned to a loc
29
-  cmTypeDcmId_t typeId;
30
-  cmChar_t*     descStr;
30
+  cmTypeDcmId_t typeId;       // the cfg type id (e.g. midi, audio, net, ...)
31
+  cmChar_t*     descStr;      // summary description string 
32
+
33
+  // NOTE: any fields added to this structure, type generic (above) 
34
+  // or type specific (below), must be explicitely duplicated in cmDevCfgLocStore().
31 35
 
32 36
   union
33 37
   {
@@ -71,8 +75,10 @@ typedef struct cmDcmLoc_str
71 75
 typedef struct
72 76
 {
73 77
   cmErr_t     err;
78
+  cmCtx_t*    ctx;
74 79
   cmDcmLoc_t* loc;
75 80
   cmDcmLoc_t* clp;
81
+  cmChar_t*   fn;
76 82
 } cmDcm_t;
77 83
 
78 84
 
@@ -166,6 +172,8 @@ void _cmDcmFreeCfg( cmDcm_t* p, cmDcmLoc_t* lp, cmDcmCfg_t* cp )
166 172
       assert(0);
167 173
       break;
168 174
   }
175
+
176
+  cmMemFree(cp);
169 177
 }
170 178
 
171 179
 void _cmDcmFreeLoc( cmDcm_t* p, cmDcmLoc_t* lp )
@@ -208,6 +216,7 @@ cmDcRC_t _cmDcmFree( cmDcm_t* p )
208 216
   cmDcRC_t rc = kOkDcRC;
209 217
 
210 218
   _cmDcmFreeAllLocs(p);
219
+  cmMemFree(p->fn);
211 220
 
212 221
   cmMemFree(p);
213 222
   return rc;
@@ -270,21 +279,64 @@ cmDcRC_t _cmDcmNewLoc( cmDcm_t* p, const cmChar_t* labelStr, cmDcmLoc_t**  locRe
270 279
    
271 280
 }
272 281
 
273
-cmDcRC_t cmDevCfgMgrAlloc( cmCtx_t* c, cmDevCfgH_t* hp )
282
+cmDcRC_t _cmDevCfgRead( cmDcm_t* p, cmJsonH_t jsH, const cmJsonNode_t* rootObjPtr );
283
+
284
+cmDcRC_t _cmDevCfgReadFile( cmDcm_t* p, const cmChar_t* fn )
285
+{
286
+  cmDcRC_t rc = kOkDcRC;
287
+
288
+  cmJsonH_t jsH = cmJsonNullHandle;
289
+
290
+  // initialize the JSON tree from the preferences file
291
+  if( cmJsonInitializeFromFile( &jsH, fn, p->ctx ) != kOkJsRC )
292
+  {
293
+    rc = cmErrMsg(&p->err,kJsonFailDcRC,"JSON initialization from '%s' failed.",cmStringNullGuard(fn));
294
+    goto errLabel;
295
+  }
296
+
297
+  if((rc = _cmDevCfgRead(p, jsH, cmJsonRoot(jsH))) != kOkJsRC )
298
+    goto errLabel;
299
+
300
+ errLabel:
301
+  if( cmJsonFinalize(&jsH) != kOkJsRC )
302
+    cmErrMsg(&p->err,kJsonFailDcRC,"JSON finalization failed following dev cfg read.");
303
+
304
+  return rc;
305
+
306
+}
307
+
308
+cmDcRC_t cmDevCfgAlloc( cmCtx_t* c, cmDevCfgH_t* hp, const cmChar_t* fn )
274 309
 {
275 310
   cmDcRC_t rc;
276 311
   cmDcmLoc_t* lp;
277 312
 
278
-  if((rc = cmDevCfgMgrFree(hp)) != kOkDcRC )
313
+  if((rc = cmDevCfgFree(hp)) != kOkDcRC )
279 314
     return rc;
280 315
 
281 316
   cmDcm_t* p = cmMemAllocZ(cmDcm_t,1);
282 317
 
283 318
   cmErrSetup(&p->err,&c->rpt,"cmDevCfg");
284 319
 
320
+  p->ctx = c;
285 321
 
286
-  if((rc = _cmDcmNewLoc(p,"Default", &lp)) != kOkDcRC )
287
-    goto errLabel;
322
+  if( fn != NULL )
323
+  {
324
+    p->fn = cmMemAllocStr(fn);
325
+    
326
+    if( cmFsIsFile(fn) )
327
+    {
328
+      // if the file read fails then reset and go with the default empty setup.
329
+      if(_cmDevCfgReadFile(p,fn) != kOkDcRC )
330
+        _cmDcmFreeAllLocs(p);
331
+    }
332
+  }
333
+
334
+  // if the location array is empty then create a default location
335
+  if( p->loc == NULL )
336
+  {
337
+    if((rc = _cmDcmNewLoc(p,"Default", &lp)) != kOkDcRC )
338
+      goto errLabel;
339
+  }
288 340
 
289 341
   hp->h = p;
290 342
 
@@ -295,7 +347,7 @@ cmDcRC_t cmDevCfgMgrAlloc( cmCtx_t* c, cmDevCfgH_t* hp )
295 347
   return rc;
296 348
 }
297 349
 
298
-cmDcRC_t cmDevCfgMgrFree( cmDevCfgH_t* hp )
350
+cmDcRC_t cmDevCfgFree( cmDevCfgH_t* hp )
299 351
 {
300 352
   cmDcRC_t rc = kOkDcRC;
301 353
   if( hp == NULL || cmDevCfgIsValid(*hp)==false )
@@ -436,7 +488,7 @@ cmDcmCfg_t*  _cmDcmFindOrCreateCfg( cmDcm_t* p, cmTypeDcmId_t typeId, const cmCh
436 488
   cp->dcLabelStr = cmMemAllocStr(dcLabelStr);
437 489
   cp->cfgId      = newCfgId;
438 490
   cp->typeId     = typeId;
439
-  
491
+
440 492
   // link to the end of the loc's cfg list
441 493
   if( ep == NULL )
442 494
     p->clp->cfg = cp;
@@ -643,7 +695,7 @@ cmDcRC_t cmDevCfgNameAudioPort(
643 695
   unsigned    outDevIdx;
644 696
 
645 697
   // validate the label
646
-  if((dcLabelStr = _cmDcmTrimLabel(p,dcLabelStr,"MIDI cfg")) == NULL)
698
+  if((dcLabelStr = _cmDcmTrimLabel(p,dcLabelStr,"Audio cfg")) == NULL)
647 699
     return cmErrLastRC(&p->err);
648 700
 
649 701
   // validate the input device
@@ -654,11 +706,30 @@ cmDcRC_t cmDevCfgNameAudioPort(
654 706
   if(( outDevIdx = cmApDeviceLabelToIndex(outDevNameStr)) == cmInvalidIdx )
655 707
     return cmErrMsg(&p->err, kInvalidArgDcRC,"The output audio device name '%s' is not valid.",cmStringNullGuard(outDevNameStr));
656 708
 
709
+  // validate the msg byte cnt
710
+  if( msgQueueByteCnt == 0 )
711
+    return cmErrMsg(&p->err, kInvalidArgDcRC,"The 'message queue size' must be greater than zero.");
712
+
713
+  // validate the dev. frames per cycle
714
+  if( devFramesPerCycle == 0 )
715
+    return cmErrMsg(&p->err, kInvalidArgDcRC,"The 'device frames per cycle' must be greater than zero.");
716
+  
717
+  // validate the dsp frames per cycle
718
+  if( dspFramesPerCycle == 0 || ((devFramesPerCycle/dspFramesPerCycle) * dspFramesPerCycle != devFramesPerCycle) )
719
+    return cmErrMsg(&p->err, kInvalidArgDcRC,"The 'DSP frames per cycle' must be greater than zero and an integer factor of 'Device frames per cycle.'.");
720
+
721
+  // validate the sample rate
722
+  if( srate == 0 )
723
+    return cmErrMsg(&p->err, kInvalidArgDcRC,"The audio sample rate must be greater than zero.");
724
+
657 725
   // if dcLabelStr is already in use for this location and type then update
658 726
   // the assoc'd recd otherwise create a new one.
659 727
   if((cp = _cmDcmFindOrCreateCfg(p,kAudioDcmTId, dcLabelStr)) == NULL )
660 728
     return cmErrLastRC(&p->err);
661 729
 
730
+  unsigned inChCnt  = cmApDeviceChannelCount( inDevIdx,  true );
731
+  unsigned outChCnt = cmApDeviceChannelCount( outDevIdx, false );
732
+
662 733
   cp->u.a.inDevLabelStr                  = cmMemAllocStr(inDevNameStr);
663 734
   cp->u.a.outDevLabelStr                 = cmMemAllocStr(outDevNameStr);
664 735
   cp->u.a.audioSysArgs.rpt               = p->err.rpt;
@@ -670,10 +741,60 @@ cmDcRC_t cmDevCfgNameAudioPort(
670 741
   cp->u.a.audioSysArgs.dspFramesPerCycle = dspFramesPerCycle;
671 742
   cp->u.a.audioSysArgs.audioBufCnt       = audioBufCnt;
672 743
   cp->u.a.audioSysArgs.srate             = srate;
673
-  cp->descStr = cmTsPrintfP(cp->descStr,"In:%s Out:%s",inDevNameStr,outDevNameStr);
744
+  cp->descStr = cmTsPrintfP(cp->descStr,"In: Chs:%i %s\nOut: Chs:%i %s",inChCnt,inDevNameStr,outChCnt,outDevNameStr);
674 745
   return kOkDcRC;  
675 746
 }
676 747
 
748
+
749
+
750
+cmDcRC_t            cmDevCfgAudioSetDefaultCfgIndex( cmDevCfgH_t h, unsigned cfgIdx )
751
+{
752
+  cmDcm_t*    p  = _cmDcmHandleToPtr(h);
753
+
754
+  assert( p->clp != NULL );
755
+
756
+  cmDcmCfg_t* cp = p->clp->cfg;
757
+  unsigned    i;
758
+
759
+  for(i=0; cp!=NULL; cp=cp->next)
760
+    if( cp->typeId == kAudioDcmTId )
761
+    {
762
+      if( i == cfgIdx )
763
+        cp->u.a.dfltFl = true;
764
+      else
765
+      {
766
+        if( cp->u.a.dfltFl )
767
+          cp->u.a.dfltFl = false;
768
+      }
769
+
770
+      ++i;
771
+    }
772
+  
773
+
774
+  return kOkDcRC;
775
+}
776
+
777
+unsigned   cmDevCfgAudioGetDefaultCfgIndex( cmDevCfgH_t h )
778
+{
779
+  cmDcm_t*    p  = _cmDcmHandleToPtr(h);
780
+
781
+  assert( p->clp != NULL );
782
+
783
+  cmDcmCfg_t* cp = p->clp->cfg;
784
+  unsigned    i;
785
+
786
+  for(i=0; cp!=NULL; cp=cp->next)
787
+    if( cp->typeId == kAudioDcmTId )
788
+    {
789
+      if( cp->u.a.dfltFl )
790
+        return i;
791
+
792
+      ++i;
793
+    }
794
+  return cmInvalidIdx;
795
+}
796
+
797
+
677 798
 const cmDcmAudio_t* cmDevCfgAudioCfg( cmDevCfgH_t h, unsigned cfgIdx )
678 799
 {
679 800
   cmDcm_t* p = _cmDcmHandleToPtr(h);
@@ -697,7 +818,7 @@ const cmDcmAudio_t* cmDevCfgAudioDevMap(    cmDevCfgH_t h, unsigned usrAppId, un
697 818
 }
698 819
 
699 820
 
700
-cmDcRC_t cmDevCfgNetPort(
821
+cmDcRC_t cmDevCfgNameNetPort(
701 822
   cmDevCfgH_t      h,
702 823
   const cmChar_t* dcLabelStr,
703 824
   const cmChar_t* sockAddr,
@@ -716,7 +837,7 @@ cmDcRC_t cmDevCfgNetPort(
716 837
 
717 838
   // if dcLabelStr is already in use for this location and type then update
718 839
   // the assoc'd recd otherwise create a new one.
719
-  if((cp = _cmDcmFindOrCreateCfg(p,kAudioDcmTId, dcLabelStr)) == NULL )
840
+  if((cp = _cmDcmFindOrCreateCfg(p,kNetDcmTId, dcLabelStr)) == NULL )
720 841
     return cmErrLastRC(&p->err);
721 842
 
722 843
   cp->u.n.sockAddr = cmMemAllocStr(sockAddr);
@@ -760,11 +881,11 @@ unsigned        cmDevCfgLocCount(  cmDevCfgH_t h )
760 881
 }
761 882
 const cmChar_t* cmDevCfgLocLabel(  cmDevCfgH_t h, unsigned locIdx )
762 883
 {
763
-  unsigned n = 0;
764 884
   cmDcm_t* p = _cmDcmHandleToPtr(h);
765 885
   const cmDcmLoc_t* lp = p->loc;
766
-  for(; lp!=NULL; lp=lp->next)
767
-    if( n == locIdx )
886
+  unsigned i;
887
+  for(i=0; lp!=NULL; lp=lp->next,++i)
888
+    if( i == locIdx )
768 889
       return lp->labelStr;
769 890
 
770 891
   assert(0);
@@ -772,7 +893,7 @@ const cmChar_t* cmDevCfgLocLabel(  cmDevCfgH_t h, unsigned locIdx )
772 893
 }
773 894
 
774 895
 
775
-cmDcmLoc_t* _cmDcmLocLabelToPtr( cmDcm_t* p, const cmChar_t* locLabelStr)
896
+cmDcmLoc_t* _cmDcmLocLabelToPtr( cmDcm_t* p, const cmChar_t* locLabelStr, bool errFl)
776 897
 {
777 898
   if((locLabelStr = _cmDcmTrimLabel(p,locLabelStr,"location")) == NULL )
778 899
     return NULL;
@@ -782,7 +903,8 @@ cmDcmLoc_t* _cmDcmLocLabelToPtr( cmDcm_t* p, const cmChar_t* locLabelStr)
782 903
     if( strcmp(lp->labelStr,locLabelStr) == 0 )
783 904
       return lp;
784 905
 
785
-  cmErrMsg(&p->err,kLabelNotFoundDcRC,"The location label '%s' was not found.",locLabelStr);
906
+  if( errFl )
907
+    cmErrMsg(&p->err,kLabelNotFoundDcRC,"The location label '%s' was not found.",locLabelStr);
786 908
 
787 909
   return NULL;
788 910
 }
@@ -795,7 +917,7 @@ cmDcRC_t cmDevCfgLocStore(  cmDevCfgH_t h, const cmChar_t* locLabelStr )
795 917
   unsigned i,j;
796 918
 
797 919
   // if this location label is already in use then it has already been stored.
798
-  if( _cmDcmLocLabelToPtr(p,locLabelStr) != NULL )
920
+  if( _cmDcmLocLabelToPtr(p,locLabelStr,false) != NULL )
799 921
     return kOkDcRC;
800 922
 
801 923
   // store the current loc ptr
@@ -812,11 +934,15 @@ cmDcRC_t cmDevCfgLocStore(  cmDevCfgH_t h, const cmChar_t* locLabelStr )
812 934
   {
813 935
     cmDcmCfg_t* ncp;
814 936
 
937
+    // this will always create (never find) a new cfg recd
815 938
     if((ncp = _cmDcmFindOrCreateCfg(p,ocp->typeId, ocp->dcLabelStr)) == NULL )
816 939
     {
817 940
       rc = cmErrLastRC(&p->err);
818 941
       goto errLabel;
819 942
     }
943
+
944
+    // duplicate the desc. string
945
+    ncp->descStr = cmMemAllocStr(ocp->descStr);
820 946
     
821 947
     switch( ncp->typeId )
822 948
     {
@@ -869,7 +995,7 @@ cmDcRC_t cmDevCfgLocRecall( cmDevCfgH_t h, const cmChar_t* locLabelStr )
869 995
   cmDcm_t*     p = _cmDcmHandleToPtr(h);
870 996
   cmDcmLoc_t* lp;
871 997
 
872
-  if((lp = _cmDcmLocLabelToPtr(p,locLabelStr)) == NULL)
998
+  if((lp = _cmDcmLocLabelToPtr(p,locLabelStr,true)) == NULL)
873 999
     return cmErrLastRC(&p->err);
874 1000
 
875 1001
   p->clp = lp;
@@ -881,7 +1007,7 @@ cmDcRC_t cmDevCfgLocDelete( cmDevCfgH_t h, const cmChar_t* locLabelStr )
881 1007
   cmDcm_t*     p = _cmDcmHandleToPtr(h);
882 1008
   cmDcmLoc_t* lp;
883 1009
 
884
-  if((lp = _cmDcmLocLabelToPtr(p,locLabelStr)) == NULL )
1010
+  if((lp = _cmDcmLocLabelToPtr(p,locLabelStr,true)) == NULL )
885 1011
     return cmErrLastRC(&p->err);
886 1012
 
887 1013
   _cmDcmFreeLoc(p,lp);
@@ -908,14 +1034,14 @@ cmDcRC_t _cmDcmJsonNotFound( cmDcm_t* p, const cmChar_t* tagStr )
908 1034
 cmDcRC_t _cmDcmJsonSyntaxErr( cmDcm_t* p, const cmChar_t* tagStr )
909 1035
 { return cmErrMsg(&p->err,kJsonFailDcRC,"JSON syntax error '%s' not found.",tagStr); }
910 1036
 
911
-cmDcRC_t _cmDevCfgRead( cmDevCfgH_t h, cmJsonH_t jsH, const cmJsonNode_t* rootObjPtr )
1037
+cmDcRC_t _cmDevCfgRead( cmDcm_t* p, cmJsonH_t jsH, const cmJsonNode_t* rootObjPtr )
912 1038
 {
913 1039
   cmDcRC_t        rc          = kOkDcRC;
914 1040
   const cmChar_t* errLabelPtr = NULL;
915 1041
   cmJsonNode_t* cfgNp, *locArrNp;
916 1042
   unsigned i,j;
917
-
918
-  cmDcm_t* p = _cmDcmHandleToPtr(h);
1043
+  cmDevCfgH_t h;
1044
+  h.h = p;
919 1045
 
920 1046
   // clear the all locations
921 1047
   _cmDcmFreeAllLocs(p);
@@ -931,7 +1057,7 @@ cmDcRC_t _cmDevCfgRead( cmDevCfgH_t h, cmJsonH_t jsH, const cmJsonNode_t* rootOb
931 1057
   for(i=0; i<cmJsonChildCount(locArrNp); ++i)
932 1058
   {
933 1059
     cmJsonNode_t* locObjNp, *cfgArrNp;
934
-    const cmChar_t* label = NULL;
1060
+    const cmChar_t* locLabelStr = NULL;
935 1061
 
936 1062
     // get the loc object
937 1063
     if((locObjNp = cmJsonArrayElement(locArrNp,i)) == NULL || cmJsonIsObject(locObjNp)==false )
@@ -939,15 +1065,15 @@ cmDcRC_t _cmDevCfgRead( cmDevCfgH_t h, cmJsonH_t jsH, const cmJsonNode_t* rootOb
939 1065
 
940 1066
     // read the loc object fields
941 1067
     if( cmJsonMemberValues(locObjNp, &errLabelPtr,  
942
-        "label", kStringTId, &label,
1068
+        "label", kStringTId, &locLabelStr,
943 1069
         "cfg",   kArrayTId,  &cfgArrNp,
944
-        NULL ) == kOkJsRC )
1070
+        NULL ) != kOkJsRC )
945 1071
     { return _cmDcmJsonNotFound(p,errLabelPtr); }
946 1072
 
947 1073
     // create a new location recd
948 1074
     cmDcmLoc_t* locPtr = NULL;
949
-    if((rc = _cmDcmNewLoc(p,label,&locPtr)) == kOkDcRC )
950
-      return cmErrMsg(&p->err,kJsonFailDcRC,"Location '%s' create failed.",cmStringNullGuard(label));
1075
+    if((rc = _cmDcmNewLoc(p,locLabelStr,&locPtr)) != kOkDcRC )
1076
+      return cmErrMsg(&p->err,kJsonFailDcRC,"Location '%s' create failed.",cmStringNullGuard(locLabelStr));
951 1077
 
952 1078
     /*
953 1079
     // read each app object
@@ -998,23 +1124,28 @@ cmDcRC_t _cmDevCfgRead( cmDevCfgH_t h, cmJsonH_t jsH, const cmJsonNode_t* rootOb
998 1124
         "cfgId",  kIntTId,    &cfgId,
999 1125
         "typeId", kIntTId,    &typeId,
1000 1126
         "desc",   kStringTId, &descStr,
1001
-          NULL ) == kOkJsRC )
1127
+          NULL ) != kOkJsRC )
1002 1128
       { _cmDcmJsonSyntaxErr(p,errLabelPtr); }
1003 1129
 
1004 1130
       cmDcmMidi_t  m;
1005 1131
       cmDcmAudio_t a;
1006 1132
       cmDcmNet_t   n;
1007
-
1133
+      
1008 1134
       switch( typeId )
1009 1135
       {
1010 1136
         case kMidiDcmTId:   
1011 1137
           if( cmJsonMemberValues( cfgObjNp, &errLabelPtr,
1012 1138
               "devLabelStr", kStringTId, &m.devLabelStr,
1013 1139
               "portLabelStr",kStringTId, &m.portLabelStr,
1140
+              "inputFl",     kBoolTId,   &m.inputFl,
1014 1141
               NULL) != kOkJsRC )
1015
-          {}
1142
+          {
1143
+            rc = _cmDcmJsonSyntaxErr(p,errLabelPtr);
1144
+            goto errLabel;
1145
+          }
1016 1146
           
1017
-          cmDevCfgNameMidiPort(h,label,m.devLabelStr,m.portLabelStr,m.inputFl);
1147
+          if((rc = cmDevCfgNameMidiPort(h,dcLabelStr,m.devLabelStr,m.portLabelStr,m.inputFl)) != kOkDcRC )
1148
+            goto errLabel;
1018 1149
           
1019 1150
           break;
1020 1151
             
@@ -1027,16 +1158,23 @@ cmDcRC_t _cmDevCfgRead( cmDevCfgH_t h, cmJsonH_t jsH, const cmJsonNode_t* rootOb
1027 1158
               "devFramesPerCycle", kIntTId,    &a.audioSysArgs.devFramesPerCycle,
1028 1159
               "dspFramesPerCycle", kIntTId,    &a.audioSysArgs.dspFramesPerCycle,
1029 1160
               "audioBufCnt",       kIntTId,    &a.audioSysArgs.audioBufCnt,
1030
-              "srate",             kIntTId,    &a.audioSysArgs.srate ) == kOkJsRC )
1031
-          {}
1032
-
1033
-          cmDevCfgNameAudioPort(h,label,a.inDevLabelStr,a.outDevLabelStr,
1034
-            a.audioSysArgs.syncInputFl,
1035
-            a.audioSysArgs.msgQueueByteCnt,
1036
-            a.audioSysArgs.devFramesPerCycle,
1037
-            a.audioSysArgs.dspFramesPerCycle,
1038
-            a.audioSysArgs.audioBufCnt,
1039
-            a.audioSysArgs.srate );
1161
+              "srate",             kRealTId,   &a.audioSysArgs.srate,
1162
+              NULL ) != kOkJsRC )
1163
+          {
1164
+            rc = _cmDcmJsonSyntaxErr(p,errLabelPtr);
1165
+            goto errLabel;
1166
+          }
1167
+
1168
+          if((rc = cmDevCfgNameAudioPort(h,dcLabelStr,a.inDevLabelStr,a.outDevLabelStr,
1169
+                a.audioSysArgs.syncInputFl,
1170
+                a.audioSysArgs.msgQueueByteCnt,
1171
+                a.audioSysArgs.devFramesPerCycle,
1172
+                a.audioSysArgs.dspFramesPerCycle,
1173
+                a.audioSysArgs.audioBufCnt,
1174
+                a.audioSysArgs.srate )) != kOkDcRC )
1175
+          {
1176
+            goto errLabel;
1177
+          }
1040 1178
 
1041 1179
           break;
1042 1180
 
@@ -1045,9 +1183,13 @@ cmDcRC_t _cmDevCfgRead( cmDevCfgH_t h, cmJsonH_t jsH, const cmJsonNode_t* rootOb
1045 1183
               "sockAddr",   kStringTId, &n.sockAddr,
1046 1184
               "portNumber", kIntTId,    &n.portNumber,
1047 1185
               NULL ) != kOkJsRC )
1048
-          {}
1186
+          {
1187
+            rc = _cmDcmJsonSyntaxErr(p,errLabelPtr);
1188
+            goto errLabel;
1189
+          }
1049 1190
 
1050
-          cmDevCfgNetPort(h,label,n.sockAddr,n.portNumber);
1191
+          if((rc = cmDevCfgNameNetPort(h,dcLabelStr,n.sockAddr,n.portNumber)) != kOkDcRC )
1192
+            goto errLabel;
1051 1193
 
1052 1194
           break;
1053 1195
 
@@ -1058,13 +1200,14 @@ cmDcRC_t _cmDevCfgRead( cmDevCfgH_t h, cmJsonH_t jsH, const cmJsonNode_t* rootOb
1058 1200
     }    
1059 1201
   }
1060 1202
 
1203
+ errLabel:
1061 1204
   return kOkDcRC;
1062 1205
 }
1063 1206
 
1064 1207
 cmDcRC_t _cmDevCfgWrite( cmDcm_t* p, cmJsonH_t jsH, cmJsonNode_t* rootObjPtr )
1065 1208
 {
1066 1209
   cmDcRC_t rc = kOkDcRC;
1067
-  const cmDcmLoc_t* lp;
1210
+  const cmDcmLoc_t* lp = p->loc;
1068 1211
   
1069 1212
   cmJsonNode_t* cfgNp = cmJsonInsertPairObject(jsH, rootObjPtr, "cfg" );
1070 1213
 
@@ -1077,7 +1220,7 @@ cmDcRC_t _cmDevCfgWrite( cmDcm_t* p, cmJsonH_t jsH, cmJsonNode_t* rootObjPtr )
1077 1220
     cmJsonNode_t* locObjNp = cmJsonCreateObject(jsH,locArrNp);
1078 1221
 
1079 1222
     // set the loc label
1080
-    cmJsonInsertPairString(jsH, locObjNp, lp->labelStr, "label" );
1223
+    cmJsonInsertPairString(jsH, locObjNp, "label", lp->labelStr );
1081 1224
 
1082 1225
     /*
1083 1226
     // create the 'loc.app[]' array
@@ -1143,7 +1286,7 @@ cmDcRC_t _cmDevCfgWrite( cmDcm_t* p, cmJsonH_t jsH, cmJsonNode_t* rootObjPtr )
1143 1286
             "devFramesPerCycle", kIntTId,    cp->u.a.audioSysArgs.devFramesPerCycle,
1144 1287
             "dspFramesPerCycle", kIntTId,    cp->u.a.audioSysArgs.dspFramesPerCycle,
1145 1288
             "audioBufCnt",       kIntTId,    cp->u.a.audioSysArgs.audioBufCnt,
1146
-            "srate",             kIntTId,    cp->u.a.audioSysArgs.srate,
1289
+            "srate",             kRealTId,   cp->u.a.audioSysArgs.srate,
1147 1290
             NULL );
1148 1291
           break;
1149 1292
 
@@ -1163,8 +1306,49 @@ cmDcRC_t _cmDevCfgWrite( cmDcm_t* p, cmJsonH_t jsH, cmJsonNode_t* rootObjPtr )
1163 1306
   return rc;
1164 1307
 }
1165 1308
 
1166
-cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h )
1309
+cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h, const cmChar_t* fn )
1167 1310
 {
1168 1311
   cmDcRC_t rc = kOkDcRC;
1312
+  cmDcm_t* p = _cmDcmHandleToPtr(h);
1313
+
1314
+  cmJsonH_t jsH = cmJsonNullHandle;
1315
+
1316
+  if( fn == NULL )
1317
+    fn = p->fn;
1318
+
1319
+  // validate the filename
1320
+  if( fn == NULL || strlen(fn)==0 )
1321
+    return cmErrMsg(&p->err,kInvalidFnDcRC,"No output file name was provided.");
1322
+
1323
+  // create a json object
1324
+  if( cmJsonInitialize( &jsH, p->ctx ) != kOkJsRC )
1325
+  {
1326
+    rc = cmErrMsg(&p->err,kJsonFailDcRC,"An empty JSON tree could not be created.");
1327
+    goto errLabel;
1328
+  }
1329
+
1330
+  // insert a wrapper object as the root
1331
+  if( cmJsonCreateObject( jsH, NULL ) == NULL )
1332
+  {
1333
+    rc = cmErrMsg(&p->err,kJsonFailDcRC,"The JSON root object could not be created.");
1334
+    goto errLabel;
1335
+  }
1336
+
1337
+  // fill the JSON tree
1338
+  if((rc = _cmDevCfgWrite(p,jsH,cmJsonRoot(jsH))) != kOkDcRC )
1339
+    goto errLabel;
1340
+
1341
+  // write the output file
1342
+  if( cmJsonWrite(jsH, cmJsonRoot(jsH), fn ) != kOkJsRC )
1343
+  {
1344
+    rc = cmErrMsg(&p->err,kJsonFailDcRC,"The JSON file write failed on '%s'.",cmStringNullGuard(fn));
1345
+    goto errLabel;
1346
+  }
1347
+  
1348
+  
1349
+ errLabel:
1350
+  if( cmJsonFinalize(&jsH) != kOkJsRC )
1351
+    cmErrMsg(&p->err,kJsonFailDcRC,"JSON tree finalization failed.");
1352
+
1169 1353
   return rc;
1170 1354
 }

+ 24
- 6
cmDevCfg.h View File

@@ -50,7 +50,8 @@ extern "C" {
50 50
     kInvalidUserMapIdRC,
51 51
     kInvalidArgDcRC,
52 52
     kInvalidCfgIdxDcRC,
53
-    kJsonFailDcRC
53
+    kJsonFailDcRC,
54
+    kInvalidFnDcRC
54 55
   };
55 56
 
56 57
   typedef enum
@@ -78,6 +79,7 @@ extern "C" {
78 79
     cmChar_t*        inDevLabelStr;  // Input audio device label.
79 80
     cmChar_t*        outDevLabelStr; // Output audio device label.
80 81
     cmAudioSysArgs_t audioSysArgs;   // Audio system  cfg recd
82
+    bool             dfltFl;         // true if this is the default audio cfg.
81 83
   } cmDcmAudio_t;
82 84
 
83 85
   typedef struct              
@@ -88,8 +90,8 @@ extern "C" {
88 90
 
89 91
   extern cmDevCfgH_t cmDevCfgNullHandle;
90 92
 
91
-  cmDcRC_t cmDevCfgMgrAlloc( cmCtx_t* c, cmDevCfgH_t* hp );
92
-  cmDcRC_t cmDevCfgMgrFree( cmDevCfgH_t* hp );
93
+  cmDcRC_t cmDevCfgAlloc( cmCtx_t* c, cmDevCfgH_t* hp, const cmChar_t* fn );
94
+  cmDcRC_t cmDevCfgFree( cmDevCfgH_t* hp );
93 95
   bool     cmDevCfgIsValid( cmDevCfgH_t h );
94 96
 
95 97
   // Return the count of cfg records for the given type in the current location.
@@ -139,12 +141,16 @@ extern "C" {
139 141
     unsigned        audioBufCnt,
140 142
     double          srate  );
141 143
 
144
+  cmDcRC_t            cmDevCfgAudioSetDefaultCfgIndex( cmDevCfgH_t h, unsigned cfgIdx );
145
+  unsigned            cmDevCfgAudioGetDefaultCfgIndex( cmDevCfgH_t h );
146
+
142 147
   const cmDcmAudio_t* cmDevCfgAudioCfg( cmDevCfgH_t h, unsigned cfgIdx );
143 148
   const cmDcmAudio_t* cmDevCfgAudioMap( cmDevCfgH_t h, unsigned usrAppId, unsigned usrMapId );
149
+  
144 150
 
145 151
   const struct cmAudioSysArgs_str* cmDevCfgAudioSysArgs( cmDevCfgH_t h, unsigned usrAppId, unsigned usrMapId );
146 152
 
147
-  cmDcRC_t cmDevCfgNetPort(
153
+  cmDcRC_t cmDevCfgNameNetPort(
148 154
     cmDevCfgH_t      h,
149 155
     const cmChar_t* dcLabelStr,
150 156
     const cmChar_t* sockAddr,
@@ -153,19 +159,31 @@ extern "C" {
153 159
   const cmDcmNet_t* cmDevCfgNetCfg( cmDevCfgH_t h, unsigned cfgIdx );
154 160
   const cmDcmNet_t* cmDevCfgNetMap( cmDevCfgH_t h, unsigned usrAppId, unsigned usrMapId );
155 161
 
162
+  //---------------------------------------------------------------------------------------
156 163
   // Location Management Functions:
157
-  // Store and recall groups cfg records.
164
+  // Store and recall groups of cfg records.
158 165
 
166
+  // Return a count of the current number of locations.
159 167
   unsigned        cmDevCfgLocCount(  cmDevCfgH_t h );
168
+
169
+  // Given a location index (0 to cmDevCfgLocCount()-1) return the locations label.
160 170
   const cmChar_t* cmDevCfgLocLabel(  cmDevCfgH_t h, unsigned locIdx );
171
+
172
+  // If 'locLabelStr' has already been used then this function does nothing and returns.
173
+  // otherwise the current location is duplicated and the duplicate is named 'locLabelStr'.
161 174
   cmDcRC_t        cmDevCfgLocStore(  cmDevCfgH_t h, const cmChar_t* locLabelStr );
175
+
176
+  // Make the location named 'locLabelStr' the current location.
162 177
   cmDcRC_t        cmDevCfgLocRecall( cmDevCfgH_t h, const cmChar_t* locLabelStr );
178
+
179
+  // Delete the location named by 'locLabelStr'.
163 180
   cmDcRC_t        cmDevCfgLocDelete( cmDevCfgH_t h, const cmChar_t* locLabelStr );
164 181
 
165 182
   // Return the current location index
166 183
   unsigned        cmDevCfgLocCurIndex(  cmDevCfgH_t h );
167 184
 
168
-  cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h );
185
+  // Set 'fn' to NULL to use filename from cmDevCfgAlloc()
186
+  cmDcRC_t cmDevCfgWrite( cmDevCfgH_t h, const cmChar_t* fn );
169 187
   
170 188
 
171 189
 #ifdef __cplusplus

Loading…
Cancel
Save