From 85954c5498e973971b655b722e9cb8c0ca64c57b Mon Sep 17 00:00:00 2001 From: kpl Date: Wed, 25 Dec 2019 21:44:14 -0500 Subject: [PATCH] Changed audio system to use external driver modules. --- Makefile | 4 +- cwAudioBuf.cpp | 12 +- cwAudioBuf.h | 2 +- cwAudioDevice.cpp | 217 ++++++ cwAudioDevice.h | 95 +++ cwAudioPortAlsa.cpp => cwAudioDeviceAlsa.cpp | 761 ++++++++----------- cwAudioDeviceAlsa.h | 37 + cwAudioPort.cpp => cwAudioDeviceTest.cpp | 506 ++---------- cwAudioDeviceTest.h | 15 + cwAudioPort.h | 119 --- cwAudioPortAlsa.h | 53 -- cwCommonImpl.h | 13 + cwFile.cpp | 396 +++++----- cwFile.h | 341 +++++---- cwLex.cpp | 20 +- cwMem.h | 5 +- cwObject.cpp | 2 +- main.cpp | 13 +- setup.sh | 3 + 19 files changed, 1172 insertions(+), 1442 deletions(-) create mode 100644 cwAudioDevice.cpp create mode 100644 cwAudioDevice.h rename cwAudioPortAlsa.cpp => cwAudioDeviceAlsa.cpp (70%) create mode 100644 cwAudioDeviceAlsa.h rename cwAudioPort.cpp => cwAudioDeviceTest.cpp (53%) create mode 100644 cwAudioDeviceTest.h delete mode 100644 cwAudioPort.h delete mode 100644 cwAudioPortAlsa.h diff --git a/Makefile b/Makefile index 3f50cb4..be17d8c 100644 --- a/Makefile +++ b/Makefile @@ -17,8 +17,8 @@ SRC += cwSerialPort.cpp cwSerialPortSrv.cpp HDR += cwMidi.h cwMidiPort.h SRC += cwMidi.cpp cwMidiPort.cpp cwMidiAlsa.cpp -HDR += cwAudioBuf.h cwAudioPort.h cwAudioPortAlsa.h -SRC += cwAudioBuf.cpp cwAudioPort.cpp cwAudioPortAlsa.cpp +HDR += cwAudioBuf.h cwAudioDevice.h cwAudioDeviceAlsa.h +SRC += cwAudioBuf.cpp cwAudioDevice.cpp cwAudioDeviceAlsa.cpp cwAudioDeviceTest.cpp LIBS = -lpthread -lwebsockets -lasound diff --git a/cwAudioBuf.cpp b/cwAudioBuf.cpp index cc29f14..da85899 100644 --- a/cwAudioBuf.cpp +++ b/cwAudioBuf.cpp @@ -4,7 +4,7 @@ #include "cwMem.h" #include "cwTime.h" #include "cwTextBuf.h" -#include "cwAudioPort.h" +#include "cwAudioDevice.h" #include "cwAudioBuf.h" /* @@ -853,13 +853,11 @@ void cw::audio::buf::inputToOutput( unsigned iDevIdx, unsigned oDevIdx ) } -void cw::audio::buf::report( textBuf::handle_t tbH ) +void cw::audio::buf::report() { unsigned i,j,k; for(i=0; i<_theBuf.devCnt; ++i) { - textBuf::print(tbH,"%i ",i); - for(j=0; jfn; } - textBuf::print(tbH,"%s - i:%7i o:%7i f:%7i n:%7i err %s:%7i ", - j==0?"IN":"OUT", + cwLogInfo("%i : %s - i:%7i o:%7i f:%7i n:%7i err %s:%7i ", + i,j==0?"IN ":"OUT", ii,oi,fn,ip->n, (j==0?"over":"under"), ip->faultCnt); } - - textBuf::print(tbH,"\n"); } } diff --git a/cwAudioBuf.h b/cwAudioBuf.h index 626d206..5680cac 100644 --- a/cwAudioBuf.h +++ b/cwAudioBuf.h @@ -227,7 +227,7 @@ namespace cw void inputToOutput( unsigned inDevIdx, unsigned outDevIdx ); // Print the current buffer state. - void report( textBuf::handle_t tbH ); + void report(); // Run a buffer usage simulation to test the class. cmAudioPortTest.c calls this function. void test(); diff --git a/cwAudioDevice.cpp b/cwAudioDevice.cpp new file mode 100644 index 0000000..614fb17 --- /dev/null +++ b/cwAudioDevice.cpp @@ -0,0 +1,217 @@ +#include "cwCommon.h" +#include "cwLog.h" +#include "cwCommonImpl.h" +#include "cwMem.h" +#include "cwTime.h" +#include "cwAudioDevice.h" +#include "cwText.h" + +namespace cw +{ + namespace audio + { + namespace device + { + typedef struct drv_str + { + unsigned begIdx; + unsigned endIdx; + driver_t* drv; + struct drv_str* link; + } drv_t; + + typedef struct device_str + { + drv_t* drvList = nullptr; + unsigned nextDrvIdx = 0; + } device_t; + + inline device_t* _handleToPtr( handle_t h ){ return handleToPtr(h); } + + cw::rc_t _destroy( device_t* p ) + { + drv_t* d = p->drvList; + while( d != nullptr ) + { + drv_t* d0 = d->link; + memRelease(d); + d = d0; + } + + memRelease(p); + + return kOkRC; + } + + drv_t* _indexToDriver( device_t* p, unsigned idx ) + { + drv_t* l = p->drvList; + for(; l != nullptr; l=l->link ) + if( l->begIdx <= idx && idx <= l->endIdx ) + return l; + + cwLogError(kInvalidArgRC,"An invalid audio device index (%) was requested.",idx); + return nullptr; + } + + drv_t* _indexToDriver( handle_t h, unsigned idx ) + { + device_t* p = _handleToPtr(h); + return _indexToDriver(p,idx); + } + + } + } +} + +cw::rc_t cw::audio::device::create( handle_t& hRef ) +{ + rc_t rc; + if((rc = destroy(hRef)) != kOkRC) + return rc; + + device_t* p = memAllocZ(); + hRef.set(p); + + return rc; +} + +cw::rc_t cw::audio::device::destroy( handle_t& hRef ) +{ + rc_t rc = kOkRC; + if( !hRef.isValid() ) + return rc; + + device_t* p = _handleToPtr(hRef); + + if((rc = _destroy(p)) != kOkRC ) + return rc; + + hRef.clear(); + + return rc; +} + +cw::rc_t cw::audio::device::registerDriver( handle_t h, driver_t* drv ) +{ + device_t* p = _handleToPtr(h); + + unsigned n = drv->deviceCount( drv ); + if( n > 0 ) + { + drv_t* d = memAllocZ(); + + d->begIdx = p->nextDrvIdx; + p->nextDrvIdx += n; + d->endIdx = p->nextDrvIdx-1; + d->drv = drv; + d->link = p->drvList; + p->drvList = d; + } + + return kOkRC; +} + +unsigned cw::audio::device::deviceCount( handle_t h ) +{ + device_t* p = _handleToPtr(h); + return p->nextDrvIdx; +} + +unsigned cw::audio::device::deviceLabelToIndex( handle_t h, const char* label ) +{ + unsigned n = deviceCount(h); + unsigned i; + for(i=0; idrv->deviceLabel( d->drv, devIdx - d->begIdx ); + return nullptr; +} + +unsigned cw::audio::device::deviceChannelCount( handle_t h, unsigned devIdx, bool inputFl ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + return d->drv->deviceChannelCount( d->drv, devIdx - d->begIdx, inputFl ); + return 0; +} + +double cw::audio::device::deviceSampleRate( handle_t h, unsigned devIdx ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + return d->drv->deviceSampleRate( d->drv, devIdx - d->begIdx ); + return 0; +} + +unsigned cw::audio::device::deviceFramesPerCycle( handle_t h, unsigned devIdx, bool inputFl ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + return d->drv->deviceFramesPerCycle( d->drv, devIdx - d->begIdx, inputFl ); + return 0; +} + +cw::rc_t cw::audio::device::deviceSetup( handle_t h, unsigned devIdx, double sr, unsigned frmPerCycle, cbFunc_t cb, void* cbData ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + return d->drv->deviceSetup( d->drv, devIdx - d->begIdx, sr, frmPerCycle, cb, cbData ); + return kInvalidArgRC; +} + +cw::rc_t cw::audio::device::deviceStart( handle_t h, unsigned devIdx ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + return d->drv->deviceStart( d->drv, devIdx - d->begIdx ); + return kInvalidArgRC; +} + +cw::rc_t cw::audio::device::deviceStop( handle_t h, unsigned devIdx ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + return d->drv->deviceStop( d->drv, devIdx - d->begIdx ); + return kInvalidArgRC; +} + +bool cw::audio::device::deviceIsStarted(handle_t h, unsigned devIdx ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + return d->drv->deviceIsStarted( d->drv, devIdx - d->begIdx ); + return false; +} + +void cw::audio::device::deviceRealTimeReport( handle_t h, unsigned devIdx ) +{ + drv_t* d; + if((d = _indexToDriver(h,devIdx)) != nullptr ) + d->drv->deviceRealTimeReport( d->drv, devIdx - d->begIdx ); +} + +void cw::audio::device::report( handle_t h ) +{ + for(unsigned i=0; i handle_t; + + rc_t create( handle_t& hRef ); + rc_t destroy( handle_t& hRef ); + + rc_t registerDriver( handle_t h, driver_t* drv ); + + unsigned deviceCount( handle_t h ); + unsigned deviceLabelToIndex( handle_t h, const char* label ); + const char* deviceLabel( handle_t h, unsigned devIdx ); + unsigned deviceChannelCount( handle_t h, unsigned devIdx, bool inputFl ); + double deviceSampleRate( handle_t h, unsigned devIdx ); + unsigned deviceFramesPerCycle( handle_t h, unsigned devIdx, bool inputFl ); + rc_t deviceSetup( handle_t h, unsigned devIdx, double sr, unsigned frmPerCycle, cbFunc_t cb, void* cbData ); + rc_t deviceStart( handle_t h, unsigned devIdx ); + rc_t deviceStop( handle_t h, unsigned devIdx ); + bool deviceIsStarted( handle_t h, unsigned devIdx ); + void deviceRealTimeReport( handle_t h, unsigned devIdx ); + + void report( handle_t h ); + } + } +} + + + +#endif diff --git a/cwAudioPortAlsa.cpp b/cwAudioDeviceAlsa.cpp similarity index 70% rename from cwAudioPortAlsa.cpp rename to cwAudioDeviceAlsa.cpp index b4a9fb8..7da4278 100644 --- a/cwAudioPortAlsa.cpp +++ b/cwAudioDeviceAlsa.cpp @@ -4,9 +4,9 @@ #include "cwMem.h" #include "cwTime.h" #include "cwTextBuf.h" -#include "cwAudioPort.h" #include "cwThread.h" -#include "cwAudioPortAlsa.h" +#include "cwAudioDevice.h" +#include "cwAudioDeviceAlsa.h" #include "alsa/asoundlib.h" #include // usleep @@ -19,25 +19,18 @@ namespace cw { namespace alsa { -#define NAME_CHAR_CNT (255) -#define DESC_CHAR_CNT (255) -#define INIT_DEV_CNT (5) - - //#define IMPULSE_FN "/home/kevin/temp/recd0.txt" - enum { kDfltPeriodsPerBuf = 2, kPollfdsArrayCnt=2 }; enum { kInFl=0x01, kOutFl=0x02 }; - struct cmApRoot_str; - + struct alsa_str; typedef struct devRecd_str { - struct cmApRoot_str* rootPtr; + struct alsa_str* rootPtr; unsigned devIdx; - char nameStr[ NAME_CHAR_CNT ]; - char descStr[ DESC_CHAR_CNT ]; + char* nameStr; + char* descStr; unsigned flags; unsigned framesPerCycle; // samples per sub-buffer @@ -61,17 +54,11 @@ namespace cw unsigned oSigBits; // with the most sig. bit. - device::sample_t* iBuf; // iBuf[ iFpc * iChCnt ] - device::sample_t* oBuf; // oBuf[ oFpc * oChCnt ] + device::sample_t* iBuf; // iBuf[ iFpc * iChCnt ] + device::sample_t* oBuf; // oBuf[ oFpc * oChCnt ] unsigned oBufCnt; // count of buffers written -#ifdef IMPULSE_FN - int* recdBuf; - unsigned recdN; - unsigned recdIdx; -#endif - unsigned iFpC; // buffer frames per cycle (in ALSA this is call period_size) unsigned oFpC; @@ -84,52 +71,36 @@ namespace cw unsigned iErrCnt; // error count unsigned oErrCnt; - device::cbFunc_t cbPtr; // user callback - void* userCbPtr; + device::cbFunc_t cbFunc; // user callback + void* cbArg; - } cmApDevRecd_t; + } devRecd_t; - typedef struct cmApPoll_str + typedef struct poll_str { - cmApDevRecd_t* devPtr; + devRecd_t* devPtr; bool inputFl; unsigned fdsCnt; - } cmApPollfdsDesc_t; + } pollfdsDesc_t; - typedef struct cmApRoot_str + typedef struct alsa_str { - cmApDevRecd_t* devArray = nullptr; // array of device records - unsigned devCnt = 0; // count of actual dev recds in devArray[] - unsigned devAllocCnt = 0; // count of dev recds allocated in devArray[] - bool asyncFl = false; // true=use async callback false=use polling thread + driver_t driver; + devRecd_t* devArray = nullptr; // array of device records + unsigned devCnt = 0; // count of actual dev recds in devArray[] + unsigned devAllocCnt = 0; // count of dev recds allocated in devArray[] + bool asyncFl = false; // true=use async callback false=use polling thread - thread::handle_t thH; // polling thread + thread::handle_t thH; // polling thread - unsigned pollfdsAllocCnt = 0; // 2*devCnt (max possible in+out handles) - struct pollfd* pollfds = nullptr; // pollfds[ pollfdsAllocCnt ] - cmApPollfdsDesc_t *pollfdsDesc = nullptr; // pollfdsDesc[ pollfdsAllocCnt ] - unsigned pollfdsCnt = 0; // count of active recds in pollfds[] and pollfdsDesc[] + unsigned pollfdsAllocCnt = 0; // 2*devCnt (max possible in+out handles) + struct pollfd* pollfds = nullptr; // pollfds[ pollfdsAllocCnt ] + pollfdsDesc_t *pollfdsDesc = nullptr; // pollfdsDesc[ pollfdsAllocCnt ] + unsigned pollfdsCnt = 0; // count of active recds in pollfds[] and pollfdsDesc[] - } cmApRoot_t; - - cmApRoot_t _cmApRoot; - - enum - { - kReadErrRId, - kWriteErrRId - }; - - void recdSetup(){} - void recdPush( unsigned typeId, unsigned devIdx, bool inputFl, unsigned arg, unsigned arg1 ){} - void recdStart( const cmApDevRecd_t* drp, bool inputFl ){} - void recdCb( const cmApDevRecd_t* drp, bool inputFl, unsigned frmCnt ){} - void recdSysErr( bool inputFl, int err ){} - void recdAppErr( const cmApDevRecd_t* drp, bool inputFl, int app, int err ){} - void recdRecover( const cmApDevRecd_t* drp, bool inputFl, int err, int line ){} - void recdPrint(){} - void recdFree(){} + } alsa_t; + alsa_t* _handleToPtr( handle_t h) { return handleToPtr(h); } rc_t _alsaErrorImpl( int alsaRC, const char* func, const char* fn, int lineNumb, const char* fmt, ... ) { @@ -150,7 +121,7 @@ namespace cw char msg0[n+1]; int m = vsnprintf(msg0,n+1,fmt,vl1); - cwAssert(n==m) + cwAssert(n==m); va_end(vl1); const char* fmt1 = "%s ALSA Error:%s"; @@ -168,7 +139,7 @@ namespace cw #define _alsaError( alsaRC, fmt, ...) _alsaErrorImpl( alsaRC, __FUNCTION__, __FILE__, __LINE__, fmt, ##__VA_ARGS__ ) - rc_t _alsaSetupErrorImpl( int alsaRC, bool inputFl, const cmApDevRecd_t* drp, const char* func, const char* fn, int lineNumb, const char* fmt, ... ) + rc_t _alsaSetupErrorImpl( int alsaRC, bool inputFl, const devRecd_t* drp, const char* func, const char* fn, int lineNumb, const char* fmt, ... ) { va_list vl0,vl1; va_start(vl0,fmt); @@ -181,8 +152,8 @@ namespace cw } #define _alsaSetupError( alsaRC, inputFl, drp, fmt, ...) _alsaSetupErrorImpl( alsaRC, inputFl, drp, __FUNCTION__, __FILE__, __LINE__, fmt, ##__VA_ARGS__ ) - - const char* _cmApPcmStateToString( snd_pcm_state_t state ) + + const char* _pcmStateToString( snd_pcm_state_t state ) { switch( state ) { @@ -201,20 +172,8 @@ namespace cw return ""; } - void _cmApDevRtReport( cmApDevRecd_t* drp ) - { - cwLogInfo("cb i:%i o:%i err i:%i o:%i",drp->iCbCnt,drp->oCbCnt,drp->iErrCnt,drp->oErrCnt); - - if( drp->iPcmH != NULL ) - cwLogInfo(" state i:%s",_cmApPcmStateToString(snd_pcm_state(drp->iPcmH))); - - if( drp->oPcmH != NULL ) - cwLogInfo(" o:%s",_cmApPcmStateToString(snd_pcm_state(drp->oPcmH))); - - - } - - void _cmApDevReportFormats( snd_pcm_hw_params_t* hwParams ) + // Print a report of the audio signal formats this described in this 'snd_pcm_hw_params_t' record. + void _devReportFormats( snd_pcm_hw_params_t* hwParams ) { snd_pcm_format_mask_t* mask; @@ -284,16 +243,14 @@ namespace cw } - void _cmApDevReport( cmApDevRecd_t* drp ) + void _devReport( devRecd_t* drp ) { bool inputFl = true; snd_pcm_t* pcmH; int err; unsigned i; - //cmApRoot_t* p = drp->rootPtr; - - cwLogInfo("%s %s Device:%s Desc:%s\n", drp->flags & kInFl ? "IN ":"", drp->flags & kOutFl ? "OUT ":"", drp->nameStr, drp->descStr); + cwLogInfo("%s %s Device:%s Desc:%s", drp->flags & kInFl ? "IN ":"", drp->flags & kOutFl ? "OUT ":"", drp->nameStr, drp->descStr); for(i=0; i<2; i++,inputFl=!inputFl) { @@ -358,7 +315,7 @@ namespace cw (snd_pcm_hw_params_is_half_duplex(hwParams) ? "yes" : "no"), (snd_pcm_hw_params_is_joint_duplex(hwParams) ? "yes" : "no")); - _cmApDevReportFormats( hwParams ); + _devReportFormats( hwParams ); } if((err = snd_pcm_close(pcmH)) < 0) @@ -368,31 +325,25 @@ namespace cw } } - - // Called by cmApInitialize() to append a cmApDevRecd to the _cmApRoot.devArray[]. - void _cmApDevAppend( cmApRoot_t* p, cmApDevRecd_t* drp ) + // Called by create() to append a devRecd to the alsa_t.devArray[]. + void _devAppend( alsa_t* p, devRecd_t* drp ) { + const int reallocN = 5; if( p->devCnt == p->devAllocCnt ) { - p->devArray = memResizeZ( p->devArray, p->devAllocCnt + INIT_DEV_CNT ); - p->devAllocCnt += INIT_DEV_CNT; + p->devArray = memResizeZ( p->devArray, p->devAllocCnt + reallocN ); + p->devAllocCnt += reallocN; } drp->devIdx = p->devCnt; // set the device index drp->rootPtr = p; // set the pointer back to the root -#ifdef IMPULSE_FN - drp->recdN = 44100*2*2; - drp->recdBuf = cmMemAllocZ(int,drp->recdN); - drp->recdIdx = 0; -#endif - - memcpy(p->devArray + p->devCnt, drp, sizeof(cmApDevRecd_t)); + memcpy(p->devArray + p->devCnt, drp, sizeof(devRecd_t)); ++p->devCnt; } - rc_t _cmApDevShutdown( cmApRoot_t* p, cmApDevRecd_t* drp, bool inputFl ) + rc_t _devShutdown( alsa_t* p, devRecd_t* drp, bool inputFl ) { int err; @@ -411,7 +362,7 @@ namespace cw return kOkRC; } - int _cmApDevOpen( snd_pcm_t** pcmHPtr, const char* devNameStr, bool inputFl ) + int _devOpen( snd_pcm_t** pcmHPtr, const char* devNameStr, bool inputFl ) { int cnt = 0; int err; @@ -429,14 +380,47 @@ namespace cw return err; } - void _cmApXrun_recover( snd_pcm_t* pcmH, int err, cmApDevRecd_t* drp, bool inputFl, int line ) + rc_t _destroy( alsa_t* p ) + { + unsigned i; + rc_t rc = kOkRC; + + if( p->asyncFl==false ) + if((rc = thread::destroy(p->thH)) != kOkRC ) + { + rc = cwLogError(rc,"Thread destroy failed."); + } + + for(i=0; idevCnt; ++i) + { + _devShutdown(p,p->devArray+i,true); + _devShutdown(p,p->devArray+i,false); + + memRelease(p->devArray[i].iBuf); + memRelease(p->devArray[i].oBuf); + memRelease(p->devArray[i].nameStr); + memRelease(p->devArray[i].descStr); + + } + + memRelease(p->pollfds); + memRelease(p->pollfdsDesc); + + memRelease(p->devArray); + p->devAllocCnt = 0; + p->devCnt = 0; + + memRelease(p); + + return rc; + } + + void _devXrun_recover( snd_pcm_t* pcmH, int err, devRecd_t* drp, bool inputFl, int line ) { char dirCh = inputFl ? 'I' : 'O'; inputFl ? drp->iErrCnt++ : drp->oErrCnt++; - recdRecover(drp,inputFl,err,line); - // -EPIPE signals and over/underrun (see pcm.c example xrun_recovery()) switch( err ) { @@ -455,28 +439,10 @@ namespace cw if((err = snd_pcm_start(pcmH)) < 0 ) _alsaSetupError(err,inputFl,drp,"restart failed."); } - else - { - /* - _cmApWriteBuf(pcmH, NULL, drp->oChCnt, drp->oFpC ); - _cmApWriteBuf(pcmH, NULL, drp->oChCnt, drp->oFpC ); - - if((err = snd_pcm_prepare(pcmH))<0) - _alsaSetupError(err,inputFl,drp,"Recovery failed.\n"); - else - if((err = snd_pcm_resume(pcmH))<0) - _alsaSetupError(err,inputFl,drp,"Resume failed.\n"); - */ - } printf("EPIPE %c %i %i %i\n",dirCh,drp->devIdx,drp->oCbCnt,line); - //if((err = snd_pcm_prepare(pcmH))<0) - // _devSetupError(err,inputFl,*drp,"Recovery failed.\n"); - //else - // if((err = snd_pcm_resume(pcmH))<0) - // _devSetupError(err,inputFl,*drp,"Resume failed.\n"); break; } @@ -503,7 +469,7 @@ namespace cw } - void _cmApStateRecover( snd_pcm_t* pcmH, cmApDevRecd_t* drp, bool inputFl ) + void _devStateRecover( snd_pcm_t* pcmH, devRecd_t* drp, bool inputFl ) { int err = 0; @@ -530,11 +496,11 @@ namespace cw } if( err < 0 ) - _cmApXrun_recover( pcmH, err, drp, inputFl, __LINE__ ); + _devXrun_recover( pcmH, err, drp, inputFl, __LINE__ ); } - void _cmApS24_3BE_to_Float( const char* x, device::sample_t* y, unsigned n ) + void _devS24_3BE_to_Float( const char* x, device::sample_t* y, unsigned n ) { unsigned i; for(i=0; ioBufCnt < 3 ) - for(; ii<32; ++ii) - tmp[ii] = 0x7fffffff; -#endif - } break; } @@ -632,7 +590,6 @@ namespace cw if( err < 0 ) { - recdAppErr(drp,false,kWriteErrRId,err); _alsaSetupError( err, false, drp, "ALSA write error" ); } else @@ -648,7 +605,7 @@ namespace cw // Returns frames read on success or < 0 on error. // Set smpPtr to NULL to read the incoming buffer and discard it - int _cmApReadBuf( cmApDevRecd_t* drp, snd_pcm_t* pcmH, device::sample_t* smpPtr, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits ) + int _devReadBuf( devRecd_t* drp, snd_pcm_t* pcmH, device::sample_t* smpPtr, unsigned chCnt, unsigned frmCnt, unsigned bits, unsigned sigBits ) { int err = 0; unsigned bytesPerSmp = (bits==24 ? 32 : bits)/8; @@ -663,7 +620,6 @@ namespace cw // if a read error occurred if( err < 0 ) { - recdAppErr(drp,true,kReadErrRId,err); _alsaSetupError( err, false, drp, "ALSA read error" ); } else @@ -701,7 +657,7 @@ namespace cw case 24: { // For use with MBox - //_cmApS24_3BE_to_Float(buf, dp, ep-dp ); + //_devS24_3BE_to_Float(buf, dp, ep-dp ); int* sp = (int*)buf; while(dp < ep) *dp++ = ((device::sample_t)*sp++) / 0x7fffff; @@ -722,13 +678,6 @@ namespace cw while(dp < ep) *dp++ = ((device::sample_t)*sp++) / mv; -#ifdef IMPULSE_FN - sp = (int*)buf; - int* esp = sp + smpCnt; - for(; sprecdIdx < drp->recdN; ++drp->recdIdx) - drp->recdBuf[drp->recdIdx] = *sp++; -#endif - } break; default: @@ -736,14 +685,15 @@ namespace cw } return err; - } - void _cmApStaticAsyncHandler( snd_async_handler_t* ahandler ) + + + void _staticAsyncHandler( snd_async_handler_t* ahandler ) { int err; snd_pcm_sframes_t avail; - cmApDevRecd_t* drp = (cmApDevRecd_t*)snd_async_handler_get_callback_private(ahandler); + devRecd_t* drp = (devRecd_t*)snd_async_handler_get_callback_private(ahandler); snd_pcm_t* pcmH = snd_async_handler_get_pcm(ahandler); bool inputFl = snd_pcm_stream(pcmH) == SND_PCM_STREAM_CAPTURE; device::sample_t* b = inputFl ? drp->iBuf : drp->oBuf; @@ -753,18 +703,16 @@ namespace cw inputFl ? drp->iCbCnt++ : drp->oCbCnt++; - pkt.devIdx = drp->devIdx; - pkt.begChIdx = 0; - pkt.chCnt = chCnt; - pkt.audioFramesCnt = frmCnt; - pkt.bitsPerSample = 32; - pkt.flags = kInterleavedApFl | kFloatApFl; - pkt.audioBytesPtr = b; - pkt.userCbPtr = drp->userCbPtr; + pkt.devIdx = drp->devIdx; + pkt.begChIdx = 0; + pkt.chCnt = chCnt; + pkt.audioFramesCnt = frmCnt; + pkt.bitsPerSample = 32; + pkt.flags = kInterleavedApFl | kFloatApFl; + pkt.audioBytesPtr = b; + pkt.cbArg = drp->cbArg; - recdCb(drp,inputFl,0); - - _cmApStateRecover( pcmH, drp, inputFl ); + _devStateRecover( pcmH, drp, inputFl ); while( (avail = snd_pcm_avail_update(pcmH)) >= (snd_pcm_sframes_t)frmCnt ) { @@ -773,11 +721,11 @@ namespace cw if( inputFl ) { // read samples from the device - if((err = _cmApReadBuf(drp,pcmH,drp->iBuf,chCnt,frmCnt,drp->iBits,drp->oBits)) > 0 ) + if((err = _devReadBuf(drp,pcmH,drp->iBuf,chCnt,frmCnt,drp->iBits,drp->oBits)) > 0 ) { pkt.audioFramesCnt = err; - drp->cbPtr(&pkt,1,NULL,0 ); // send the samples to the application + drp->cbFunc(&pkt,1,NULL,0 ); // send the samples to the application } } @@ -785,10 +733,10 @@ namespace cw else { // callback to fill the buffer - drp->cbPtr(NULL,0,&pkt,1); + drp->cbFunc(NULL,0,&pkt,1); // note that the application may return fewer samples than were requested - err = _cmApWriteBuf(drp, pcmH, pkt.audioFramesCnt < frmCnt ? NULL : drp->oBuf,chCnt,frmCnt,drp->oBits,drp->oSigBits); + err = _devWriteBuf(drp, pcmH, pkt.audioFramesCnt < frmCnt ? NULL : drp->oBuf,chCnt,frmCnt,drp->oBits,drp->oSigBits); } @@ -796,20 +744,16 @@ namespace cw if( err < 0 ) { inputFl ? drp->iErrCnt++ : drp->oErrCnt++; - _cmApXrun_recover( pcmH, err, drp, inputFl, __LINE__ ); - } - else - { - // _cmApStateRecover( pcmH, drp, inputFl ); + _devXrun_recover( pcmH, err, drp, inputFl, __LINE__ ); } } // while } - bool _cmApThreadFunc(void* param) + bool _threadFunc(void* param) { - cmApRoot_t* p = (cmApRoot_t*)param; + alsa_t* p = static_cast(param); int result; bool retFl = true; @@ -832,27 +776,27 @@ namespace cw // for each i/o stream for(i=0; ipollfdsCnt; ++i) { - cmApDevRecd_t* drp = p->pollfdsDesc[i].devPtr; - bool inputFl = p->pollfdsDesc[i].inputFl; - snd_pcm_t* pcmH = inputFl ? drp->iPcmH : drp->oPcmH; - unsigned chCnt = inputFl ? drp->iChCnt : drp->oChCnt; - unsigned frmCnt = inputFl ? drp->iFpC : drp->oFpC; + devRecd_t* drp = p->pollfdsDesc[i].devPtr; + bool inputFl = p->pollfdsDesc[i].inputFl; + snd_pcm_t* pcmH = inputFl ? drp->iPcmH : drp->oPcmH; + unsigned chCnt = inputFl ? drp->iChCnt : drp->oChCnt; + unsigned frmCnt = inputFl ? drp->iFpC : drp->oFpC; device::sample_t* b = inputFl ? drp->iBuf : drp->oBuf; - unsigned short revents = 0; - int err; + unsigned short revents = 0; + int err; device::audioPacket_t pkt; - snd_pcm_uframes_t avail_frames; + snd_pcm_uframes_t avail_frames; inputFl ? drp->iCbCnt++ : drp->oCbCnt++; - pkt.devIdx = drp->devIdx; - pkt.begChIdx = 0; - pkt.chCnt = chCnt; - pkt.audioFramesCnt = frmCnt; - pkt.bitsPerSample = 32; - pkt.flags = kInterleavedApFl | kFloatApFl; - pkt.audioBytesPtr = b; - pkt.userCbPtr = drp->userCbPtr; + pkt.devIdx = drp->devIdx; + pkt.begChIdx = 0; + pkt.chCnt = chCnt; + pkt.audioFramesCnt = frmCnt; + pkt.bitsPerSample = 32; + pkt.flags = kInterleavedApFl | kFloatApFl; + pkt.audioBytesPtr = b; + pkt.cbArg = drp->cbArg; inputFl ? drp->iCbCnt++ : drp->oCbCnt++; @@ -913,16 +857,16 @@ namespace cw if(revents & POLLERR) { _alsaSetupError( err, p->pollfdsDesc[i].inputFl, drp, "Poll error."); - _cmApStateRecover( pcmH, drp, inputFl ); + _devStateRecover( pcmH, drp, inputFl ); //goto errLabel; } if( inputFl && (revents & POLLIN) ) { - if((err = _cmApReadBuf(drp,pcmH,drp->iBuf,chCnt,frmCnt,drp->iBits,drp->oBits)) > 0 ) + if((err = _devReadBuf(drp,pcmH,drp->iBuf,chCnt,frmCnt,drp->iBits,drp->oBits)) > 0 ) { pkt.audioFramesCnt = err; - drp->cbPtr(&pkt,1,NULL,0 ); // send the samples to the application + drp->cbFunc(&pkt,1,NULL,0 ); // send the samples to the application } } @@ -930,41 +874,22 @@ namespace cw 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 - drp->cbPtr(NULL,0,&pkt,1); + drp->cbFunc(NULL,0,&pkt,1); // note that the application may return fewer samples than were requested - err = _cmApWriteBuf(drp, pcmH, pkt.audioFramesCnt < frmCnt ? NULL : drp->oBuf,chCnt,frmCnt,drp->oBits,drp->oSigBits); + err = _devWriteBuf(drp, pcmH, pkt.audioFramesCnt < frmCnt ? NULL : drp->oBuf,chCnt,frmCnt,drp->oBits,drp->oSigBits); - } - - + } } - } - + } } errLabel: return retFl; } - - rc_t _cmApDevSetup( cmApDevRecd_t *drp, unsigned srate, unsigned framesPerCycle, unsigned periodsPerBuf ) + rc_t _devSetup( devRecd_t *drp, unsigned srate, unsigned framesPerCycle, unsigned periodsPerBuf ) { int err; int dir; @@ -972,12 +897,12 @@ namespace cw rc_t rc = kOkRC; bool inputFl = true; snd_pcm_uframes_t periodFrameCnt = framesPerCycle; - snd_pcm_uframes_t bufferFrameCnt; + snd_pcm_uframes_t bufferFrameCnt = 0; unsigned bits = 0; int sig_bits = 0; bool signFl = true; bool swapFl = false; - cmApRoot_t* p = drp->rootPtr; + alsa_t* p = drp->rootPtr; snd_pcm_format_t fmt[] = { @@ -1004,7 +929,7 @@ namespace cw snd_pcm_t* pcmH = NULL; rc_t rc0; - if((rc0 = _cmApDevShutdown(p, drp, inputFl )) != kOkRC ) + if((rc0 = _devShutdown(p, drp, inputFl )) != kOkRC ) rc = rc0; // attempt to open the sub-device @@ -1085,8 +1010,6 @@ namespace cw if((err = snd_pcm_hw_params(pcmH,hwParams)) < 0 ) rc = _alsaSetupError(err,inputFl, drp, "Parameter application failed."); - - //_reportActualParams( hwParams, inputFl, dr, srate, periodFrameCnt, bufferFrameCnt ); } // prepare the sw param recd @@ -1120,7 +1043,7 @@ namespace cw // setup the callback if( p->asyncFl ) - if((err = snd_async_add_pcm_handler(&drp->ahandler,pcmH,_cmApStaticAsyncHandler, drp )) < 0 ) + if((err = snd_async_add_pcm_handler(&drp->ahandler,pcmH,_staticAsyncHandler, drp )) < 0 ) rc = _alsaSetupError(err,inputFl,drp,"Error assigning callback handler."); // get the actual frames per cycle @@ -1174,8 +1097,8 @@ namespace cw // if the pollfds[] needs more memroy if( p->pollfdsCnt + fdsCnt > p->pollfdsAllocCnt ) { - p->pollfds = memResizeZ( p->pollfds, p->pollfdsCnt + fdsCnt ); - p->pollfdsDesc = memResizeZ( p->pollfdsDesc, p->pollfdsCnt + fdsCnt ); + p->pollfds = memResizeZ( p->pollfds, p->pollfdsCnt + fdsCnt ); + p->pollfdsDesc = memResizeZ( p->pollfdsDesc, p->pollfdsCnt + fdsCnt ); p->pollfdsAllocCnt += fdsCnt; } } @@ -1195,121 +1118,62 @@ namespace cw } printf("%s %s period:%i %i buffer:%i bits:%i sig_bits:%i\n",inputFl?"in ":"out",drp->nameStr,(unsigned)periodFrameCnt,(unsigned)actFpC,(unsigned)bufferFrameCnt,bits,sig_bits); - } - //_dumpAlsaDevice(pcmH); + } // end if async - } // end if + } // end if } // end for return rc; - } + } + } // alsa + } // device + } // audio +} // cw -#ifdef NOTDEF -#define TRY(e) while(e<0){ printf("LINE:%i ALSA ERROR:%s\n",__LINE__,snd_strerror(e)); exit(EXIT_FAILURE); } - - void open_device( const char* device_name, bool inputFl ) - { - snd_pcm_t *pcm_handle = NULL; - snd_pcm_hw_params_t *hw_params; - - - snd_pcm_uframes_t bs_min,bs_max,ps_min,ps_max; - unsigned rt_min,rt_max,ch_min,ch_max; - const char* ioLabel = inputFl ? "in" : "out"; - - - // Open the device - TRY( snd_pcm_open (&pcm_handle, device_name, inputFl ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, 0)); - - TRY( snd_pcm_hw_params_malloc (&hw_params) ); - TRY( snd_pcm_hw_params_any (pcm_handle, hw_params)); - - TRY( snd_pcm_hw_params_test_format(pcm_handle, hw_params, SND_PCM_FORMAT_S16_LE)); - - // get the sample rate range - TRY(snd_pcm_hw_params_get_rate_min(hw_params,&rt_min,NULL)); - TRY(snd_pcm_hw_params_get_rate_max(hw_params,&rt_max,NULL)); - TRY(snd_pcm_hw_params_get_channels_min(hw_params,&ch_min)); - TRY(snd_pcm_hw_params_get_channels_max(hw_params,&ch_max)); - - // set the basic device format - setting the format may influence the size of the possible - // buffer and period size - //TRY( snd_pcm_hw_params_set_access (pcm_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)); - //TRY( snd_pcm_hw_params_set_format (pcm_handle, hw_params, SND_PCM_FORMAT_S16_LE)); - //TRY( snd_pcm_hw_params_set_rate_near(pcm_handle, hw_params, &srate, NULL)); - //TRY( snd_pcm_hw_params_set_channels(pcm_handle, hw_params, ch_cnt)); - - - // get the range of possible buffer and period sizes - TRY(snd_pcm_hw_params_get_buffer_size_min(hw_params,&bs_min)); - TRY(snd_pcm_hw_params_get_buffer_size_max(hw_params,&bs_max)); - TRY(snd_pcm_hw_params_get_period_size_min(hw_params,&ps_min,NULL)); - TRY(snd_pcm_hw_params_get_period_size_max(hw_params,&ps_max,NULL)); - - //printf("%s %s bs min:%u max:%u ps min:%u max:%u rate min:%u max:%u ch min:%u max:%u\n",device_name,ioLabel,bs_min,bs_max,ps_min,ps_max,rt_min,rt_max,ch_min,ch_max); - printf("%s %s rate min:%u max:%u ch min:%u max:%u\n",device_name,ioLabel,rt_min,rt_max,ch_min,ch_max); - - snd_pcm_hw_params_free(hw_params); - snd_pcm_close(pcm_handle); - } -#endif - - } - } - } -} - -cw::rc_t cw::audio::device::alsa::initialize(unsigned baseApDevIdx) +cw::rc_t cw::audio::device::alsa::create( handle_t& hRef, struct driver_str*& drvRef ) { rc_t rc = kOkRC; - int err; int cardNum = -1; + int err; - if((rc = finalize()) != kOkRC ) + if((rc = destroy(hRef)) != kOkRC ) return rc; - recdSetup(); - - cmApRoot_t* p = &_cmApRoot; - //memset(p,0,sizeof(cmApRoot_t)); - p->asyncFl = false; + alsa_t* p = memAllocZ(); // for each sound card while(1) { - snd_ctl_t* cardH; + snd_ctl_t* cardH = NULL; char* cardNamePtr = NULL; char* cardLongNamePtr = NULL; int devNum = -1; int devStrN = 31; char devStr[devStrN+1]; - // get the next card handle if((err = snd_card_next(&cardNum)) < 0 ) - { return _alsaError(err,"Error getting sound card handle"); - } // if no more card's to get if( cardNum < 0 ) break; - // get the card short name + // get the card short name (and free() when done) if(((err = snd_card_get_name(cardNum,&cardNamePtr)) < 0) || (cardNamePtr == NULL)) { _alsaError(err,"Unable to get card name for card number %i",cardNum); goto releaseCard; } - // get the card long name + // get the card long name (and free() when done) if((err = snd_card_get_longname(cardNum,&cardLongNamePtr)) < 0 || cardLongNamePtr == NULL ) { _alsaError(err,"Unable to get long card name for card number %i",cardNum); goto releaseCard; } - + // form the device name for this card if(snprintf(devStr,devStrN,"hw:%i",cardNum) > devStrN ) { @@ -1324,7 +1188,6 @@ cw::rc_t cw::audio::device::alsa::initialize(unsigned baseApDevIdx) goto releaseCard; } - // for each device on this card while(1) { @@ -1352,8 +1215,8 @@ cw::rc_t cw::audio::device::alsa::initialize(unsigned baseApDevIdx) for(i=0; iasyncFl==false ) { p->pollfdsCnt = 0; p->pollfdsAllocCnt = 2*p->devCnt; p->pollfds = memAllocZ( p->pollfdsAllocCnt ); - p->pollfdsDesc = memAllocZ(p->pollfdsAllocCnt ); + p->pollfdsDesc = memAllocZ(p->pollfdsAllocCnt ); - if((rc = thread::create(p->thH,_cmApThreadFunc,p)) != kOkRC ) + if((rc = thread::create(p->thH,_threadFunc,p)) != kOkRC ) { rc = cwLogError(rc,"Thread create failed."); } } - return rc; - -} - -cw::rc_t cw::audio::device::alsa::finalize() -{ - cmApRoot_t* p = &_cmApRoot; - unsigned i; - rc_t rc = kOkRC; - - if( p->asyncFl==false ) - if((rc = thread::destroy(p->thH)) != kOkRC ) - { - rc = cwLogError(rc,"Thread destroy failed."); - } - - for(i=0; idevCnt; ++i) + if( rc != kOkRC ) + _destroy(p); + else { - _cmApDevShutdown(p,p->devArray+i,true); - _cmApDevShutdown(p,p->devArray+i,false); - -#ifdef IMPULSE_FN - if( p->devArray[i].recdIdx > 0 ) - { - const char* fn = "/home/kevin/temp/recd0.txt"; - FILE* fp = fopen(fn,"wt"); - if( fp != NULL ) - { - unsigned j; - for(j=0; jdevArray[i].recdIdx; ++j) - fprintf(fp,"%i\n",p->devArray[i].recdBuf[j]); - fclose(fp); - } - } - memRelease(p->devArray[i].recdBuf); -#endif - - memRelease(p->devArray[i].iBuf); - memRelease(p->devArray[i].oBuf); - + p->driver.drvArg = p; + p->driver.deviceCount = deviceCount; + p->driver.deviceLabel = deviceLabel; + p->driver.deviceChannelCount = deviceChannelCount; + p->driver.deviceSampleRate = deviceSampleRate; + p->driver.deviceFramesPerCycle = deviceFramesPerCycle; + p->driver.deviceSetup = deviceSetup; + p->driver.deviceStart = deviceStart; + p->driver.deviceStop = deviceStop; + p->driver.deviceIsStarted = deviceIsStarted; + p->driver.deviceRealTimeReport = deviceRealTimeReport; + + hRef.set(p); + drvRef = &p->driver; } - memRelease(p->pollfds); - memRelease(p->pollfdsDesc); - - memRelease(p->devArray); - p->devAllocCnt = 0; - p->devCnt = 0; - - recdFree(); - //write_rec(2); - - - return rc; -} - -unsigned cw::audio::device::alsa::deviceCount() -{ - return _cmApRoot.devCnt; -} - -const char* cw::audio::device::alsa::deviceLabel( unsigned devIdx ) -{ - cwAssert(devIdx < deviceCount()); - return _cmApRoot.devArray[devIdx].descStr; - -} - -unsigned cw::audio::device::alsa::deviceChannelCount( unsigned devIdx, bool inputFl ) -{ - cwAssert(devIdx < deviceCount()); - return inputFl ? _cmApRoot.devArray[devIdx].iChCnt : _cmApRoot.devArray[devIdx].oChCnt; + return rc; + } -double cw::audio::device::alsa::deviceSampleRate( unsigned devIdx ) +cw::rc_t cw::audio::device::alsa::destroy( handle_t& hRef ) { - cwAssert(devIdx < deviceCount()); - return (double)_cmApRoot.devArray[devIdx].srate; -} - -unsigned cw::audio::device::alsa::deviceFramesPerCycle( unsigned devIdx, bool inputFl ) -{ - cwAssert(devIdx < deviceCount()); - return _cmApRoot.devArray[devIdx].framesPerCycle; -} - -cw::rc_t cw::audio::device::alsa::deviceSetup( unsigned devIdx, double srate, unsigned framesPerCycle, device::cbFunc_t cbFunc, void* cbArg ) -{ - - cwAssert( devIdx < deviceCount()); rc_t rc = kOkRC; - cmApRoot_t* p = &_cmApRoot; - cmApDevRecd_t* drp = _cmApRoot.devArray + devIdx; - unsigned periodsPerBuf = kDfltPeriodsPerBuf; + if( !hRef.isValid() ) + return rc; + + alsa_t* p = _handleToPtr(hRef); + + if((rc = _destroy(p)) != kOkRC ) + return rc; + + hRef.clear(); + return rc; +} + +unsigned cw::audio::device::alsa::deviceCount( struct driver_str* drv) +{ + alsa_t* p = static_cast(drv->drvArg); + return p->devCnt; +} + +const char* cw::audio::device::alsa::deviceLabel( struct driver_str* drv, unsigned devIdx ) +{ + alsa_t* p = static_cast(drv->drvArg); + cwAssert( devIdx < deviceCount(drv)); + return p->devArray[devIdx].descStr; +} + +unsigned cw::audio::device::alsa::deviceChannelCount(struct driver_str* drv, unsigned devIdx, bool inputFl ) +{ + alsa_t* p = static_cast(drv->drvArg); + cwAssert( devIdx < deviceCount(drv)); + return inputFl ? p->devArray[devIdx].iChCnt : p->devArray[devIdx].oChCnt; +} + +double cw::audio::device::alsa::deviceSampleRate( struct driver_str* drv, unsigned devIdx ) +{ + alsa_t* p = static_cast(drv->drvArg); + cwAssert( devIdx < deviceCount(drv)); + return (double)p->devArray[devIdx].srate; +} + +unsigned cw::audio::device::alsa::deviceFramesPerCycle( struct driver_str* drv, unsigned devIdx, bool inputFl ) +{ + alsa_t* p = static_cast(drv->drvArg); + cwAssert( devIdx < deviceCount(drv)); + return p->devArray[devIdx].framesPerCycle; +} + +cw::rc_t cw::audio::device::alsa::deviceSetup( struct driver_str* drv, unsigned devIdx, double srate, unsigned framesPerCycle, cbFunc_t cbFunc, void* cbArg ) +{ + alsa_t* p = static_cast(drv->drvArg); + cwAssert( devIdx < deviceCount(drv)); + + rc_t rc = kOkRC; + devRecd_t* drp = p->devArray + devIdx; + unsigned periodsPerBuf = kDfltPeriodsPerBuf; if( p->asyncFl == false ) if((rc = thread::pause(p->thH,thread::kWaitFl | thread::kPauseFl)) != kOkRC ) - { return cwLogError(rc,"Audio thread pause failed."); - } - if((rc = _cmApDevSetup(drp, srate, framesPerCycle, periodsPerBuf )) == kOkRC ) + if((rc = _devSetup(drp, srate, framesPerCycle, periodsPerBuf )) == kOkRC ) { drp->srate = srate; drp->framesPerCycle = framesPerCycle; drp->periodsPerBuf = periodsPerBuf; - drp->cbPtr = cbFunc; - drp->userCbPtr = cbArg; + drp->cbFunc = cbFunc; + drp->cbArg = cbArg; } return rc; + } -cw::rc_t cw::audio::device::alsa::deviceStart( unsigned devIdx ) +cw::rc_t cw::audio::device::alsa::deviceStart( struct driver_str* drv, unsigned devIdx ) { - cwAssert( devIdx < deviceCount()); - int err; - cmApRoot_t* p = &_cmApRoot; - cmApDevRecd_t* drp = p->devArray + devIdx; - rc_t rc = kOkRC; - bool inputFl = true; - unsigned i; + cwAssert( devIdx < deviceCount(drv)); + alsa_t* p = static_cast(drv->drvArg); + int err; + devRecd_t* drp = p->devArray + devIdx; + rc_t rc = kOkRC; + bool inputFl = true; + unsigned i; for(i=0; i<2; ++i,inputFl=!inputFl) { @@ -1606,13 +1452,11 @@ cw::rc_t cw::audio::device::alsa::deviceStart( unsigned devIdx ) else { - recdStart(drp,inputFl); - if( inputFl == false ) { int j; for(j=0; j<1; ++j) - if((err = _cmApWriteBuf( drp, pcmH, NULL, chCnt, frmCnt, drp->oBits, drp->oSigBits )) < 0 ) + if((err = _devWriteBuf( drp, pcmH, NULL, chCnt, frmCnt, drp->oBits, drp->oSigBits )) < 0 ) { rc = _alsaSetupError(err,inputFl,drp,"Write before start failed."); break; @@ -1649,20 +1493,22 @@ cw::rc_t cw::audio::device::alsa::deviceStart( unsigned devIdx ) } -cw::rc_t cw::audio::device::alsa::deviceStop( unsigned devIdx ) +cw::rc_t cw::audio::device::alsa::deviceStop( struct driver_str* drv, unsigned devIdx ) { - int err; - rc_t rc = kOkRC; - cmApRoot_t* p = &_cmApRoot; - cmApDevRecd_t* drp = p->devArray + devIdx; - + cwAssert( devIdx < deviceCount(drv)); + alsa_t* p = static_cast(drv->drvArg); + devRecd_t* drp = p->devArray + devIdx; + rc_t rc = kOkRC; + int err; + + if( drp->iPcmH != NULL ) - if((err = snd_pcm_drop(drp->iPcmH)) < 0 ) - rc = _alsaSetupError(err,true,drp,"Input stop failed."); + if((err = snd_pcm_drop(drp->iPcmH)) < 0 ) + rc = _alsaSetupError(err,true,drp,"Input stop failed."); if( drp->oPcmH != NULL ) - if((err = snd_pcm_drop(drp->oPcmH)) < 0 ) - rc = _alsaSetupError(err,false,drp,"Output stop failed."); + if((err = snd_pcm_drop(drp->oPcmH)) < 0 ) + rc = _alsaSetupError(err,false,drp,"Output stop failed."); if( p->asyncFl == false ) { @@ -1671,16 +1517,16 @@ cw::rc_t cw::audio::device::alsa::deviceStop( unsigned devIdx ) rc =_alsaError(rc0,"Audio thread pause failed."); } - return rc; + return rc; } -bool cw::audio::device::alsa::deviceIsStarted( unsigned devIdx ) +bool cw::audio::device::alsa::deviceIsStarted(struct driver_str* drv, unsigned devIdx ) { - cwAssert( devIdx < deviceCount()); - - bool iFl = false; - bool oFl = false; - const cmApDevRecd_t* drp = _cmApRoot.devArray + devIdx; + cwAssert( devIdx < deviceCount(drv)); + alsa_t* p = static_cast(drv->drvArg); + bool iFl = false; + bool oFl = false; + const devRecd_t* drp = p->devArray + devIdx; if( drp->iPcmH != NULL ) iFl = snd_pcm_state(drp->iPcmH) == SND_PCM_STATE_RUNNING; @@ -1689,8 +1535,21 @@ bool cw::audio::device::alsa::deviceIsStarted( unsigned devIdx ) oFl = snd_pcm_state(drp->oPcmH) == SND_PCM_STATE_RUNNING; return iFl || oFl; + } +void cw::audio::device::alsa::deviceRealTimeReport(struct driver_str* drv, unsigned devIdx ) +{ + alsa_t* p = static_cast(drv->drvArg); + devRecd_t* drp = p->devArray + devIdx; + const char* iState = drp->iPcmH == NULL ? "" : _pcmStateToString(snd_pcm_state(drp->iPcmH)); + const char* oState = drp->oPcmH == NULL ? "" : _pcmStateToString(snd_pcm_state(drp->oPcmH)); + + cwLogInfo("ALSA cb i:%i o:%i err i:%i o:%i state: i:%s o:%s",drp->iCbCnt,drp->oCbCnt,drp->iErrCnt,drp->oErrCnt,iState,oState); +} + + + //{ { label:alsaDevRpt } //( // Here's an example of generating a report of available @@ -1698,18 +1557,32 @@ bool cw::audio::device::alsa::deviceIsStarted( unsigned devIdx ) //) //[ -void cw::audio::device::alsa::deviceReport() +void cw::audio::device::alsa::report( handle_t h ) { + alsa_t* p = _handleToPtr(h); unsigned i; - for(i=0; i<_cmApRoot.devCnt; i++) - { - cwLogInfo("%i : ",i); - _cmApDevReport(_cmApRoot.devArray + i ); - } + for(i=0; idevCnt; i++) + { + cwLogInfo(" "); + cwLogInfo("%i : ",i); + _devReport(p->devArray + i ); + } + + snd_config_update_free_global(); } + +void cw::audio::device::alsa::report() +{ + handle_t h; + driver_t* d; + if( create(h,d) == kOkRC ) + { + report(h); + destroy(h); + } +} + //] //} - - diff --git a/cwAudioDeviceAlsa.h b/cwAudioDeviceAlsa.h new file mode 100644 index 0000000..63f96bd --- /dev/null +++ b/cwAudioDeviceAlsa.h @@ -0,0 +1,37 @@ +#ifndef cwAudioDeviceAlsa_H +#define cwAudioDeviceAlsa_H + + +namespace cw +{ + namespace audio + { + namespace device + { + namespace alsa + { + typedef handle handle_t; + + rc_t create( handle_t& hRef, struct driver_str*& drvRef ); + rc_t destroy( handle_t& hRef ); + + unsigned deviceCount( struct driver_str* drv); + const char* deviceLabel( struct driver_str* drv, unsigned devIdx ); + unsigned deviceChannelCount( struct driver_str* drv, unsigned devIdx, bool inputFl ); + double deviceSampleRate( struct driver_str* drv, unsigned devIdx ); + unsigned deviceFramesPerCycle( struct driver_str* drv, unsigned devIdx, bool inputFl ); + rc_t deviceSetup( struct driver_str* drv, unsigned devIdx, double sr, unsigned frmPerCycle, cbFunc_t cbFunc, void* cbArg ); + rc_t deviceStart( struct driver_str* drv, unsigned devIdx ); + rc_t deviceStop( struct driver_str* drv, unsigned devIdx ); + bool deviceIsStarted( struct driver_str* drv, unsigned devIdx ); + void deviceRealTimeReport( struct driver_str* drv, unsigned devIdx ); + + void report(handle_t h ); + void report(); + } + } + } + +} + +#endif diff --git a/cwAudioPort.cpp b/cwAudioDeviceTest.cpp similarity index 53% rename from cwAudioPort.cpp rename to cwAudioDeviceTest.cpp index 9072db3..f685d7e 100644 --- a/cwAudioPort.cpp +++ b/cwAudioDeviceTest.cpp @@ -2,375 +2,12 @@ #include "cwLog.h" #include "cwCommonImpl.h" #include "cwMem.h" -#include "cwTextBuf.h" #include "cwTime.h" -#include "cwAudioPort.h" +#include "cwTextBuf.h" +#include "cwAudioDevice.h" #include "cwAudioBuf.h" - - -#ifdef cwLINUX -#include "cwAudioPortAlsa.h" -#endif - -#ifdef cwOSX -#include "cmAudioPortOsx.h" -#endif - -namespace cw -{ - namespace audio - { - namespace device - { - - typedef struct - { - unsigned begDevIdx; - unsigned endDevIdx; - - rc_t (*initialize)( unsigned baseApDevIdx ); - rc_t (*finalize)(); - rc_t (*deviceCount)(); - const char* (*deviceLabel)( unsigned devIdx ); - unsigned (*deviceChannelCount)( unsigned devIdx, bool inputFl ); - double (*deviceSampleRate)( unsigned devIdx ); - unsigned (*deviceFramesPerCycle)( unsigned devIdx, bool inputFl ); - rc_t (*deviceSetup)( unsigned devIdx, double sr, unsigned frmPerCycle, cbFunc_t cb, void* cbData ); - rc_t (*deviceStart)( unsigned devIdx ); - rc_t (*deviceStop)( unsigned devIdx ); - bool (*deviceIsStarted)( unsigned devIdx ); - - } cmApDriver_t; - - typedef struct - { - cmApDriver_t* drvArray; - unsigned drvCnt; - unsigned devCnt; - } cmAp_t; - - cmAp_t* _ap = NULL; - - rc_t _cmApIndexToDev( unsigned devIdx, cmApDriver_t** drvPtrPtr, unsigned* devIdxPtr ) - { - assert( drvPtrPtr != NULL && devIdxPtr != NULL ); - *drvPtrPtr = NULL; - *devIdxPtr = kInvalidIdx; - - unsigned i; - for(i=0; i<_ap->drvCnt; ++i) - if( _ap->drvArray[i].begDevIdx != kInvalidIdx ) - if( (_ap->drvArray[i].begDevIdx <= devIdx) && (devIdx <= _ap->drvArray[i].endDevIdx) ) - { - *drvPtrPtr = _ap->drvArray + i; - *devIdxPtr = devIdx - _ap->drvArray[i].begDevIdx; - return kOkRC; - } - - return cwLogError(kInvalidIdRC,"The audio port device index %i is not valid.",devIdx); - } - } - } -} - -cw::rc_t cw::audio::device::initialize() -{ - rc_t rc = kOkRC; - if((rc = finalize()) != kOkRC ) - return rc; - - _ap = memAllocZ(1); - - _ap->drvCnt = 1; - _ap->drvArray = memAllocZ(_ap->drvCnt); - cmApDriver_t* dp = _ap->drvArray; - -#ifdef cwOSX - dp->initialize = cmApOsxInitialize; - dp->finalize = cmApOsxFinalize; - dp->deviceCount = cmApOsxDeviceCount; - dp->deviceLabel = cmApOsxDeviceLabel; - dp->deviceChannelCount = cmApOsxDeviceChannelCount; - dp->deviceSampleRate = cmApOsxDeviceSampleRate; - dp->deviceFramesPerCycle = cmApOsxDeviceFramesPerCycle; - dp->deviceSetup = cmApOsxDeviceSetup; - dp->deviceStart = cmApOsxDeviceStart; - dp->deviceStop = cmApOsxDeviceStop; - dp->deviceIsStarted = cmApOsxDeviceIsStarted; -#endif - -#ifdef cwLINUX - dp->initialize = alsa::initialize; - dp->finalize = alsa::finalize; - dp->deviceCount = alsa::deviceCount; - dp->deviceLabel = alsa::deviceLabel; - dp->deviceChannelCount = alsa::deviceChannelCount; - dp->deviceSampleRate = alsa::deviceSampleRate; - dp->deviceFramesPerCycle = alsa::deviceFramesPerCycle; - dp->deviceSetup = alsa::deviceSetup; - dp->deviceStart = alsa::deviceStart; - dp->deviceStop = alsa::deviceStop; - dp->deviceIsStarted = alsa::deviceIsStarted; -#endif - - /* - dp = _ap->drvArray + 1; - - dp->initialize = cmApFileInitialize; - dp->finalize = cmApFileFinalize; - dp->deviceCount = cmApFileDeviceCount; - dp->deviceLabel = cmApFileDeviceLabel; - dp->deviceChannelCount = cmApFileDeviceChannelCount; - dp->deviceSampleRate = cmApFileDeviceSampleRate; - dp->deviceFramesPerCycle = cmApFileDeviceFramesPerCycle; - dp->deviceSetup = cmApFileDeviceSetup; - dp->deviceStart = cmApFileDeviceStart; - dp->deviceStop = cmApFileDeviceStop; - dp->deviceIsStarted = cmApFileDeviceIsStarted; - - dp = _ap->drvArray + 2; - - dp->initialize = cmApAggInitialize; - dp->finalize = cmApAggFinalize; - dp->deviceCount = cmApAggDeviceCount; - dp->deviceLabel = cmApAggDeviceLabel; - dp->deviceChannelCount = cmApAggDeviceChannelCount; - dp->deviceSampleRate = cmApAggDeviceSampleRate; - dp->deviceFramesPerCycle = cmApAggDeviceFramesPerCycle; - dp->deviceSetup = cmApAggDeviceSetup; - dp->deviceStart = cmApAggDeviceStart; - dp->deviceStop = cmApAggDeviceStop; - dp->deviceIsStarted = cmApAggDeviceIsStarted; - - dp = _ap->drvArray + 3; - - dp->initialize = cmApNrtInitialize; - dp->finalize = cmApNrtFinalize; - dp->deviceCount = cmApNrtDeviceCount; - dp->deviceLabel = cmApNrtDeviceLabel; - dp->deviceChannelCount = cmApNrtDeviceChannelCount; - dp->deviceSampleRate = cmApNrtDeviceSampleRate; - dp->deviceFramesPerCycle = cmApNrtDeviceFramesPerCycle; - dp->deviceSetup = cmApNrtDeviceSetup; - dp->deviceStart = cmApNrtDeviceStart; - dp->deviceStop = cmApNrtDeviceStop; - dp->deviceIsStarted = cmApNrtDeviceIsStarted; - */ - - _ap->devCnt = 0; - - unsigned i; - for(i=0; i<_ap->drvCnt; ++i) - { - unsigned dn; - rc_t rc0; - - _ap->drvArray[i].begDevIdx = kInvalidIdx; - _ap->drvArray[i].endDevIdx = kInvalidIdx; - - if((rc0 = _ap->drvArray[i].initialize(_ap->devCnt)) != kOkRC ) - { - rc = rc0; - continue; - } - - if((dn = _ap->drvArray[i].deviceCount()) > 0) - { - _ap->drvArray[i].begDevIdx = _ap->devCnt; - _ap->drvArray[i].endDevIdx = _ap->devCnt + dn - 1; - _ap->devCnt += dn; - } - } - - if( rc != kOkRC ) - finalize(); - - return rc; -} - -cw::rc_t cw::audio::device::finalize() -{ - rc_t rc=kOkRC; - rc_t rc0 = kOkRC; - unsigned i; - - if( _ap == NULL ) - return kOkRC; - - for(i=0; i<_ap->drvCnt; ++i) - { - if((rc0 = _ap->drvArray[i].finalize()) != kOkRC ) - rc = rc0; - } - - memRelease(_ap->drvArray); - memRelease(_ap); - return rc; -} - - -unsigned cw::audio::device::deviceCount() -{ return _ap->devCnt; } - -const char* cw::audio::device::deviceLabel( unsigned devIdx ) -{ - cmApDriver_t* dp = NULL; - unsigned di = kInvalidIdx; - rc_t rc; - - if( devIdx == kInvalidIdx ) - return NULL; - - if((rc = _cmApIndexToDev(devIdx,&dp,&di)) != kOkRC ) - return cwStringNullGuard(NULL); - - return dp->deviceLabel(di); -} - -unsigned cw::audio::device::deviceLabelToIndex( const char* label ) -{ - unsigned n = deviceCount(); - unsigned i; - for(i=0; ideviceChannelCount(di,inputFl); -} - -double cw::audio::device::deviceSampleRate( unsigned devIdx ) -{ - cmApDriver_t* dp = NULL; - unsigned di = kInvalidIdx; - rc_t rc; - - if((rc = _cmApIndexToDev(devIdx,&dp,&di)) != kOkRC ) - return rc; - - return dp->deviceSampleRate(di); -} - -unsigned cw::audio::device::deviceFramesPerCycle( unsigned devIdx, bool inputFl ) -{ - cmApDriver_t* dp = NULL; - unsigned di = kInvalidIdx; - rc_t rc; - - if( devIdx == kInvalidIdx ) - return 0; - - if((rc = _cmApIndexToDev(devIdx,&dp,&di)) != kOkRC ) - return rc; - - return dp->deviceFramesPerCycle(di,inputFl); -} - -cw::rc_t cw::audio::device::deviceSetup( - unsigned devIdx, - double srate, - unsigned framesPerCycle, - cbFunc_t cbFunc, - void* cbArg ) -{ - cmApDriver_t* dp; - unsigned di; - rc_t rc; - - if( devIdx == kInvalidIdx ) - return kOkRC; - - if((rc = _cmApIndexToDev(devIdx,&dp,&di)) != kOkRC ) - return rc; - - return dp->deviceSetup(di,srate,framesPerCycle,cbFunc,cbArg); -} - -cw::rc_t cw::audio::device::deviceStart( unsigned devIdx ) -{ - cmApDriver_t* dp; - unsigned di; - rc_t rc; - - if( devIdx == kInvalidIdx ) - return kOkRC; - - if((rc = _cmApIndexToDev(devIdx,&dp,&di)) != kOkRC ) - return rc; - - return dp->deviceStart(di); -} - -cw::rc_t cw::audio::device::deviceStop( unsigned devIdx ) -{ - cmApDriver_t* dp; - unsigned di; - rc_t rc; - - if( devIdx == kInvalidIdx ) - return kOkRC; - - if((rc = _cmApIndexToDev(devIdx,&dp,&di)) != kOkRC ) - return rc; - - return dp->deviceStop(di); -} - -bool cw::audio::device::deviceIsStarted( unsigned devIdx ) -{ - cmApDriver_t* dp; - unsigned di; - rc_t rc; - - if( devIdx == kInvalidIdx ) - return false; - - if((rc = _cmApIndexToDev(devIdx,&dp,&di)) != kOkRC ) - return rc; - - return dp->deviceIsStarted(di); -} - - - -void cw::audio::device::report() -{ - unsigned i,j,k; - for(j=0,k=0; j<_ap->drvCnt; ++j) - { - cmApDriver_t* drvPtr = _ap->drvArray + j; - unsigned n = drvPtr->deviceCount(); - - for(i=0; ideviceSampleRate(i), - drvPtr->deviceChannelCount(i,true), drvPtr->deviceFramesPerCycle(i,true), - drvPtr->deviceChannelCount(i,false), drvPtr->deviceFramesPerCycle(i,false), - drvPtr->deviceLabel(i)); - - } - } - - //cmApAlsaDeviceReport(rpt); -} +#include "cwAudioDeviceAlsa.h" +#include "cwAudioDeviceTest.h" namespace cw { @@ -380,7 +17,7 @@ namespace cw { /// [cmAudioPortExample] - // See cmApPortTest() below for the main point of entry. + // See test() below for the main point of entry. // Data structure used to hold the parameters for cpApPortTest() // and the user defined data record passed to the host from the @@ -640,8 +277,10 @@ namespace cw cwLogInfo(msg); } - // Get a command line option. - int _cmApGetOpt( int argc, const char* argv[], const char* label, int defaultVal, bool boolFl ) + // Get a command line option. Note that if 'boolFl' is set to 'true' then the function simply + // returns '1'. This is used to handle arguments whose presense indicates a positive boolean + // flag. For example -h (help) indicates that the usage data should be printed - it needs no other argument. + int _cmApGetOpt( int argc, const char* argv[], const char* label, int defaultVal, bool boolFl=false ) { int i = 0; for(; i(inPktArray[i].cbArg)->cbCnt++; + + for(unsigned i=0; i(outPktArray[i].cbArg)->cbCnt++; + buf::inputToOutput( _cmGlobalInDevIdx, _cmGlobalOutDevIdx ); buf::update( inPktArray, inPktCnt, outPktArray, outPktCnt ); @@ -673,23 +318,26 @@ namespace cw } // Audio Port testing function -cw::rc_t cw::audio::device::test( bool runFl, int argc, const char** argv ) +cw::rc_t cw::audio::device::test( int argc, const char** argv ) { cmApPortTestRecd r; unsigned i; - int result = 0; - textBuf::handle_t tbH = textBuf::create(); + rc_t rc; + driver_t* drv = nullptr; + handle_t h; + alsa::handle_t alsaH; + bool runFl = true; if( _cmApGetOpt(argc,argv,"-h",0,true) ) _cmApPrintUsage(); - runFl = _cmApGetOpt(argc,argv,"-p",!runFl,true)?false:true; - r.srate = _cmApGetOpt(argc,argv,"-r",44100,false); - r.chIdx = _cmApGetOpt(argc,argv,"-a",0,false); - r.chCnt = _cmApGetOpt(argc,argv,"-c",2,false); - r.bufCnt = _cmApGetOpt(argc,argv,"-b",3,false); - r.framesPerCycle = _cmApGetOpt(argc,argv,"-f",512,false); + runFl = _cmApGetOpt(argc,argv,"-p",0,true)?false:true; + r.srate = _cmApGetOpt(argc,argv,"-r",44100); + r.chIdx = _cmApGetOpt(argc,argv,"-a",0); + r.chCnt = _cmApGetOpt(argc,argv,"-c",2); + r.bufCnt = _cmApGetOpt(argc,argv,"-b",3); + r.framesPerCycle = _cmApGetOpt(argc,argv,"-f",512); r.bufFrmCnt = (r.bufCnt*r.framesPerCycle); r.bufSmpCnt = (r.chCnt * r.bufFrmCnt); r.logCnt = 100; @@ -699,8 +347,8 @@ cw::rc_t cw::audio::device::test( bool runFl, int argc, const char** argv ) char log[r.logCnt]; unsigned ilog[r.logCnt]; - r.inDevIdx = _cmGlobalInDevIdx = _cmApGetOpt(argc,argv,"-i",0,false); - r.outDevIdx = _cmGlobalOutDevIdx = _cmApGetOpt(argc,argv,"-o",2,false); + r.inDevIdx = _cmGlobalInDevIdx = _cmApGetOpt(argc,argv,"-i",0); + r.outDevIdx = _cmGlobalOutDevIdx = _cmApGetOpt(argc,argv,"-o",2); r.phase = 0; r.frqHz = 2000; r.bufInIdx = 0; @@ -713,75 +361,75 @@ cw::rc_t cw::audio::device::test( bool runFl, int argc, const char** argv ) r.ilog = ilog; r.cbCnt = 0; - cwLogInfo("%s in:%i out:%i chidx:%i chs:%i bufs=%i frm=%i rate=%f",runFl?"exec":"rpt",r.inDevIdx,r.outDevIdx,r.chIdx,r.chCnt,r.bufCnt,r.framesPerCycle,r.srate); + cwLogInfo("Program cfg: %s in:%i out:%i chidx:%i chs:%i bufs=%i frm=%i rate=%f",runFl?"exec":"rpt",r.inDevIdx,r.outDevIdx,r.chIdx,r.chCnt,r.bufCnt,r.framesPerCycle,r.srate); - /* - if( cmApFileAllocate(rpt) != kOkRC ) - { - cwLogInfo("Audio port file allocation failed."); - result = -1; - goto errLabel; - } - - // allocate the non-real-time port - if( cmApNrtAllocate(rpt) != kOkRC ) - { - cwLogInfo("Non-real-time system allocation failed."); - result = 1; - goto errLabel; - } - */ - // initialize the audio device interface - if( initialize() != kOkRC ) + // initialize the audio device interface + if((rc = create(h)) != kOkRC ) { cwLogInfo("Initialize failed."); - result = 1; + goto errLabel; + } + + // initialize the ALSA device driver interface + if((rc = alsa::create(alsaH, drv )) != kOkRC ) + { + cwLogInfo("ALSA initialize failed."); + goto errLabel; + } + + // register the ALSA device driver with the audio interface + if((rc = registerDriver( h, drv )) != kOkRC ) + { + cwLogInfo("ALSA driver registration failed."); goto errLabel; } // report the current audio device configuration - for(i=0; i + rc_t rcSelect(T rc, ARGS... args) + { + if( rc != kOkRC ) + return rc; + + return rcSelect(args...); + } + + void sleepSec( unsigned secs ); // sleep seconds void sleepMs( unsigned ms ); // sleep milliseconds void sleepUs( unsigned us ); // sleep seconds diff --git a/cwFile.cpp b/cwFile.cpp index 7da5500..18738c2 100644 --- a/cwFile.cpp +++ b/cwFile.cpp @@ -14,132 +14,138 @@ namespace cw { - typedef struct file_str + namespace file { - FILE* fp; - char* fnStr; - } file_t; + typedef struct file_str + { + FILE* fp; + char* fnStr; + } this_t; -#define _fileHandleToPtr(h) handleToPtr(h) + this_t* _handleToPtr(handle_t h) + { + return handleToPtr(h); + } -char* _fileToBuf( fileH_t h, unsigned nn, unsigned* bufByteCntPtr ) -{ - errno = 0; + char* _fileToBuf( handle_t h, unsigned nn, unsigned* bufByteCntPtr ) + { + errno = 0; - unsigned n = fileByteCount(h); - char* buf = nullptr; + unsigned n = byteCount(h); + char* buf = nullptr; - // if the file size calculation is ok - if( errno != 0 ) - { - cwLogSysError(kOpFailRC,errno,"Invalid file buffer length on '%s'.", cwStringNullGuard(fileName(h))); - goto errLabel; - } + // if the file size calculation is ok + if( errno != 0 ) + { + cwLogSysError(kOpFailRC,errno,"Invalid file buffer length on '%s'.", cwStringNullGuard(name(h))); + goto errLabel; + } - // allocate the read target buffer - if((buf = memAlloc(n+nn)) == nullptr) - { - cwLogError(kMemAllocFailRC,"Read buffer allocation failed."); - goto errLabel; - } + // allocate the read target buffer + if((buf = memAlloc(n+nn)) == nullptr) + { + cwLogError(kMemAllocFailRC,"Read buffer allocation failed."); + goto errLabel; + } - // read the file - if( fileRead(h,buf,n) != kOkRC ) - goto errLabel; + // read the file + if( read(h,buf,n) != kOkRC ) + goto errLabel; - // zero memory after the file data - memset(buf+n,0,nn); + // zero memory after the file data + memset(buf+n,0,nn); - if( bufByteCntPtr != nullptr ) - *bufByteCntPtr = n; + if( bufByteCntPtr != nullptr ) + *bufByteCntPtr = n; - return buf; + return buf; - errLabel: - if( bufByteCntPtr != nullptr ) - *bufByteCntPtr = 0; + errLabel: + if( bufByteCntPtr != nullptr ) + *bufByteCntPtr = 0; - memRelease(buf); + memRelease(buf); - return nullptr; + return nullptr; -} + } -char* _fileFnToBuf( const char* fn, unsigned nn, unsigned* bufByteCntPtr ) -{ - fileH_t h; - char* buf = nullptr; + char* _fileFnToBuf( const char* fn, unsigned nn, unsigned* bufByteCntPtr ) + { + handle_t h; + char* buf = nullptr; - if( fileOpen(h,fn,kReadFileFl | kBinaryFileFl) != kOkRC ) - goto errLabel; + if( open(h,fn,kReadFl | kBinaryFl) != kOkRC ) + goto errLabel; - buf = _fileToBuf(h,nn,bufByteCntPtr); + buf = _fileToBuf(h,nn,bufByteCntPtr); - errLabel: - fileClose(h); + errLabel: + close(h); - return buf; -} + return buf; + } - rc_t _fileGetLine( file_t* p, char* buf, unsigned* bufByteCntPtr ) -{ - // fgets() reads up to n-1 bytes into buf[] - if( fgets(buf,*bufByteCntPtr,p->fp) == nullptr ) - { - // an read error or EOF condition occurred - *bufByteCntPtr = 0; + rc_t _fileGetLine( this_t* p, char* buf, unsigned* bufByteCntPtr ) + { + // fgets() reads up to n-1 bytes into buf[] + if( fgets(buf,*bufByteCntPtr,p->fp) == nullptr ) + { + // an read error or EOF condition occurred + *bufByteCntPtr = 0; - if( !feof(p->fp ) ) - return cwLogSysError(kReadFailRC,errno,"File read line failed"); + if( !feof(p->fp ) ) + return cwLogSysError(kReadFailRC,errno,"File read line failed"); - return kReadFailRC; + return kReadFailRC; + } + + return kOkRC; + } + } - return kOkRC; } -} - - -cw::rc_t cw::fileOpen( fileH_t& hRef, const char* fn, unsigned flags ) +cw::rc_t cw::file::open( handle_t& hRef, const char* fn, unsigned flags ) { char mode[] = "/0/0/0"; - file_t* p = nullptr; + this_t* p = nullptr; rc_t rc; - if((rc = fileClose(hRef)) != kOkRC ) + if((rc = close(hRef)) != kOkRC ) return rc; - if( cwIsFlag(flags,kReadFileFl) ) + if( cwIsFlag(flags,kReadFl) ) mode[0] = 'r'; else - if( cwIsFlag(flags,kWriteFileFl) ) + if( cwIsFlag(flags,kWriteFl) ) mode[0] = 'w'; else - if( cwIsFlag(flags,kAppendFileFl) ) + if( cwIsFlag(flags,kAppendFl) ) mode[0] = 'a'; else - cwLogError(kInvalidArgRC,"File open flags must contain 'kReadFileFl','kWriteFileFl', or 'kAppendFileFl'."); + cwLogError(kInvalidArgRC,"File open flags must contain 'kReadFl','kWriteFl', or 'kAppendFl'."); - if( cwIsFlag(flags,kUpdateFileFl) ) + if( cwIsFlag(flags,kUpdateFl) ) mode[1] = '+'; // handle requests to use stdin,stdout,stderr FILE* sfp = nullptr; - if( cwIsFlag(flags,kStdoutFileFl) ) + if( cwIsFlag(flags,kStdoutFl) ) { sfp = stdout; fn = "stdout"; } else - if( cwIsFlag(flags,kStderrFileFl) ) + if( cwIsFlag(flags,kStderrFl) ) { sfp = stderr; fn = "stderr"; } else - if( cwIsFlag(flags,kStdinFileFl) ) + if( cwIsFlag(flags,kStdinFl) ) { sfp = stdin; fn = "stdin"; @@ -149,9 +155,9 @@ cw::rc_t cw::fileOpen( fileH_t& hRef, const char* fn, unsigned flags ) if( fn == nullptr ) return cwLogError(kInvalidArgRC,"File object allocation failed due to empty file name."); - unsigned byteCnt = sizeof(file_t) + strlen(fn) + 1; + unsigned byteCnt = sizeof(this_t) + strlen(fn) + 1; - if((p = memAllocZ(byteCnt)) == nullptr ) + if((p = memAllocZ(byteCnt)) == nullptr ) return cwLogError(kOpFailRC,"File object allocation failed for file '%s'.",cwStringNullGuard(fn)); p->fnStr = (char*)(p+1); @@ -175,12 +181,12 @@ cw::rc_t cw::fileOpen( fileH_t& hRef, const char* fn, unsigned flags ) return kOkRC; } -cw::rc_t cw::fileClose( fileH_t& hRef ) +cw::rc_t cw::file::close( handle_t& hRef ) { - if( fileIsValid(hRef) == false ) + if( isValid(hRef) == false ) return kOkRC; - file_t* p = _fileHandleToPtr(hRef); + this_t* p = _handleToPtr(hRef); errno = 0; if( p->fp != nullptr ) @@ -188,17 +194,17 @@ cw::rc_t cw::fileClose( fileH_t& hRef ) return cwLogSysError(kCloseFailRC,errno,"File close failed on '%s'.", cwStringNullGuard(p->fnStr)); memRelease(p); - hRef.set(nullptr); + hRef.clear(); return kOkRC; } -bool cw::fileIsValid( fileH_t h ) +bool cw::file::isValid( handle_t h ) { return h.isValid(); } -cw::rc_t cw::fileRead( fileH_t h, void* buf, unsigned bufByteCnt ) +cw::rc_t cw::file::read( handle_t h, void* buf, unsigned bufByteCnt ) { - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); errno = 0; if( fread(buf,bufByteCnt,1,p->fp) != 1 ) @@ -207,9 +213,9 @@ cw::rc_t cw::fileRead( fileH_t h, void* buf, unsigned bufByteCnt ) return kOkRC; } -cw::rc_t cw::fileWrite( fileH_t h, const void* buf, unsigned bufByteCnt ) +cw::rc_t cw::file::write( handle_t h, const void* buf, unsigned bufByteCnt ) { - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); errno = 0; if( fwrite(buf,bufByteCnt,1,p->fp) != 1 ) @@ -218,18 +224,18 @@ cw::rc_t cw::fileWrite( fileH_t h, const void* buf, unsigned bufByteCnt ) return kOkRC; } -cw::rc_t cw::fileSeek( fileH_t h, enum fileSeekFlags_t flags, int offsByteCnt ) +cw::rc_t cw::file::seek( handle_t h, enum seekFlags_t flags, int offsByteCnt ) { - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); unsigned fileflags = 0; - if( cwIsFlag(flags,kBeginFileFl) ) + if( cwIsFlag(flags,kBeginFl) ) fileflags = SEEK_SET; else - if( cwIsFlag(flags,kCurFileFl) ) + if( cwIsFlag(flags,kCurFl) ) fileflags = SEEK_CUR; else - if( cwIsFlag(flags,kEndFileFl) ) + if( cwIsFlag(flags,kEndFl) ) fileflags = SEEK_END; else return cwLogError(kInvalidArgRC,"Invalid file seek flag on '%s'.",cwStringNullGuard(p->fnStr)); @@ -241,11 +247,11 @@ cw::rc_t cw::fileSeek( fileH_t h, enum fileSeekFlags_t flags, int offsByteCnt return kOkRC; } -cw::rc_t cw::fileTell( fileH_t h, long* offsPtr ) +cw::rc_t cw::file::tell( handle_t h, long* offsPtr ) { cwAssert( offsPtr != nullptr ); *offsPtr = -1; - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); errno = 0; if((*offsPtr = ftell(p->fp)) == -1) @@ -254,15 +260,15 @@ cw::rc_t cw::fileTell( fileH_t h, long* offsPtr ) } -bool cw::fileEof( fileH_t h ) -{ return feof( _fileHandleToPtr(h)->fp ) != 0; } +bool cw::file::eof( handle_t h ) +{ return feof( _handleToPtr(h)->fp ) != 0; } -unsigned cw::fileByteCount( fileH_t h ) +unsigned cw::file::byteCount( handle_t h ) { struct stat sr; int f; - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); const char errMsg[] = "File byte count request failed."; errno = 0; @@ -282,44 +288,44 @@ unsigned cw::fileByteCount( fileH_t h ) return sr.st_size; } -cw::rc_t cw::fileByteCountFn( const char* fn, unsigned* fileByteCntPtr ) +cw::rc_t cw::file::byteCountFn( const char* fn, unsigned* fileByteCntPtr ) { cwAssert( fileByteCntPtr != nullptr ); rc_t rc; - fileH_t h; + handle_t h; - if((rc = fileOpen(h,fn,kReadFileFl)) != kOkRC ) + if((rc = open(h,fn,kReadFl)) != kOkRC ) return rc; if( fileByteCntPtr != nullptr) - *fileByteCntPtr = fileByteCount(h); + *fileByteCntPtr = byteCount(h); - fileClose(h); + close(h); return rc; } -cw::rc_t cw::fileCompare( const char* fn0, const char* fn1, bool& isEqualRef ) +cw::rc_t cw::file::compare( const char* fn0, const char* fn1, bool& isEqualRef ) { rc_t rc = kOkRC; unsigned bufByteCnt = 2048; - fileH_t h0; - fileH_t h1; - file_t* p0 = nullptr; - file_t* p1 = nullptr; + handle_t h0; + handle_t h1; + this_t* p0 = nullptr; + this_t* p1 = nullptr; char b0[ bufByteCnt ]; char b1[ bufByteCnt ]; isEqualRef = true; - if((rc = fileOpen(h0,fn0,kReadFileFl)) != kOkRC ) + if((rc = open(h0,fn0,kReadFl)) != kOkRC ) goto errLabel; - if((rc = fileOpen(h1,fn1,kReadFileFl)) != kOkRC ) + if((rc = open(h1,fn1,kReadFl)) != kOkRC ) goto errLabel; - p0 = _fileHandleToPtr(h0); - p1 = _fileHandleToPtr(h1); + p0 = _handleToPtr(h0); + p1 = _handleToPtr(h1); while(1) { @@ -336,36 +342,36 @@ cw::rc_t cw::fileCompare( const char* fn0, const char* fn1, bool& isEqualRef ) } errLabel: - fileClose(h0); - fileClose(h1); + close(h0); + close(h1); return rc; } -const char* cw::fileName( fileH_t h ) +const char* cw::file::name( handle_t h ) { - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); return p->fnStr; } -cw::rc_t cw::fileFnWrite( const char* fn, const void* buf, unsigned bufByteCnt ) +cw::rc_t cw::file::fnWrite( const char* fn, const void* buf, unsigned bufByteCnt ) { - fileH_t h; + handle_t h; rc_t rc; - if((rc = fileOpen(h,fn,kWriteFileFl)) != kOkRC ) + if((rc = open(h,fn,kWriteFl)) != kOkRC ) goto errLabel; - rc = fileWrite(h,buf,bufByteCnt); + rc = write(h,buf,bufByteCnt); errLabel: - fileClose(h); + close(h); return rc; } -cw::rc_t cw::fileCopy( +cw::rc_t cw::file::copy( const char* srcDir, const char* srcFn, const char* srcExt, @@ -401,12 +407,12 @@ cw::rc_t cw::fileCopy( } // read the source file into a buffer - if((buf = fileFnToBuf(srcPathFn,&byteCnt)) == nullptr ) + if((buf = fnToBuf(srcPathFn,&byteCnt)) == nullptr ) rc = cwLogError(kReadFailRC,"Attempt to fill a buffer from '%s' failed.",cwStringNullGuard(srcPathFn)); else { // write the file to the output file - if( fileFnWrite(dstPathFn,buf,byteCnt) != kOkRC ) + if( fnWrite(dstPathFn,buf,byteCnt) != kOkRC ) rc = cwLogError(kWriteFailRC,"An attempt to write a buffer to '%s' failed.",cwStringNullGuard(dstPathFn)); } @@ -419,7 +425,7 @@ cw::rc_t cw::fileCopy( } -cw::rc_t cw::fileBackup( const char* dir, const char* name, const char* ext ) +cw::rc_t cw::file::backup( const char* dir, const char* name, const char* ext ) { rc_t rc = kOkRC; char* newName = nullptr; @@ -465,7 +471,7 @@ cw::rc_t cw::fileBackup( const char* dir, const char* name, const char* ext ) if( fileSysIsFile(newFn) == false ) { // .. then duplicate the file - if((rc = fileCopy(srcFn,nullptr,nullptr,newFn,nullptr,nullptr)) != kOkRC ) + if((rc = copy(srcFn,nullptr,nullptr,newFn,nullptr,nullptr)) != kOkRC ) rc = cwLogError(rc,"The file '%s' could not be duplicated as '%s'.",cwStringNullGuard(srcFn),cwStringNullGuard(newFn)); break; @@ -486,22 +492,22 @@ cw::rc_t cw::fileBackup( const char* dir, const char* name, const char* ext ) } -char* cw::fileToBuf( fileH_t h, unsigned* bufByteCntPtr ) +char* cw::file::toBuf( handle_t h, unsigned* bufByteCntPtr ) { return _fileToBuf(h,0,bufByteCntPtr); } -char* cw::fileFnToBuf( const char* fn, unsigned* bufByteCntPtr ) +char* cw::file::fnToBuf( const char* fn, unsigned* bufByteCntPtr ) { return _fileFnToBuf(fn,0,bufByteCntPtr); } -char* cw::fileToStr( fileH_t h, unsigned* bufByteCntPtr ) +char* cw::file::toStr( handle_t h, unsigned* bufByteCntPtr ) { return _fileToBuf(h,1,bufByteCntPtr); } -char* cw::fileFnToStr( const char* fn, unsigned* bufByteCntPtr ) +char* cw::file::fnToStr( const char* fn, unsigned* bufByteCntPtr ) { return _fileFnToBuf(fn,1,bufByteCntPtr); } -cw::rc_t cw::fileLineCount( fileH_t h, unsigned* lineCntPtr ) +cw::rc_t cw::file::lineCount( handle_t h, unsigned* lineCntPtr ) { rc_t rc = kOkRC; - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); unsigned lineCnt = 0; long offs; int c; @@ -510,7 +516,7 @@ cw::rc_t cw::fileLineCount( fileH_t h, unsigned* lineCntPtr ) cwAssert( lineCntPtr != nullptr ); *lineCntPtr = 0; - if((rc = fileTell(h,&offs)) != kOkRC ) + if((rc = tell(h,&offs)) != kOkRC ) return rc; errno = 0; @@ -522,7 +528,7 @@ cw::rc_t cw::fileLineCount( fileH_t h, unsigned* lineCntPtr ) if( c == EOF ) { if( errno ) - rc = cwLogSysError(kReadFailRC,errno,"File read char failed on 's'.", cwStringNullGuard(fileName(h))); + rc = cwLogSysError(kReadFailRC,errno,"File read char failed on 's'.", cwStringNullGuard(name(h))); else ++lineCnt; // add one in case the last line isn't terminated with a '\n'. @@ -535,7 +541,7 @@ cw::rc_t cw::fileLineCount( fileH_t h, unsigned* lineCntPtr ) } - if((rc = fileSeek(h,kBeginFileFl,offs)) != kOkRC ) + if((rc = seek(h,kBeginFl,offs)) != kOkRC ) return rc; *lineCntPtr = lineCnt; @@ -544,10 +550,10 @@ cw::rc_t cw::fileLineCount( fileH_t h, unsigned* lineCntPtr ) } -cw::rc_t cw::fileGetLine( fileH_t h, char* buf, unsigned* bufByteCntPtr ) +cw::rc_t cw::file::getLine( handle_t h, char* buf, unsigned* bufByteCntPtr ) { cwAssert( bufByteCntPtr != nullptr ); - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); unsigned tn = 128; char t[ tn ]; unsigned on = *bufByteCntPtr; @@ -555,7 +561,7 @@ cw::rc_t cw::fileGetLine( fileH_t h, char* buf, unsigned* bufByteCntPtr ) rc_t rc; // store the current file offset - if((rc = fileTell(h,&offs)) != kOkRC ) + if((rc = tell(h,&offs)) != kOkRC ) return rc; // if no buffer was given then use t[] @@ -598,7 +604,7 @@ cw::rc_t cw::fileGetLine( fileH_t h, char* buf, unsigned* bufByteCntPtr ) } // restore the original file offset - if((rc = fileSeek(h,kBeginFileFl,offs)) != kOkRC ) + if((rc = seek(h,kBeginFl,offs)) != kOkRC ) return rc; // add 1 for /0, 1 for /n and 1 to detect buf-too-short @@ -608,7 +614,7 @@ cw::rc_t cw::fileGetLine( fileH_t h, char* buf, unsigned* bufByteCntPtr ) } -cw::rc_t cw::fileGetLineAuto( fileH_t h, char** bufPtrPtr, unsigned* bufByteCntPtr ) +cw::rc_t cw::file::getLineAuto( handle_t h, char** bufPtrPtr, unsigned* bufByteCntPtr ) { rc_t rc = kOkRC; bool fl = true; @@ -620,7 +626,7 @@ cw::rc_t cw::fileGetLineAuto( fileH_t h, char** bufPtrPtr, unsigned* bufByteCntP { fl = false; - switch( rc = fileGetLine(h,buf,bufByteCntPtr) ) + switch( rc = getLine(h,buf,bufByteCntPtr) ) { case kOkRC: { @@ -644,91 +650,91 @@ cw::rc_t cw::fileGetLineAuto( fileH_t h, char** bufPtrPtr, unsigned* bufByteCntP return rc; } -cw::rc_t cw::fileReadChar( fileH_t h, char* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readChar( handle_t h, char* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadUChar( fileH_t h, unsigned char* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readUChar( handle_t h, unsigned char* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadShort( fileH_t h, short* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readShort( handle_t h, short* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadUShort( fileH_t h, unsigned short* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readUShort( handle_t h, unsigned short* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadLong( fileH_t h, long* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readLong( handle_t h, long* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadULong( fileH_t h, unsigned long* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readULong( handle_t h, unsigned long* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadInt( fileH_t h, int* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readInt( handle_t h, int* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadUInt( fileH_t h, unsigned int* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readUInt( handle_t h, unsigned int* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadFloat( fileH_t h, float* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readFloat( handle_t h, float* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadDouble( fileH_t h, double* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readDouble( handle_t h, double* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileReadBool( fileH_t h, bool* buf, unsigned cnt ) -{ return fileRead(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::readBool( handle_t h, bool* buf, unsigned cnt ) +{ return read(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteChar( fileH_t h, const char* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeChar( handle_t h, const char* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteUChar( fileH_t h, const unsigned char* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeUChar( handle_t h, const unsigned char* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteShort( fileH_t h, const short* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeShort( handle_t h, const short* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteUShort( fileH_t h, const unsigned short* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeUShort( handle_t h, const unsigned short* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteLong( fileH_t h, const long* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeLong( handle_t h, const long* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteULong( fileH_t h, const unsigned long* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeULong( handle_t h, const unsigned long* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteInt( fileH_t h, const int* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeInt( handle_t h, const int* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteUInt( fileH_t h, const unsigned int* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeUInt( handle_t h, const unsigned int* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteFloat( fileH_t h, const float* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeFloat( handle_t h, const float* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteDouble( fileH_t h, const double* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeDouble( handle_t h, const double* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteBool( fileH_t h, const bool* buf, unsigned cnt ) -{ return fileWrite(h,buf,sizeof(buf[0])*cnt); } +cw::rc_t cw::file::writeBool( handle_t h, const bool* buf, unsigned cnt ) +{ return write(h,buf,sizeof(buf[0])*cnt); } -cw::rc_t cw::fileWriteStr( fileH_t h, const char* s ) +cw::rc_t cw::file::writeStr( handle_t h, const char* s ) { rc_t rc; unsigned n = textLength(s); - if((rc = fileWriteUInt(h,&n,1)) != kOkRC ) + if((rc = writeUInt(h,&n,1)) != kOkRC ) return rc; if( n > 0 ) - rc = fileWriteChar(h,s,n); + rc = writeChar(h,s,n); return rc; } -cw::rc_t cw::fileReadStr( fileH_t h, char** sRef, unsigned maxCharN ) +cw::rc_t cw::file::readStr( handle_t h, char** sRef, unsigned maxCharN ) { unsigned n; rc_t rc; @@ -741,7 +747,7 @@ cw::rc_t cw::fileReadStr( fileH_t h, char** sRef, unsigned maxCharN ) maxCharN = 16384; // read the string length - if((rc = fileReadUInt(h,&n,1)) != kOkRC ) + if((rc = readUInt(h,&n,1)) != kOkRC ) return rc; // verify that string isn't too long @@ -754,7 +760,7 @@ cw::rc_t cw::fileReadStr( fileH_t h, char** sRef, unsigned maxCharN ) char* s = memAllocZ(n+1); // fill the buffer from the file - if((rc = fileReadChar(h,s,n)) != kOkRC ) + if((rc = readChar(h,s,n)) != kOkRC ) return rc; s[n] = 0; // terminate the string @@ -765,33 +771,33 @@ cw::rc_t cw::fileReadStr( fileH_t h, char** sRef, unsigned maxCharN ) } -cw::rc_t cw::filePrint( fileH_t h, const char* text ) +cw::rc_t cw::file::print( handle_t h, const char* text ) { - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); errno = 0; if( fputs(text,p->fp) < 0 ) - return cwLogSysError(kOpFailRC,errno,"File print failed on '%s'.", cwStringNullGuard(fileName(h))); + return cwLogSysError(kOpFailRC,errno,"File print failed on '%s'.", cwStringNullGuard(name(h))); return kOkRC; } -cw::rc_t cw::fileVPrintf( fileH_t h, const char* fmt, va_list vl ) +cw::rc_t cw::file::vPrintf( handle_t h, const char* fmt, va_list vl ) { - file_t* p = _fileHandleToPtr(h); + this_t* p = _handleToPtr(h); if( vfprintf(p->fp,fmt,vl) < 0 ) - return cwLogSysError(kOpFailRC,errno,"File print failed on '%s'.", cwStringNullGuard(fileName(h))); + return cwLogSysError(kOpFailRC,errno,"File print failed on '%s'.", cwStringNullGuard(name(h))); return kOkRC; } -cw::rc_t cw::filePrintf( fileH_t h, const char* fmt, ... ) +cw::rc_t cw::file::printf( handle_t h, const char* fmt, ... ) { va_list vl; va_start(vl,fmt); - rc_t rc = fileVPrintf(h,fmt,vl); + rc_t rc = vPrintf(h,fmt,vl); va_end(vl); return rc; } diff --git a/cwFile.h b/cwFile.h index cd3734d..aae7bd3 100644 --- a/cwFile.h +++ b/cwFile.h @@ -3,206 +3,209 @@ namespace cw { - typedef handle fileH_t; - - // Flags for use with fileOpen(). - enum fileOpenFlags_t + namespace file { - kReadFileFl = 0x01, //< Open a file for reading - kWriteFileFl = 0x02, //< Create an empty file for writing - kAppendFileFl = 0x04, //< Open a file for writing at the end of the file. - kUpdateFileFl = 0x08, //< Open a file for reading and writing. - kBinaryFileFl = 0x10, //< Open a file for binary (not text) input/output. - kStdoutFileFl = 0x20, //< Ignore fn use 'stdout' - kStderrFileFl = 0x40, //< Ignore fn use 'stderr' - kStdinFileFl = 0x80, //< Ignore fn use 'stdin' - }; + + typedef handle handle_t; - // Open or create a file. - // Equivalent to fopen(). - // If *hp was not initalized by an earlier call to fileOpen() then it should - // be set to fileNullHandle prior to calling this function. If *hp is a valid handle - // then it is automatically finalized by an internal call to fileClose() prior to - // being re-iniitalized. - // - // If kStdoutFileFl, kStderrFileFl or kStdinFileFl are set then - // file name argument 'fn' is ignored. - rc_t fileOpen( - fileH_t& hRef, // Pointer to a client supplied fileHandle_t to recieve the handle for the new object. - const char* fn, // The name of the file to open or create. - unsigned flags ); // See fileOpenFlags_t + // Flags for use with fileOpen(). + enum openFlags_t + { + kReadFl = 0x01, //< Open a file for reading + kWriteFl = 0x02, //< Create an empty file for writing + kAppendFl = 0x04, //< Open a file for writing at the end of the file. + kUpdateFl = 0x08, //< Open a file for reading and writing. + kBinaryFl = 0x10, //< Open a file for binary (not text) input/output. + kStdoutFl = 0x20, //< Ignore fn use 'stdout' + kStderrFl = 0x40, //< Ignore fn use 'stderr' + kStdinFl = 0x80, //< Ignore fn use 'stdin' + }; - // Close a file opened with Equivalent to fclose(). - rc_t fileClose( fileH_t& hRef ); + // Open or create a file. + // Equivalent to fopen(). + // If *hp was not initalized by an earlier call to fileOpen() then it should + // be set to fileNullHandle prior to calling this function. If *hp is a valid handle + // then it is automatically finalized by an internal call to fileClose() prior to + // being re-iniitalized. + // + // If kStdoutFl, kStderrFl or kStdinFl are set then + // file name argument 'fn' is ignored. + rc_t open( + handle_t& hRef, // Pointer to a client supplied fileHandle_t to recieve the handle for the new object. + const char* fn, // The name of the file to open or create. + unsigned flags ); // See fileOpenFlags_t - // Return true if the file handle is associated with an open file. - bool fileIsValid( fileH_t h ); + // Close a file opened with Equivalent to fclose(). + rc_t close( handle_t& hRef ); - // Read a block bytes from a file. Equivalent to fread(). - rc_t fileRead( fileH_t h, void* buf, unsigned bufByteCnt ); + // Return true if the file handle is associated with an open file. + bool isValid( handle_t h ); - // Write a block of bytes to a file. Equivalent to fwrite(). - rc_t fileWrite( fileH_t h, const void* buf, unsigned bufByteCnt ); + // Read a block bytes from a file. Equivalent to fread(). + rc_t read( handle_t h, void* buf, unsigned bufByteCnt ); + + // Write a block of bytes to a file. Equivalent to fwrite(). + rc_t write( handle_t h, const void* buf, unsigned bufByteCnt ); - enum fileSeekFlags_t - { - kBeginFileFl = 0x01, - kCurFileFl = 0x02, - kEndFileFl = 0x04 - }; + enum seekFlags_t + { + kBeginFl = 0x01, + kCurFl = 0x02, + kEndFl = 0x04 + }; - // Set the file position indicator. Equivalent to fseek(). - rc_t fileSeek( fileH_t h, enum fileSeekFlags_t flags, int offsByteCnt ); + // Set the file position indicator. Equivalent to fseek(). + rc_t seek( handle_t h, enum seekFlags_t flags, int offsByteCnt ); - // Return the file position indicator. Equivalent to ftell(). - rc_t fileTell( fileH_t h, long* offsPtr ); + // Return the file position indicator. Equivalent to ftell(). + rc_t tell( handle_t h, long* offsPtr ); - // Return true if the file position indicator is at the end of the file. - // Equivalent to feof(). - bool fileEof( fileH_t h ); + // Return true if the file position indicator is at the end of the file. + // Equivalent to feof(). + bool eof( handle_t h ); - // Return the length of the file in bytes - unsigned fileByteCount( fileH_t h ); - rc_t fileByteCountFn( const char* fn, unsigned* fileByteCntPtr ); + // Return the length of the file in bytes + unsigned byteCount( handle_t h ); + rc_t byteCountFn( const char* fn, unsigned* fileByteCntPtr ); - // Set *isEqualPtr=true if the two files are identical. - rc_t fileCompare( const char* fn0, const char* fn1, bool& isEqualFlRef ); + // Set *isEqualPtr=true if the two files are identical. + rc_t compare( const char* fn0, const char* fn1, bool& isEqualFlRef ); - // Return the file name associated with a file handle. - const char* fileName( fileH_t h ); + // Return the file name associated with a file handle. + const char* name( handle_t h ); - // Write a buffer to a file. - rc_t fileFnWrite( const char* fn, const void* buf, unsigned bufByteCnt ); + // Write a buffer to a file. + rc_t fnWrite( const char* fn, const void* buf, unsigned bufByteCnt ); - // Allocate and fill a buffer from the file. - // Set *bufByteCntPtr to count of bytes read into the buffer. - // 'bufByteCntPtr' is optional - set it to nullptr if it is not required by the caller. - // It is the callers responsibility to delete the returned buffer with a - // call to cmMemFree() - char* fileToBuf( fileH_t h, unsigned* bufByteCntPtr ); + // Allocate and fill a buffer from the file. + // Set *bufByteCntPtr to count of bytes read into the buffer. + // 'bufByteCntPtr' is optional - set it to nullptr if it is not required by the caller. + // It is the callers responsibility to delete the returned buffer with a + // call to cmMemFree() + char* toBuf( handle_t h, unsigned* bufByteCntPtr ); - // Same as fileToBuf() but accepts a file name argument. - char* fileFnToBuf( const char* fn, unsigned* bufByteCntPtr ); + // Same as fileToBuf() but accepts a file name argument. + char* fnToBuf( const char* fn, unsigned* bufByteCntPtr ); - // Copy the file named in srcDir/srcFn/srcExt to a file named dstDir/dstFn/dstExt. - // Note that srcExt/dstExt may be set to nullptr if the file extension is included - // in srcFn/dstFn. Likewise srcFn/dstFn may be set to nullptr if the file name - // is included in srcDir/dstDir. - rc_t fileCopy( - const char* srcDir, - const char* srcFn, - const char* srcExt, - const char* dstDir, - const char* dstFn, - const char* dstExt); + // Copy the file named in srcDir/srcFn/srcExt to a file named dstDir/dstFn/dstExt. + // Note that srcExt/dstExt may be set to nullptr if the file extension is included + // in srcFn/dstFn. Likewise srcFn/dstFn may be set to nullptr if the file name + // is included in srcDir/dstDir. + rc_t copy( + const char* srcDir, + const char* srcFn, + const char* srcExt, + const char* dstDir, + const char* dstFn, + const char* dstExt); - // This function creates a backup copy of the file 'fn' by duplicating it into - // a file named fn_#.ext where # is an integer which makes the file name unique. - // The integers chosen with zero and are incremented until an - // unused file name is found in the same directory as 'fn'. - // If the file identified by 'fn' is not found then the function returns quietly. - rc_t fileBackup( const char* dir, const char* name, const char* ext ); + // This function creates a backup copy of the file 'fn' by duplicating it into + // a file named fn_#.ext where # is an integer which makes the file name unique. + // The integers chosen with zero and are incremented until an + // unused file name is found in the same directory as 'fn'. + // If the file identified by 'fn' is not found then the function returns quietly. + rc_t backup( const char* dir, const char* name, const char* ext ); - // Allocate and fill a zero terminated string from a file. - // Set *bufByteCntPtr to count of bytes read into the buffer.= - // (the buffer memory size is one byte larger to account for the terminating zero) - // 'bufByteCntPtr' is optional - set it to nullptr if it is not required by the caller. - // It is the callers responsibility to delete the returned buffer with a - // call to cmMemFree() - char* fileToStr( fileH_t h, unsigned* bufByteCntPtr ); + // Allocate and fill a zero terminated string from a file. + // Set *bufByteCntPtr to count of bytes read into the buffer.= + // (the buffer memory size is one byte larger to account for the terminating zero) + // 'bufByteCntPtr' is optional - set it to nullptr if it is not required by the caller. + // It is the callers responsibility to delete the returned buffer with a + // call to cmMemFree() + char* toStr( handle_t h, unsigned* bufByteCntPtr ); - // Same as fileToBuf() but accepts a file name argument. - char* fileFnToStr( const char* fn, unsigned* bufByteCntPtr ); + // Same as fileToBuf() but accepts a file name argument. + char* fnToStr( const char* fn, unsigned* bufByteCntPtr ); - // Return the count of lines in a file. - rc_t fileLineCount( fileH_t h, unsigned* lineCntPtr ); + // Return the count of lines in a file. + rc_t lineCount( handle_t h, unsigned* lineCntPtr ); - // Read the next line into buf[bufByteCnt]. - // Consider using fileGetLineAuto() as an alternative to this function - // to avoid having to use a buffer with an explicit size. - // - // If buf is not long enough to hold the entire string then - // - // 1. The function returns kFileBufTooSmallRC - // 2. *bufByteCntPtr is set to the size of the required buffer. - // 3. The internal file position is left unchanged. - // - // If the buffer is long enough to hold the entire line then - // *bufByteCntPtr is left unchanged. - // See fileGetLineTest() in cmProcTest.c or fileGetLineAuto() - // in file.c for examples of how to use this function to a - // achieve proper buffer sizing. - rc_t fileGetLine( fileH_t h, char* buf, unsigned* bufByteCntPtr ); + // Read the next line into buf[bufByteCnt]. + // Consider using fileGetLineAuto() as an alternative to this function + // to avoid having to use a buffer with an explicit size. + // + // If buf is not long enough to hold the entire string then + // + // 1. The function returns kFileBufTooSmallRC + // 2. *bufByteCntPtr is set to the size of the required buffer. + // 3. The internal file position is left unchanged. + // + // If the buffer is long enough to hold the entire line then + // *bufByteCntPtr is left unchanged. + // See fileGetLineTest() in cmProcTest.c or fileGetLineAuto() + // in file.c for examples of how to use this function to a + // achieve proper buffer sizing. + rc_t getLine( handle_t h, char* buf, unsigned* bufByteCntPtr ); - // A version of fileGetLine() which eliminates the need to handle buffer - // sizing. - // - // Example usage: - // - // char* buf = nullptr; - // unsigned bufByteCnt = 0; - // while(fileGetLineAuto(h,&buf,&bufByteCnt)==kOkFileRC) - // proc(buf); - // cmMemPtrFree(buf); - // - // On the first call to this function *bufPtrPtr must be set to nullptr and - // *bufByteCntPtr must be set to 0. - // Following the last call to this function call cmMemPtrFree(bufPtrptr) - // to be sure the line buffer is fully released. Note this step is not - // neccessary if the last call does not return kOkFileRC. - rc_t fileGetLineAuto( fileH_t h, char** bufPtrPtr, unsigned* bufByteCntPtr ); + // A version of fileGetLine() which eliminates the need to handle buffer + // sizing. + // + // Example usage: + // + // char* buf = nullptr; + // unsigned bufByteCnt = 0; + // while(fileGetLineAuto(h,&buf,&bufByteCnt)==kOkFileRC) + // proc(buf); + // cmMemPtrFree(buf); + // + // On the first call to this function *bufPtrPtr must be set to nullptr and + // *bufByteCntPtr must be set to 0. + // Following the last call to this function call cmMemPtrFree(bufPtrptr) + // to be sure the line buffer is fully released. Note this step is not + // neccessary if the last call does not return kOkFileRC. + rc_t getLineAuto( handle_t h, char** bufPtrPtr, unsigned* bufByteCntPtr ); - // Binary Array Reading Functions - // Each of these functions reads a block of binary data from a file. - // The advantage to using these functions over fileRead() is only that they are type specific. - rc_t fileReadChar( fileH_t h, char* buf, unsigned cnt ); - rc_t fileReadUChar( fileH_t h, unsigned char* buf, unsigned cnt ); - rc_t fileReadShort( fileH_t h, short* buf, unsigned cnt ); - rc_t fileReadUShort( fileH_t h, unsigned short* buf, unsigned cnt ); - rc_t fileReadLong( fileH_t h, long* buf, unsigned cnt ); - rc_t fileReadULong( fileH_t h, unsigned long* buf, unsigned cnt ); - rc_t fileReadInt( fileH_t h, int* buf, unsigned cnt ); - rc_t fileReadUInt( fileH_t h, unsigned int* buf, unsigned cnt ); - rc_t fileReadFloat( fileH_t h, float* buf, unsigned cnt ); - rc_t fileReadDouble( fileH_t h, double* buf, unsigned cnt ); - rc_t fileReadBool( fileH_t h, bool* buf, unsigned cnt ); + // Binary Array Reading Functions + // Each of these functions reads a block of binary data from a file. + // The advantage to using these functions over fileRead() is only that they are type specific. + rc_t readChar( handle_t h, char* buf, unsigned cnt ); + rc_t readUChar( handle_t h, unsigned char* buf, unsigned cnt ); + rc_t readShort( handle_t h, short* buf, unsigned cnt ); + rc_t readUShort( handle_t h, unsigned short* buf, unsigned cnt ); + rc_t readLong( handle_t h, long* buf, unsigned cnt ); + rc_t readULong( handle_t h, unsigned long* buf, unsigned cnt ); + rc_t readInt( handle_t h, int* buf, unsigned cnt ); + rc_t readUInt( handle_t h, unsigned int* buf, unsigned cnt ); + rc_t readFloat( handle_t h, float* buf, unsigned cnt ); + rc_t readDouble( handle_t h, double* buf, unsigned cnt ); + rc_t readBool( handle_t h, bool* buf, unsigned cnt ); - // Binary Array Writing Functions - // Each of these functions writes an array to a binary file. - // The advantage to using functions rather than fileWrite() is only that they are type specific. - rc_t fileWriteChar( fileH_t h, const char* buf, unsigned cnt ); - rc_t fileWriteUChar( fileH_t h, const unsigned char* buf, unsigned cnt ); - rc_t fileWriteShort( fileH_t h, const short* buf, unsigned cnt ); - rc_t fileWriteUShort( fileH_t h, const unsigned short* buf, unsigned cnt ); - rc_t fileWriteLong( fileH_t h, const long* buf, unsigned cnt ); - rc_t fileWriteULong( fileH_t h, const unsigned long* buf, unsigned cnt ); - rc_t fileWriteInt( fileH_t h, const int* buf, unsigned cnt ); - rc_t fileWriteUInt( fileH_t h, const unsigned int* buf, unsigned cnt ); - rc_t fileWriteFloat( fileH_t h, const float* buf, unsigned cnt ); - rc_t fileWriteDouble( fileH_t h, const double* buf, unsigned cnt ); - rc_t fileWriteBool( fileH_t h, const bool* buf, unsigned cnt ); + // Binary Array Writing Functions + // Each of these functions writes an array to a binary file. + // The advantage to using functions rather than fileWrite() is only that they are type specific. + rc_t writeChar( handle_t h, const char* buf, unsigned cnt ); + rc_t writeUChar( handle_t h, const unsigned char* buf, unsigned cnt ); + rc_t writeShort( handle_t h, const short* buf, unsigned cnt ); + rc_t writeUShort( handle_t h, const unsigned short* buf, unsigned cnt ); + rc_t writeLong( handle_t h, const long* buf, unsigned cnt ); + rc_t writeULong( handle_t h, const unsigned long* buf, unsigned cnt ); + rc_t writeInt( handle_t h, const int* buf, unsigned cnt ); + rc_t writeUInt( handle_t h, const unsigned int* buf, unsigned cnt ); + rc_t writeFloat( handle_t h, const float* buf, unsigned cnt ); + rc_t writeDouble( handle_t h, const double* buf, unsigned cnt ); + rc_t writeBool( handle_t h, const bool* buf, unsigned cnt ); - // Write a string to a file as ... - // where N is the count of characters in the string. - rc_t fileWriteStr( fileH_t h, const char* s ); + // Write a string to a file as ... + // where N is the count of characters in the string. + rc_t writeStr( handle_t h, const char* s ); - // Read a string back from a file as written by fileWriteStr(). - // Note that the string will by string will be dynamically allocated - // and threfore must eventually be released via cmMemFree(). - // If maxCharN is set to zero then the default maximum string - // length is 16384. Note that this limit is used to prevent - // corrupt files from generating excessively long strings. - rc_t fileReadStr( fileH_t h, char** sRef, unsigned maxCharN ); + // Read a string back from a file as written by fileWriteStr(). + // Note that the string will by string will be dynamically allocated + // and threfore must eventually be released via cmMemFree(). + // If maxCharN is set to zero then the default maximum string + // length is 16384. Note that this limit is used to prevent + // corrupt files from generating excessively long strings. + rc_t readStr( handle_t h, char** sRef, unsigned maxCharN ); - // Formatted Text Output Functions: - // Print formatted text to a file. - rc_t filePrint( fileH_t h, const char* text ); - rc_t filePrintf( fileH_t h, const char* fmt, ... ); - rc_t fileVPrintf( fileH_t h, const char* fmt, va_list vl ); + // Formatted Text Output Functions: + // Print formatted text to a file. + rc_t print( handle_t h, const char* text ); + rc_t printf( handle_t h, const char* fmt, ... ); + rc_t vPrintf( handle_t h, const char* fmt, va_list vl ); - + } } diff --git a/cwLex.cpp b/cwLex.cpp index 0c81005..0b69ce8 100644 --- a/cwLex.cpp +++ b/cwLex.cpp @@ -532,27 +532,27 @@ cw::rc_t cw::lexSetTextBuffer( lexH_t h, const char* cp, unsigned cn cw::rc_t cw::lexSetFile( lexH_t h, const char* fn ) { - rc_t rc = kOkRC; - fileH_t fh; - lex_t* p = _lexHandleToPtr(h); - long n = 0; + rc_t rc = kOkRC; + file::handle_t fh; + lex_t* p = _lexHandleToPtr(h); + long n = 0; assert( fn != nullptr && p != nullptr ); // open the file - if((rc = fileOpen(fh,fn,kReadFileFl)) != kOkRC ) + if((rc = file::open(fh,fn,file::kReadFl)) != kOkRC ) return rc; // seek to the end of the file - if((rc = fileSeek(fh,kEndFileFl,0)) != kOkRC ) + if((rc = file::seek(fh,file::kEndFl,0)) != kOkRC ) return rc; // get the length of the file - if((rc = fileTell(fh,&n)) != kOkRC ) + if((rc = file::tell(fh,&n)) != kOkRC ) return rc; // rewind to the beginning of the file - if((rc = fileSeek(fh,kBeginFileFl,0)) != kOkRC ) + if((rc = file::seek(fh,file::kBeginFl,0)) != kOkRC ) return rc; // allocate the text buffer @@ -563,7 +563,7 @@ cw::rc_t cw::lexSetFile( lexH_t h, const char* fn ) } // read the file into the buffer - if((rc = fileRead(fh,p->textBuf,n)) != kOkRC ) + if((rc = file::read(fh,p->textBuf,n)) != kOkRC ) return rc; if((rc = _lexSetTextBuffer( p, p->textBuf, n )) != kOkRC ) @@ -571,7 +571,7 @@ cw::rc_t cw::lexSetFile( lexH_t h, const char* fn ) errLabel: // close the file - rc_t rc0 = fileClose(fh); + rc_t rc0 = file::close(fh); if(rc != kOkRC ) return rc; diff --git a/cwMem.h b/cwMem.h index 080d95f..4dbcc2e 100644 --- a/cwMem.h +++ b/cwMem.h @@ -93,11 +93,12 @@ namespace cw return memDuplStr(s1); } + // s1n is <= s0n // copy s1[] into s0[] size_t i=0; for(; s1[i]; ++i) s0[i] = s1[i]; - s0[i+1] = 0; + s0[i] = 0; return s0; } @@ -118,7 +119,7 @@ namespace cw C buf[ bufN + 1 ]; - size_t n = vsnprintf(buf,bufN,fmt,vl1); + size_t n = vsnprintf(buf,bufN+1,fmt,vl1); cwAssert(n <= bufN); diff --git a/cwObject.cpp b/cwObject.cpp index d607bc4..311743e 100644 --- a/cwObject.cpp +++ b/cwObject.cpp @@ -521,7 +521,7 @@ cw::rc_t cw::objectFromFile( const char* fn, object_t*& objRef ) unsigned bufByteCnt = 0; char* buf = NULL; - if(( buf = fileFnToStr(fn, &bufByteCnt)) != NULL ) + if(( buf = file::fnToStr(fn, &bufByteCnt)) != NULL ) { rc = objectFromString( buf, objRef ); memRelease(buf); diff --git a/main.cpp b/main.cpp index 4a03ede..166b1fd 100644 --- a/main.cpp +++ b/main.cpp @@ -16,7 +16,9 @@ #include "cwMidi.h" #include "cwTime.h" #include "cwMidiPort.h" -#include "cwAudioPort.h" +#include "cwAudioDevice.h" +#include "cwAudioDeviceTest.h" +#include "cwAudioDeviceAlsa.h" #include "cwAudioBuf.h" #include @@ -126,10 +128,8 @@ void serialPortSrvTest( cw::object_t* cfg, int argc, const char* argv[] ) { cw:: void midiDeviceTest( cw::object_t* cfg, int argc, const char* argv[] ) { cw::midi::device::test();} void textBufTest( cw::object_t* cfg, int argc, const char* argv[] ) { cw::textBuf::test(); } void audioBufTest( cw::object_t* cfg, int argc, const char* argv[] ) { cw::audio::buf::test(); } -void audioPortTest( cw::object_t* cfg, int argc, const char* argv[] ) -{ - cw::audio::device::test( false, argc, argv ); -} +void audioDevTest( cw::object_t* cfg, int argc, const char* argv[] ) { cw::audio::device::test( argc, argv ); } +void audioDevAlsaTest( cw::object_t* cfg, int argc, const char* argv[] ) { cw::audio::device::alsa::report(); } void stubTest( cw::object_t* cfg, int argc, const char* argv[] ) { @@ -168,7 +168,8 @@ int main( int argc, const char* argv[] ) { "midiDevice", midiDeviceTest }, { "textBuf", textBufTest }, { "audioBuf", audioBufTest }, - { "audioPort",audioPortTest }, + { "audioDev",audioDevTest }, + { "audioDevAlsa", audioDevAlsaTest }, { "stub", stubTest }, { nullptr, nullptr } }; diff --git a/setup.sh b/setup.sh index 0a55d2f..6c81a20 100644 --- a/setup.sh +++ b/setup.sh @@ -1,2 +1,5 @@ export LD_LIBRARY_PATH=~/sdk/libwebsockets/build/out/lib +# restart pulseaudio to free ALSA driver +systemctl --user restart pulseaudio +