cmAudioPortAlsa.c : _cmApThreadFunc() now generates a cmTimeSpec_t timestamp.
This commit is contained in:
parent
e67d8f7ea5
commit
2080d13eb2
@ -2,6 +2,7 @@
|
|||||||
#include "cmPrefix.h"
|
#include "cmPrefix.h"
|
||||||
#include "cmGlobal.h"
|
#include "cmGlobal.h"
|
||||||
#include "cmRpt.h"
|
#include "cmRpt.h"
|
||||||
|
#include "cmTime.h"
|
||||||
#include "cmAudioPort.h"
|
#include "cmAudioPort.h"
|
||||||
#include "cmMem.h"
|
#include "cmMem.h"
|
||||||
#include "cmTime.h"
|
#include "cmTime.h"
|
||||||
@ -598,7 +599,6 @@ void _cmApStateRecover( snd_pcm_t* pcmH, cmApDevRecd_t* drp, bool inputFl )
|
|||||||
// set smpPtr to NULL to write a buffer of silence
|
// set smpPtr to NULL to write a buffer of silence
|
||||||
int _cmApWriteBuf( const cmApDevRecd_t* drp, snd_pcm_t* pcmH, const cmApSample_t* sp, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
|
int _cmApWriteBuf( const cmApDevRecd_t* drp, snd_pcm_t* pcmH, const cmApSample_t* sp, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits )
|
||||||
{
|
{
|
||||||
|
|
||||||
int err = 0;
|
int err = 0;
|
||||||
unsigned bytesPerSmp = (bits==24 ? 32 : bits)/8;
|
unsigned bytesPerSmp = (bits==24 ? 32 : bits)/8;
|
||||||
unsigned smpCnt = chCnt * frmCnt;
|
unsigned smpCnt = chCnt * frmCnt;
|
||||||
@ -774,13 +774,14 @@ void _cmApStaticAsyncHandler( snd_async_handler_t* ahandler )
|
|||||||
pkt.flags = kInterleavedApFl | kFloatApFl;
|
pkt.flags = kInterleavedApFl | kFloatApFl;
|
||||||
pkt.audioBytesPtr = b;
|
pkt.audioBytesPtr = b;
|
||||||
pkt.userCbPtr = drp->userCbPtr;
|
pkt.userCbPtr = drp->userCbPtr;
|
||||||
|
|
||||||
recdCb(drp,inputFl,0);
|
recdCb(drp,inputFl,0);
|
||||||
|
|
||||||
_cmApStateRecover( pcmH, drp, inputFl );
|
_cmApStateRecover( pcmH, drp, inputFl );
|
||||||
|
|
||||||
while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
|
while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt )
|
||||||
{
|
{
|
||||||
|
|
||||||
// Handle inpuut
|
// Handle inpuut
|
||||||
if( inputFl )
|
if( inputFl )
|
||||||
{
|
{
|
||||||
@ -853,6 +854,7 @@ bool _cmApThreadFunc(void* param)
|
|||||||
unsigned short revents = 0;
|
unsigned short revents = 0;
|
||||||
int err;
|
int err;
|
||||||
cmApAudioPacket_t pkt;
|
cmApAudioPacket_t pkt;
|
||||||
|
snd_pcm_uframes_t avail_frames;
|
||||||
|
|
||||||
inputFl ? drp->iCbCnt++ : drp->oCbCnt++;
|
inputFl ? drp->iCbCnt++ : drp->oCbCnt++;
|
||||||
|
|
||||||
@ -867,6 +869,35 @@ bool _cmApThreadFunc(void* param)
|
|||||||
|
|
||||||
inputFl ? drp->iCbCnt++ : drp->oCbCnt++;
|
inputFl ? drp->iCbCnt++ : drp->oCbCnt++;
|
||||||
|
|
||||||
|
// get the timestamp for this buffer
|
||||||
|
if((err = snd_pcm_htimestamp(pcmH,&avail_frames,&pkt.timeStamp)) != 0 )
|
||||||
|
{
|
||||||
|
_cmApDevSetupError(p, err, p->pollfdsDesc[i].inputFl, drp, "Get timestamp error.");
|
||||||
|
pkt.timeStamp.tv_sec = 0;
|
||||||
|
pkt.timeStamp.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note that based on experimenting with the timestamp and the current
|
||||||
|
// clock_gettime(CLOCK_MONOTONIC) time it appears that the time stamp
|
||||||
|
// marks the end of the current buffer - so in fact the time stamp should
|
||||||
|
// be backed up by the availble sample count period to get the time of the
|
||||||
|
// first sample in the buffer
|
||||||
|
/*
|
||||||
|
unsigned avail_nano_secs = (unsigned)(avail_frames * (1000000000.0/drp->srate));
|
||||||
|
if( pkt.timeStamp.tv_nsec > avail_nano_secs )
|
||||||
|
pkt.timeStamp.tv_nsec -= avail_nano_secs;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pkt.timeStamp.tv_sec -= 1;
|
||||||
|
pkt.timeStamp.tv_nsec = 1000000000 - avail_nano_secs;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//printf("AUDI: %ld %ld\n",pkt.timeStamp.tv_sec,pkt.timeStamp.tv_nsec);
|
||||||
|
//cmTimeSpec_t t;
|
||||||
|
//clock_gettime(CLOCK_PROCESS_CPUTIME_ID,&t);
|
||||||
|
//printf("AUDI: %ld %ld\n",t.tv_sec,t.tv_nsec);
|
||||||
|
|
||||||
|
|
||||||
switch( snd_pcm_state(pcmH) )
|
switch( snd_pcm_state(pcmH) )
|
||||||
{
|
{
|
||||||
@ -910,6 +941,22 @@ bool _cmApThreadFunc(void* param)
|
|||||||
|
|
||||||
if( !inputFl && (revents & POLLOUT) )
|
if( !inputFl && (revents & POLLOUT) )
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/*
|
||||||
|
unsigned srate = 96;
|
||||||
|
cmTimeSpec_t t1;
|
||||||
|
static cmTimeSpec_t t0 = {0,0};
|
||||||
|
clock_gettime(CLOCK_MONOTONIC,&t1);
|
||||||
|
|
||||||
|
// time since the time-stamp was generated
|
||||||
|
unsigned smp = (srate * (t1.tv_nsec - pkt.timeStamp.tv_nsec)) / 1000000;
|
||||||
|
|
||||||
|
// time since the last output buffer was sent
|
||||||
|
unsigned dsmp = (srate * (t1.tv_nsec - t0.tv_nsec)) / 1000000;
|
||||||
|
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);
|
||||||
|
t0 = t1;
|
||||||
|
*/
|
||||||
|
|
||||||
// callback to fill the buffer
|
// callback to fill the buffer
|
||||||
drp->cbPtr(NULL,0,&pkt,1);
|
drp->cbPtr(NULL,0,&pkt,1);
|
||||||
|
|
||||||
@ -1062,6 +1109,9 @@ bool _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle,
|
|||||||
if((err = snd_pcm_sw_params_set_avail_min(pcmH,swParams,periodFrameCnt)) < 0 )
|
if((err = snd_pcm_sw_params_set_avail_min(pcmH,swParams,periodFrameCnt)) < 0 )
|
||||||
retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error setting the avail. min. setting.");
|
retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error setting the avail. min. setting.");
|
||||||
|
|
||||||
|
if((err = snd_pcm_sw_params_set_tstamp_mode(pcmH,swParams,SND_PCM_TSTAMP_MMAP)) < 0 )
|
||||||
|
retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error setting the time samp mode.");
|
||||||
|
|
||||||
if((err = snd_pcm_sw_params(pcmH,swParams)) < 0 )
|
if((err = snd_pcm_sw_params(pcmH,swParams)) < 0 )
|
||||||
retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error applying sw params.");
|
retFl = _cmApDevSetupError(p,err,inputFl,drp,"Error applying sw params.");
|
||||||
}
|
}
|
||||||
@ -1589,6 +1639,13 @@ cmApRC_t cmApAlsaDeviceStop( unsigned devIdx )
|
|||||||
if((err = snd_pcm_drop(drp->oPcmH)) < 0 )
|
if((err = snd_pcm_drop(drp->oPcmH)) < 0 )
|
||||||
retFl = _cmApDevSetupError(p,err,false,drp,"Output stop failed.");
|
retFl = _cmApDevSetupError(p,err,false,drp,"Output stop failed.");
|
||||||
|
|
||||||
|
if( p->asyncFl == false )
|
||||||
|
if( cmThreadPause(p->thH,kPauseThFl) != kOkThRC )
|
||||||
|
{
|
||||||
|
_cmApOsError(p,0,"Audio thread pause failed.");
|
||||||
|
retFl = false;
|
||||||
|
}
|
||||||
|
|
||||||
return retFl ? kOkApRC : kSysErrApRC;
|
return retFl ? kOkApRC : kSysErrApRC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user