Просмотр исходного кода

cmAudioPortAlsa.c : Added _cmApDevReportFormats().

Added, but disabled, _cmApS24_3BE*().
Added i/oSignFl and i/oSwapFl to device record.
Changed sample format selection algorithm to use fmt[].
master
Kevin Larke 9 лет назад
Родитель
Сommit
f48cc2e7f7
1 измененных файлов: 144 добавлений и 22 удалений
  1. 144
    22
      linux/cmAudioPortAlsa.c

+ 144
- 22
linux/cmAudioPortAlsa.c Просмотреть файл

@@ -40,11 +40,17 @@ typedef struct devRecd_str
40 40
   snd_async_handler_t* ahandler;
41 41
   unsigned             srate;          // device sample rate
42 42
 
43
-  unsigned             iChCnt;  // ch count 
43
+  unsigned             iChCnt;         // ch count 
44 44
   unsigned             oChCnt;
45 45
 
46 46
   unsigned             iBits;          // bits per sample
47
-  unsigned             oBits; 
47
+  unsigned             oBits;
48
+
49
+  bool                 iSignFl;        // sample type is signed
50
+  bool                 oSignFl;
51
+
52
+  bool                 iSwapFl;        // swap the sample bytes
53
+  bool                 oSwapFl;
48 54
 
49 55
   unsigned             iSigBits;       // significant bits in each sample beginning
50 56
   unsigned             oSigBits;       // with the most sig. bit.
@@ -362,6 +368,77 @@ void _cmApDevRtReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
362 368
 
363 369
 }
364 370
 
371
+void _cmApDevReportFormats( cmRpt_t* rpt, snd_pcm_hw_params_t* hwParams )
372
+{
373
+  snd_pcm_format_mask_t* mask;
374
+
375
+  snd_pcm_format_t fmt[] =
376
+  {
377
+     SND_PCM_FORMAT_S8,
378
+     SND_PCM_FORMAT_U8,
379
+     SND_PCM_FORMAT_S16_LE,
380
+     SND_PCM_FORMAT_S16_BE,
381
+     SND_PCM_FORMAT_U16_LE,
382
+     SND_PCM_FORMAT_U16_BE,
383
+     SND_PCM_FORMAT_S24_LE,
384
+     SND_PCM_FORMAT_S24_BE,
385
+     SND_PCM_FORMAT_U24_LE,
386
+     SND_PCM_FORMAT_U24_BE,
387
+     SND_PCM_FORMAT_S32_LE,
388
+     SND_PCM_FORMAT_S32_BE,
389
+     SND_PCM_FORMAT_U32_LE,
390
+     SND_PCM_FORMAT_U32_BE,
391
+     SND_PCM_FORMAT_FLOAT_LE,
392
+     SND_PCM_FORMAT_FLOAT_BE,
393
+     SND_PCM_FORMAT_FLOAT64_LE,
394
+     SND_PCM_FORMAT_FLOAT64_BE,
395
+     SND_PCM_FORMAT_IEC958_SUBFRAME_LE,
396
+     SND_PCM_FORMAT_IEC958_SUBFRAME_BE,
397
+     SND_PCM_FORMAT_MU_LAW,
398
+     SND_PCM_FORMAT_A_LAW,
399
+     SND_PCM_FORMAT_IMA_ADPCM,
400
+     SND_PCM_FORMAT_MPEG,
401
+     SND_PCM_FORMAT_GSM,
402
+     SND_PCM_FORMAT_SPECIAL,
403
+     SND_PCM_FORMAT_S24_3LE,
404
+     SND_PCM_FORMAT_S24_3BE,
405
+     SND_PCM_FORMAT_U24_3LE,
406
+     SND_PCM_FORMAT_U24_3BE,
407
+     SND_PCM_FORMAT_S20_3LE,
408
+     SND_PCM_FORMAT_S20_3BE,
409
+     SND_PCM_FORMAT_U20_3LE,
410
+     SND_PCM_FORMAT_U20_3BE,
411
+     SND_PCM_FORMAT_S18_3LE,
412
+     SND_PCM_FORMAT_S18_3BE,
413
+     SND_PCM_FORMAT_U18_3LE,
414
+     SND_PCM_FORMAT_U18_3BE,
415
+     SND_PCM_FORMAT_G723_24,
416
+     SND_PCM_FORMAT_G723_24_1B,
417
+     SND_PCM_FORMAT_G723_40,
418
+     SND_PCM_FORMAT_G723_40_1B,
419
+     SND_PCM_FORMAT_DSD_U8,
420
+     //SND_PCM_FORMAT_DSD_U16_LE,
421
+     //SND_PCM_FORMAT_DSD_U32_LE,
422
+     //SND_PCM_FORMAT_DSD_U16_BE,
423
+     //SND_PCM_FORMAT_DSD_U32_BE,
424
+     SND_PCM_FORMAT_UNKNOWN 
425
+  };
426
+
427
+  snd_pcm_format_mask_alloca(&mask);
428
+
429
+  snd_pcm_hw_params_get_format_mask(hwParams,mask);
430
+
431
+  cmRptPrintf(rpt,"Formats: " );
432
+  
433
+  int i;
434
+  for(i=0; fmt[i]!=SND_PCM_FORMAT_UNKNOWN; ++i)
435
+    if( snd_pcm_format_mask_test(mask, fmt[i] ))
436
+      cmRptPrintf(rpt,"%s%s",snd_pcm_format_name(fmt[i]), snd_pcm_format_cpu_endian(fmt[i]) ? " " : " (swap) ");
437
+  
438
+  cmRptPrintf(rpt,"\n");
439
+  
440
+}
441
+
365 442
 void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
366 443
 {
367 444
   bool       inputFl = true;
@@ -377,7 +454,7 @@ void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
377 454
   {
378 455
     if( ((inputFl==true) && (drp->flags&kInFl)) || (((inputFl==false) && (drp->flags&kOutFl))))
379 456
     {
380
-      const char* ioLabel = inputFl ? "In" : "Out";
457
+      const char* ioLabel = inputFl ? "In " : "Out";
381 458
 
382 459
       // attempt to open the sub-device
383 460
       if((err = snd_pcm_open(&pcmH,drp->nameStr,inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,0)) < 0 )
@@ -435,6 +512,8 @@ void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
435 512
             ioLabel,minChCnt,maxChCnt,minSrate,maxSrate,minPeriodFrmCnt,maxPeriodFrmCnt,minBufFrmCnt,maxBufFrmCnt,
436 513
             (snd_pcm_hw_params_is_half_duplex(hwParams)  ? "yes" : "no"),
437 514
             (snd_pcm_hw_params_is_joint_duplex(hwParams) ? "yes" : "no"));
515
+          
516
+          _cmApDevReportFormats( rpt, hwParams );
438 517
         }
439 518
 
440 519
         if((err = snd_pcm_close(pcmH)) < 0)
@@ -610,6 +689,28 @@ void _cmApStateRecover( snd_pcm_t* pcmH, cmApDevRecd_t* drp, bool inputFl  )
610 689
   
611 690
 }
612 691
 
692
+void _cmApS24_3BE_to_Float( const char* x, cmApSample_t* y, unsigned n )
693
+{
694
+  unsigned i;
695
+  for(i=0; i<n; ++i,x+=3)
696
+  {
697
+    int s = (((int)x[0])<<16) + (((int)x[1])<<8) + (((int)x[2]));
698
+    y[i] = ((cmApSample_t)s)/0x7fffff;
699
+  }
700
+}
701
+
702
+void _cmApS24_3BE_from_Float( const cmApSample_t* x, char* y, unsigned n )
703
+{
704
+  unsigned i;
705
+  for(i=0; i<n; ++i)
706
+  {
707
+    int s = x[i] * 0x7fffff;
708
+    y[i*3+2] = (char)((s & 0x7f0000) >> 16);
709
+    y[i*3+1] = (char)((s & 0x00ff00) >>  8);
710
+    y[i*3+0] = (char)((s & 0x0000ff) >>  0);
711
+  }
712
+}
713
+
613 714
 
614 715
 // Returns count of frames written on success or < 0 on error;
615 716
 // set smpPtr to NULL to write a buffer of silence
@@ -648,9 +749,13 @@ int _cmApWriteBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, const cmApSample_t* sp,
648 749
 
649 750
       case 24:
650 751
         {
752
+          // for use w/ MBox
753
+          //_cmApS24_3BE_from_Float(sp, obuf, ep-sp );
754
+          
651 755
           int* dp = (int*)obuf;
652 756
           while( sp < ep )
653 757
             *dp++ = (int)(*sp++ * 0x7fffff);        
758
+            
654 759
         }
655 760
         break;
656 761
 
@@ -696,7 +801,6 @@ int _cmApWriteBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, const cmApSample_t* sp,
696 801
 }
697 802
 
698 803
 
699
-
700 804
 // Returns frames read on success or < 0 on error.
701 805
 // Set smpPtr to NULL to read the incoming buffer and discard it
702 806
 int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
@@ -729,7 +833,6 @@ int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, uns
729 833
 
730 834
   // setup the return buffer
731 835
   cmApSample_t* dp = smpPtr;
732
-
733 836
   cmApSample_t* ep = dp + cmMin(smpCnt,err*chCnt);
734 837
   
735 838
   switch(bits)
@@ -752,6 +855,8 @@ int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, uns
752 855
 
753 856
     case 24:
754 857
       {
858
+        // For use with MBox
859
+        //_cmApS24_3BE_to_Float(buf, dp, ep-dp );
755 860
         int* sp = (int*)buf;
756 861
         while(dp < ep)
757 862
           *dp++ = ((cmApSample_t)*sp++) /  0x7fffff;
@@ -819,7 +924,7 @@ void _cmApStaticAsyncHandler( snd_async_handler_t* ahandler )
819 924
   while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
820 925
   {
821 926
 
822
-    // Handle inpuut
927
+    // Handle input
823 928
     if( inputFl )
824 929
     {
825 930
       // read samples from the device
@@ -1024,7 +1129,21 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
1024 1129
   snd_pcm_uframes_t bufferFrameCnt;
1025 1130
   unsigned          bits           = 0;
1026 1131
   int               sig_bits       = 0;
1132
+  bool              signFl         = true;
1133
+  bool              swapFl         = false;
1027 1134
   cmApRoot_t*       p              = drp->rootPtr;
1135
+
1136
+  snd_pcm_format_t fmt[] =
1137
+  {
1138
+    SND_PCM_FORMAT_S32_LE,
1139
+    SND_PCM_FORMAT_S32_BE,
1140
+    SND_PCM_FORMAT_S24_LE,
1141
+    SND_PCM_FORMAT_S24_BE,
1142
+    SND_PCM_FORMAT_S24_3LE,
1143
+    SND_PCM_FORMAT_S24_3BE,
1144
+    SND_PCM_FORMAT_S16_LE,
1145
+    SND_PCM_FORMAT_S16_BE,
1146
+  };
1028 1147
   
1029 1148
 
1030 1149
   // setup input, then output device
@@ -1041,7 +1160,6 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
1041 1160
       if( _cmApDevShutdown(p, drp, inputFl ) != kOkApRC )
1042 1161
         retFl = false;
1043 1162
 
1044
-
1045 1163
       // attempt to open the sub-device
1046 1164
       if((err = snd_pcm_open(&pcmH,drp->nameStr, inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 0)) < 0 )
1047 1165
         retFl = _cmApDevSetupError(p,err,inputFl,drp,"Unable to open the PCM handle");
@@ -1075,23 +1193,23 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
1075 1193
 
1076 1194
           if((err = snd_pcm_hw_params_set_access(pcmH,hwParams,SND_PCM_ACCESS_RW_INTERLEAVED )) < 0 )
1077 1195
             retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set access to: RW Interleaved");
1078
-		  
1079
-          // select the widest possible sample width
1080
-          if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,SND_PCM_FORMAT_S32)) >= 0 )
1081
-            bits = 32;
1196
+          
1197
+          // select the format width
1198
+          int j;
1199
+          int fmtN = sizeof(fmt)/sizeof(fmt[0]);
1200
+          for(j=0; j<fmtN; ++j)
1201
+            if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,fmt[j])) >= 0 )
1202
+              break;
1203
+
1204
+          if( j == fmtN )
1205
+            retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set format to: S16");
1082 1206
           else
1083 1207
           {
1084
-            if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,SND_PCM_FORMAT_S24)) >= 0 )
1085
-              bits = 24;
1086
-            else
1087
-            {
1088
-              if((err = snd_pcm_hw_params_set_format(pcmH,hwParams,SND_PCM_FORMAT_S16)) >= 0 )
1089
-                bits = 16;
1090
-              else
1091
-                retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set format to: S16");
1092
-            }
1208
+            bits = snd_pcm_format_width(fmt[j]); // bits per sample
1209
+            signFl = snd_pcm_format_signed(fmt[j]);
1210
+            swapFl = !snd_pcm_format_cpu_endian(fmt[j]);
1093 1211
           }
1094
-
1212
+          
1095 1213
           sig_bits = snd_pcm_hw_params_get_sbits(hwParams);
1096 1214
 
1097 1215
           snd_pcm_uframes_t ps_min,ps_max;
@@ -1167,6 +1285,8 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
1167 1285
         {
1168 1286
           drp->iBits    = bits;
1169 1287
           drp->iSigBits = sig_bits;
1288
+          drp->iSignFl  = signFl;
1289
+          drp->iSwapFl  = swapFl;
1170 1290
           drp->iPcmH    = pcmH;
1171 1291
           drp->iBuf     = cmMemResizeZ( cmApSample_t, drp->iBuf, actFpC * drp->iChCnt );
1172 1292
           drp->iFpC     = actFpC;
@@ -1175,6 +1295,8 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
1175 1295
         {
1176 1296
           drp->oBits    = bits;
1177 1297
           drp->oSigBits = sig_bits;
1298
+          drp->oSignFl  = signFl;
1299
+          drp->oSwapFl  = swapFl;
1178 1300
           drp->oPcmH    = pcmH;
1179 1301
           drp->oBuf     = cmMemResizeZ( cmApSample_t, drp->oBuf, actFpC * drp->oChCnt );
1180 1302
           drp->oFpC     = actFpC;
@@ -1448,7 +1570,7 @@ cmApRC_t      cmApAlsaInitialize( cmRpt_t* rpt, unsigned baseApDevIdx )
1448 1570
                 // this device uses this subdevice in the current direction 
1449 1571
                 dr.flags += inputFl ? kInFl : kOutFl;
1450 1572
 
1451
-              printf("%s in:%i chs:%i rate:%i\n",dr.nameStr,inputFl,*chCntPtr,rate);
1573
+              //printf("%s in:%i chs:%i rate:%i\n",dr.nameStr,inputFl,*chCntPtr,rate);
1452 1574
               
1453 1575
             }                        
1454 1576
 

Загрузка…
Отмена
Сохранить