cwAudioDevFile.h/cpp, cwIo.cpp : Implemented input cache on audio dev file.
This commit is contained in:
parent
2fc2f7f4b0
commit
03061f42b7
@ -48,13 +48,17 @@ namespace cw
|
||||
unsigned iChCnt;
|
||||
bool iEnableFl;
|
||||
audioPacket_t iPkt;
|
||||
float* iPktAudioBuf;
|
||||
sample_t* iPktAudioBuf;
|
||||
unsigned iCbCnt;
|
||||
float** iChArray; // iChArray[2]
|
||||
float* iChSmpBuf; //
|
||||
sample_t** iChArray; // iChArray[ iChCnt ]
|
||||
sample_t* iChSmpBuf; //
|
||||
unsigned iErrCnt; // count of errors
|
||||
unsigned iFrmCnt; // count of frames read
|
||||
|
||||
sample_t* iCacheBuf; // iCacheFrameBuf[ iCacheFrameN * iChCnt ] (interleaved)
|
||||
unsigned iCacheFrameN; // count of frames in iCacheBuf
|
||||
unsigned iCacheIdx; // next frame to read (always at channel 0)
|
||||
|
||||
char* oFname;
|
||||
audiofile::handle_t oFileH;
|
||||
unsigned oFlags;
|
||||
@ -62,10 +66,10 @@ namespace cw
|
||||
bool oEnableFl;
|
||||
unsigned oBitsPerSample;
|
||||
audioPacket_t oPkt;
|
||||
float* oPktAudioBuf;
|
||||
sample_t* oPktAudioBuf;
|
||||
unsigned oCbCnt;
|
||||
float** oChArray; // oChArray[2]
|
||||
float* oChSmpBuf; //
|
||||
sample_t** oChArray; // oChArray[2]
|
||||
sample_t* oChSmpBuf; //
|
||||
unsigned oErrCnt; // count of errors
|
||||
unsigned oFrmCnt; // count of frames written
|
||||
|
||||
@ -169,9 +173,104 @@ namespace cw
|
||||
mem::release(d->iPktAudioBuf);
|
||||
mem::release(d->iChArray);
|
||||
mem::release(d->iChSmpBuf);
|
||||
mem::release(d->iCacheBuf);
|
||||
}
|
||||
}
|
||||
|
||||
rc_t _fill_input_packet_from_cache( dev_t* d )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
unsigned n = d->framesPerCycle;
|
||||
unsigned m = d->framesPerCycle;
|
||||
|
||||
// set n to the count of frames to copy from the cache into the pkt
|
||||
if( d->iCacheIdx + n > d->iCacheFrameN )
|
||||
n = d->iCacheFrameN - d->iCacheIdx;
|
||||
|
||||
if( n > 0 )
|
||||
{
|
||||
memcpy( d->iPktAudioBuf, d->iCacheBuf + (d->iCacheIdx * d->iChCnt), d->framesPerCycle * d->iChCnt * sizeof(sample_t));
|
||||
d->iCacheIdx += n;
|
||||
|
||||
// set m to the count of frames to zero at the end of the pkt
|
||||
m = d->framesPerCycle - n;
|
||||
}
|
||||
|
||||
if( m > 0 )
|
||||
{
|
||||
memset( d->iPktAudioBuf + (n*d->iChCnt), 0, m * d->iChCnt * sizeof(sample_t));
|
||||
d->iCacheIdx = d->iCacheFrameN;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _fill_input_packet_from_file( dev_t* d )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
unsigned actualFrameCnt = 0;
|
||||
|
||||
// read the file
|
||||
if((rc = readFloat(d->iFileH, d->framesPerCycle, 0, d->iChCnt, d->iChArray, &actualFrameCnt)) == kOkRC )
|
||||
d->iFrmCnt += actualFrameCnt;
|
||||
else
|
||||
{
|
||||
rc = cwLogError(rc,"File read failed on audio device file: %s.",cwStringNullGuard(d->label));
|
||||
d->iErrCnt += 1;
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
// interleave into the iPkt audio buffer
|
||||
vop::interleave( d->iPktAudioBuf, d->iChSmpBuf, actualFrameCnt, d->iChCnt );
|
||||
|
||||
if( actualFrameCnt < d->framesPerCycle )
|
||||
{
|
||||
for(unsigned i=0; i<d->iChCnt; ++i)
|
||||
vop::fill( d->iPktAudioBuf + (actualFrameCnt * d->iChCnt) + i, 0, d->framesPerCycle-actualFrameCnt, d->iChCnt );
|
||||
}
|
||||
|
||||
// d->iPktAudioBuf[] now contains d->framesPerCycle*d->iChCnt samples
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _cache_input( dev_t* d, unsigned frameN )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
unsigned n = 0;
|
||||
|
||||
d->iCacheFrameN = frameN;
|
||||
d->iCacheBuf = mem::resize<sample_t>(d->iCacheBuf, d->iCacheFrameN * d->iChCnt);
|
||||
d->iCacheIdx = 0;
|
||||
|
||||
while(n < d->iCacheFrameN )
|
||||
{
|
||||
if((rc = _fill_input_packet_from_file(d)) != kOkRC )
|
||||
{
|
||||
rc = cwLogError(rc,"Read failed while reading the input cache.");
|
||||
d->iCacheFrameN = 0; // this will prevent the cache from being used
|
||||
goto errLabel;
|
||||
}
|
||||
|
||||
unsigned copyFrameN = d->framesPerCycle;
|
||||
if( n + copyFrameN > d->iCacheFrameN )
|
||||
copyFrameN = d->iCacheFrameN - n;
|
||||
|
||||
memcpy( d->iCacheBuf + n * d->iChCnt, d->iPktAudioBuf, copyFrameN * d->iChCnt * sizeof(sample_t));
|
||||
|
||||
n += copyFrameN;
|
||||
}
|
||||
|
||||
if( n % d->iChCnt != 0 )
|
||||
{
|
||||
cwLogWarning("The cache buffer seems to have a size mismatch with the input audio file.");
|
||||
}
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc_t _open_input( dev_t* d, unsigned devIdx )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
@ -218,6 +317,11 @@ namespace cw
|
||||
for(unsigned i=0; i<d->iChCnt; ++i)
|
||||
d->iChArray[i] = d->iChSmpBuf + i*d->framesPerCycle;
|
||||
|
||||
// if input caching was requested
|
||||
if( cwIsFlag(d->iFlags,kCacheFl) )
|
||||
if((rc = _cache_input(d,info.frameCnt)) != kOkRC )
|
||||
cwLogError(rc,"Cache load failed on '%s'.",cwStringNullGuard(d->iFname));
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
@ -226,7 +330,6 @@ namespace cw
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
unsigned actualFrameCnt = 0;
|
||||
|
||||
if( !d->iEnableFl )
|
||||
{
|
||||
@ -234,26 +337,11 @@ namespace cw
|
||||
}
|
||||
else
|
||||
{
|
||||
// read the file
|
||||
if((rc = readFloat(d->iFileH, d->framesPerCycle, 0, d->iChCnt, d->iChArray, &actualFrameCnt)) == kOkRC )
|
||||
d->iFrmCnt += actualFrameCnt;
|
||||
if( d->iCacheFrameN )
|
||||
rc = _fill_input_packet_from_cache(d);
|
||||
else
|
||||
{
|
||||
rc = cwLogError(rc,"File read failed on audio device file: %s.",cwStringNullGuard(d->label));
|
||||
d->iErrCnt += 1;
|
||||
goto errLabel;
|
||||
rc = _fill_input_packet_from_file(d);
|
||||
}
|
||||
|
||||
// interleave into the iPkt audio buffer
|
||||
vop::interleave( d->iPktAudioBuf, d->iChSmpBuf, actualFrameCnt, d->iChCnt );
|
||||
|
||||
if( actualFrameCnt < d->framesPerCycle )
|
||||
{
|
||||
for(unsigned i=0; i<d->iChCnt; ++i)
|
||||
vop::fill( d->iPktAudioBuf + (actualFrameCnt * d->iChCnt) + i, 0, d->framesPerCycle-actualFrameCnt, d->iChCnt );
|
||||
}
|
||||
}
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -377,7 +465,7 @@ namespace cw
|
||||
dev_t* d = nullptr;
|
||||
|
||||
// block on the cond. var - unlock the mutex
|
||||
if((rc = mutex::waitOnCondVar(p->mutexH,false,p->threadTimeOutMs)) != kOkRC )
|
||||
if((rc = mutex::waitOnCondVar(p->mutexH,false,p->threadTimeOutMs/2)) != kOkRC )
|
||||
{
|
||||
if( rc != kTimeOutRC )
|
||||
{
|
||||
@ -658,6 +746,7 @@ cw::rc_t cw::audio::device::file::deviceStart( struct driver_str* dr
|
||||
|
||||
if((rc0 = _indexToDev( p, devIdx, d )) == kOkRC )
|
||||
{
|
||||
/*
|
||||
if( d->iFileH.isValid() && cwIsFlag(d->iFlags,kRewindOnStartFl) )
|
||||
if((rc0 = seek(d->iFileH,0)) != kOkRC )
|
||||
rc0 = cwLogError(rc0,"Rewind on start failed on the audio device file input file.");
|
||||
@ -665,6 +754,7 @@ cw::rc_t cw::audio::device::file::deviceStart( struct driver_str* dr
|
||||
if( d->oFileH.isValid() && cwIsFlag(d->oFlags,kRewindOnStartFl) )
|
||||
if((rc1 = seek(d->oFileH,0)) != kOkRC )
|
||||
rc1 = cwLogError(rc1,"Rewind on start failed on the audio device file output file.");
|
||||
*/
|
||||
}
|
||||
|
||||
if((rc0 = rcSelect(rc0,rc1)) == kOkRC )
|
||||
@ -734,8 +824,6 @@ cw::rc_t cw::audio::device::file::deviceEnable( struct driver_str* drv, unsigne
|
||||
else
|
||||
d->oEnableFl = enableFl;
|
||||
|
||||
printf("Enable i:%i o:%i\n",d->iEnableFl,d->oEnableFl);
|
||||
|
||||
errLabel:
|
||||
return rc;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ namespace cw
|
||||
|
||||
enum {
|
||||
kRewindOnStartFl = 0x01,
|
||||
kCacheFl = 0x02
|
||||
};
|
||||
|
||||
// A device may have an input, an output or both.
|
||||
|
4
cwIo.cpp
4
cwIo.cpp
@ -1878,6 +1878,7 @@ namespace cw
|
||||
const char* label = nullptr;
|
||||
const char* iFname = nullptr;
|
||||
bool iRwdOnStartFl = false;
|
||||
bool iCacheFl = true;
|
||||
|
||||
const char* oFname = nullptr;
|
||||
unsigned oChCnt = 0;
|
||||
@ -1892,6 +1893,7 @@ namespace cw
|
||||
if((rc = fnode->getv_opt("enableFl", enableFl,
|
||||
"in_fname", iFname,
|
||||
"in_rewind_on_start_fl",iRwdOnStartFl,
|
||||
"in_cache_fl",iCacheFl,
|
||||
"out_fname", oFname,
|
||||
"out_rewind_on_start_fl",oRwdOnStartFl,
|
||||
"out_ch_count", oChCnt )) != kOkRC )
|
||||
@ -1907,6 +1909,8 @@ namespace cw
|
||||
{
|
||||
unsigned iFlags = iRwdOnStartFl ? audio::device::file::kRewindOnStartFl : 0;
|
||||
|
||||
iFlags += iCacheFl ? audio::device::file::kCacheFl : 0;
|
||||
|
||||
if((rc = createInDevice( p->audioDevFileH, label, iFname, iFlags )) != kOkRC )
|
||||
{
|
||||
cwLogError(rc,"Create failed on input audio device file '%s'.",cwStringNullGuard(label));
|
||||
|
Loading…
Reference in New Issue
Block a user