Procházet zdrojové kódy

cmAudioPortAlsa.c : _cmApThreadFunc() now generates a cmTimeSpec_t timestamp.

master
kevin před 11 roky
rodič
revize
2080d13eb2
1 změnil soubory, kde provedl 59 přidání a 2 odebrání
  1. 59
    2
      linux/cmAudioPortAlsa.c

+ 59
- 2
linux/cmAudioPortAlsa.c Zobrazit soubor

@@ -2,6 +2,7 @@
2 2
 #include "cmPrefix.h"
3 3
 #include "cmGlobal.h"
4 4
 #include "cmRpt.h"
5
+#include "cmTime.h"
5 6
 #include "cmAudioPort.h"
6 7
 #include "cmMem.h"
7 8
 #include "cmTime.h"
@@ -598,7 +599,6 @@ void _cmApStateRecover( snd_pcm_t* pcmH, cmApDevRecd_t* drp, bool inputFl  )
598 599
 // set smpPtr to NULL to write a buffer of silence
599 600
 int _cmApWriteBuf( const cmApDevRecd_t* drp, snd_pcm_t* pcmH, const cmApSample_t* sp, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
600 601
 {
601
-
602 602
   int                 err         = 0;
603 603
   unsigned            bytesPerSmp = (bits==24 ? 32 : bits)/8;
604 604
   unsigned            smpCnt      = chCnt * frmCnt;
@@ -774,13 +774,14 @@ void _cmApStaticAsyncHandler( snd_async_handler_t* ahandler )
774 774
   pkt.flags                = kInterleavedApFl | kFloatApFl;
775 775
   pkt.audioBytesPtr        = b;
776 776
   pkt.userCbPtr            = drp->userCbPtr;
777
- 
777
+  
778 778
   recdCb(drp,inputFl,0);
779 779
 
780 780
   _cmApStateRecover( pcmH, drp, inputFl );
781 781
   
782 782
   while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
783 783
   {
784
+
784 785
     // Handle inpuut
785 786
     if( inputFl )
786 787
     {
@@ -853,6 +854,7 @@ bool _cmApThreadFunc(void* param)
853 854
           unsigned short    revents = 0;
854 855
           int               err;
855 856
           cmApAudioPacket_t pkt;
857
+          snd_pcm_uframes_t avail_frames;
856 858
 
857 859
           inputFl ? drp->iCbCnt++ : drp->oCbCnt++;
858 860
           
@@ -867,6 +869,35 @@ bool _cmApThreadFunc(void* param)
867 869
 
868 870
           inputFl ? drp->iCbCnt++ : drp->oCbCnt++;
869 871
 
872
+          // get the timestamp for this buffer
873
+          if((err = snd_pcm_htimestamp(pcmH,&avail_frames,&pkt.timeStamp)) != 0 )
874
+          {
875
+            _cmApDevSetupError(p, err, p->pollfdsDesc[i].inputFl, drp, "Get timestamp error.");
876
+            pkt.timeStamp.tv_sec  = 0;
877
+            pkt.timeStamp.tv_nsec = 0;
878
+          }
879
+
880
+          // Note that based on experimenting with the timestamp and the current
881
+          // clock_gettime(CLOCK_MONOTONIC) time it appears that the time stamp
882
+          // marks the end of the current buffer - so in fact the time stamp should
883
+          // be backed up by the availble sample count period to get the time of the 
884
+          // first sample in the buffer
885
+          /*
886
+          unsigned avail_nano_secs = (unsigned)(avail_frames * (1000000000.0/drp->srate));
887
+          if( pkt.timeStamp.tv_nsec > avail_nano_secs )
888
+            pkt.timeStamp.tv_nsec -= avail_nano_secs;
889
+          else
890
+          {
891
+            pkt.timeStamp.tv_sec -= 1;
892
+            pkt.timeStamp.tv_nsec = 1000000000 - avail_nano_secs;
893
+          }
894
+          */
895
+
896
+          //printf("AUDI: %ld %ld\n",pkt.timeStamp.tv_sec,pkt.timeStamp.tv_nsec);
897
+          //cmTimeSpec_t t;
898
+          //clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&t);
899
+          //printf("AUDI: %ld %ld\n",t.tv_sec,t.tv_nsec);
900
+          
870 901
 
871 902
           switch( snd_pcm_state(pcmH) )
872 903
           {
@@ -910,6 +941,22 @@ bool _cmApThreadFunc(void* param)
910 941
 
911 942
           if( !inputFl && (revents & POLLOUT) )
912 943
           {
944
+
945
+            /*
946
+            unsigned srate = 96;
947
+            cmTimeSpec_t t1;
948
+            static cmTimeSpec_t t0 = {0,0};
949
+            clock_gettime(CLOCK_MONOTONIC,&t1);
950
+
951
+            // time since the time-stamp was generated
952
+            unsigned smp =  (srate * (t1.tv_nsec - pkt.timeStamp.tv_nsec)) / 1000000;
953
+
954
+            // time since the last output buffer was sent
955
+            unsigned dsmp = (srate * (t1.tv_nsec - t0.tv_nsec)) / 1000000;
956
+            printf("%i %ld %i : %ld %ld -> %ld %ld\n",smp,avail_frames,dsmp,pkt.timeStamp.tv_sec,pkt.timeStamp.tv_nsec,t1.tv_sec,t1.tv_nsec);          
957
+            t0 = t1;
958
+            */
959
+
913 960
             // callback to fill the buffer
914 961
             drp->cbPtr(NULL,0,&pkt,1);
915 962
 
@@ -1062,6 +1109,9 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
1062 1109
           if((err = snd_pcm_sw_params_set_avail_min(pcmH,swParams,periodFrameCnt)) < 0 )
1063 1110
             retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error setting the avail. min. setting.");
1064 1111
 
1112
+          if((err = snd_pcm_sw_params_set_tstamp_mode(pcmH,swParams,SND_PCM_TSTAMP_MMAP)) < 0 )
1113
+            retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error setting the time samp mode.");
1114
+
1065 1115
           if((err = snd_pcm_sw_params(pcmH,swParams)) < 0 )
1066 1116
             retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error applying sw params.");
1067 1117
         }
@@ -1589,6 +1639,13 @@ cmApRC_t      cmApAlsaDeviceStop( unsigned devIdx )
1589 1639
 	if((err = snd_pcm_drop(drp->oPcmH)) < 0 )
1590 1640
 	  retFl = _cmApDevSetupError(p,err,false,drp,"Output stop failed.");
1591 1641
 
1642
+  if( p->asyncFl == false )
1643
+    if( cmThreadPause(p->thH,kPauseThFl) != kOkThRC )
1644
+    {
1645
+      _cmApOsError(p,0,"Audio thread pause failed.");
1646
+      retFl = false;
1647
+    }
1648
+
1592 1649
   return retFl ? kOkApRC : kSysErrApRC;
1593 1650
 }
1594 1651
 

Načítá se…
Zrušit
Uložit