ソースを参照

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年前
コミット
f48cc2e7f7
1個のファイルの変更144行の追加22行の削除
  1. 144
    22
      linux/cmAudioPortAlsa.c

+ 144
- 22
linux/cmAudioPortAlsa.c ファイルの表示

40
   snd_async_handler_t* ahandler;
40
   snd_async_handler_t* ahandler;
41
   unsigned             srate;          // device sample rate
41
   unsigned             srate;          // device sample rate
42
 
42
 
43
-  unsigned             iChCnt;  // ch count 
43
+  unsigned             iChCnt;         // ch count 
44
   unsigned             oChCnt;
44
   unsigned             oChCnt;
45
 
45
 
46
   unsigned             iBits;          // bits per sample
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
   unsigned             iSigBits;       // significant bits in each sample beginning
55
   unsigned             iSigBits;       // significant bits in each sample beginning
50
   unsigned             oSigBits;       // with the most sig. bit.
56
   unsigned             oSigBits;       // with the most sig. bit.
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
 void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
442
 void _cmApDevReport( cmRpt_t* rpt, cmApDevRecd_t* drp )
366
 {
443
 {
367
   bool       inputFl = true;
444
   bool       inputFl = true;
377
   {
454
   {
378
     if( ((inputFl==true) && (drp->flags&kInFl)) || (((inputFl==false) && (drp->flags&kOutFl))))
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
       // attempt to open the sub-device
459
       // attempt to open the sub-device
383
       if((err = snd_pcm_open(&pcmH,drp->nameStr,inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,0)) < 0 )
460
       if((err = snd_pcm_open(&pcmH,drp->nameStr,inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK,0)) < 0 )
435
             ioLabel,minChCnt,maxChCnt,minSrate,maxSrate,minPeriodFrmCnt,maxPeriodFrmCnt,minBufFrmCnt,maxBufFrmCnt,
512
             ioLabel,minChCnt,maxChCnt,minSrate,maxSrate,minPeriodFrmCnt,maxPeriodFrmCnt,minBufFrmCnt,maxBufFrmCnt,
436
             (snd_pcm_hw_params_is_half_duplex(hwParams)  ? "yes" : "no"),
513
             (snd_pcm_hw_params_is_half_duplex(hwParams)  ? "yes" : "no"),
437
             (snd_pcm_hw_params_is_joint_duplex(hwParams) ? "yes" : "no"));
514
             (snd_pcm_hw_params_is_joint_duplex(hwParams) ? "yes" : "no"));
515
+          
516
+          _cmApDevReportFormats( rpt, hwParams );
438
         }
517
         }
439
 
518
 
440
         if((err = snd_pcm_close(pcmH)) < 0)
519
         if((err = snd_pcm_close(pcmH)) < 0)
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
 // Returns count of frames written on success or < 0 on error;
715
 // Returns count of frames written on success or < 0 on error;
615
 // set smpPtr to NULL to write a buffer of silence
716
 // set smpPtr to NULL to write a buffer of silence
648
 
749
 
649
       case 24:
750
       case 24:
650
         {
751
         {
752
+          // for use w/ MBox
753
+          //_cmApS24_3BE_from_Float(sp, obuf, ep-sp );
754
+          
651
           int* dp = (int*)obuf;
755
           int* dp = (int*)obuf;
652
           while( sp < ep )
756
           while( sp < ep )
653
             *dp++ = (int)(*sp++ * 0x7fffff);        
757
             *dp++ = (int)(*sp++ * 0x7fffff);        
758
+            
654
         }
759
         }
655
         break;
760
         break;
656
 
761
 
696
 }
801
 }
697
 
802
 
698
 
803
 
699
-
700
 // Returns frames read on success or < 0 on error.
804
 // Returns frames read on success or < 0 on error.
701
 // Set smpPtr to NULL to read the incoming buffer and discard it
805
 // Set smpPtr to NULL to read the incoming buffer and discard it
702
 int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
806
 int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, cmApSample_t* smpPtr, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
729
 
833
 
730
   // setup the return buffer
834
   // setup the return buffer
731
   cmApSample_t* dp = smpPtr;
835
   cmApSample_t* dp = smpPtr;
732
-
733
   cmApSample_t* ep = dp + cmMin(smpCnt,err*chCnt);
836
   cmApSample_t* ep = dp + cmMin(smpCnt,err*chCnt);
734
   
837
   
735
   switch(bits)
838
   switch(bits)
752
 
855
 
753
     case 24:
856
     case 24:
754
       {
857
       {
858
+        // For use with MBox
859
+        //_cmApS24_3BE_to_Float(buf, dp, ep-dp );
755
         int* sp = (int*)buf;
860
         int* sp = (int*)buf;
756
         while(dp < ep)
861
         while(dp < ep)
757
           *dp++ = ((cmApSample_t)*sp++) /  0x7fffff;
862
           *dp++ = ((cmApSample_t)*sp++) /  0x7fffff;
819
   while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
924
   while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
820
   {
925
   {
821
 
926
 
822
-    // Handle inpuut
927
+    // Handle input
823
     if( inputFl )
928
     if( inputFl )
824
     {
929
     {
825
       // read samples from the device
930
       // read samples from the device
1024
   snd_pcm_uframes_t bufferFrameCnt;
1129
   snd_pcm_uframes_t bufferFrameCnt;
1025
   unsigned          bits           = 0;
1130
   unsigned          bits           = 0;
1026
   int               sig_bits       = 0;
1131
   int               sig_bits       = 0;
1132
+  bool              signFl         = true;
1133
+  bool              swapFl         = false;
1027
   cmApRoot_t*       p              = drp->rootPtr;
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
   // setup input, then output device
1149
   // setup input, then output device
1041
       if( _cmApDevShutdown(p, drp, inputFl ) != kOkApRC )
1160
       if( _cmApDevShutdown(p, drp, inputFl ) != kOkApRC )
1042
         retFl = false;
1161
         retFl = false;
1043
 
1162
 
1044
-
1045
       // attempt to open the sub-device
1163
       // attempt to open the sub-device
1046
       if((err = snd_pcm_open(&pcmH,drp->nameStr, inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 0)) < 0 )
1164
       if((err = snd_pcm_open(&pcmH,drp->nameStr, inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 0)) < 0 )
1047
         retFl = _cmApDevSetupError(p,err,inputFl,drp,"Unable to open the PCM handle");
1165
         retFl = _cmApDevSetupError(p,err,inputFl,drp,"Unable to open the PCM handle");
1075
 
1193
 
1076
           if((err = snd_pcm_hw_params_set_access(pcmH,hwParams,SND_PCM_ACCESS_RW_INTERLEAVED )) < 0 )
1194
           if((err = snd_pcm_hw_params_set_access(pcmH,hwParams,SND_PCM_ACCESS_RW_INTERLEAVED )) < 0 )
1077
             retFl = _cmApDevSetupError(p,err,inputFl, drp, "Unable to set access to: RW Interleaved");
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
           else
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
           sig_bits = snd_pcm_hw_params_get_sbits(hwParams);
1213
           sig_bits = snd_pcm_hw_params_get_sbits(hwParams);
1096
 
1214
 
1097
           snd_pcm_uframes_t ps_min,ps_max;
1215
           snd_pcm_uframes_t ps_min,ps_max;
1167
         {
1285
         {
1168
           drp->iBits    = bits;
1286
           drp->iBits    = bits;
1169
           drp->iSigBits = sig_bits;
1287
           drp->iSigBits = sig_bits;
1288
+          drp->iSignFl  = signFl;
1289
+          drp->iSwapFl  = swapFl;
1170
           drp->iPcmH    = pcmH;
1290
           drp->iPcmH    = pcmH;
1171
           drp->iBuf     = cmMemResizeZ( cmApSample_t, drp->iBuf, actFpC * drp->iChCnt );
1291
           drp->iBuf     = cmMemResizeZ( cmApSample_t, drp->iBuf, actFpC * drp->iChCnt );
1172
           drp->iFpC     = actFpC;
1292
           drp->iFpC     = actFpC;
1175
         {
1295
         {
1176
           drp->oBits    = bits;
1296
           drp->oBits    = bits;
1177
           drp->oSigBits = sig_bits;
1297
           drp->oSigBits = sig_bits;
1298
+          drp->oSignFl  = signFl;
1299
+          drp->oSwapFl  = swapFl;
1178
           drp->oPcmH    = pcmH;
1300
           drp->oPcmH    = pcmH;
1179
           drp->oBuf     = cmMemResizeZ( cmApSample_t, drp->oBuf, actFpC * drp->oChCnt );
1301
           drp->oBuf     = cmMemResizeZ( cmApSample_t, drp->oBuf, actFpC * drp->oChCnt );
1180
           drp->oFpC     = actFpC;
1302
           drp->oFpC     = actFpC;
1448
                 // this device uses this subdevice in the current direction 
1570
                 // this device uses this subdevice in the current direction 
1449
                 dr.flags += inputFl ? kInFl : kOutFl;
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
 

読み込み中…
キャンセル
保存