diff --git a/cwAudioFile.cpp b/cwAudioFile.cpp index adcdcf5..02b6724 100644 --- a/cwAudioFile.cpp +++ b/cwAudioFile.cpp @@ -439,17 +439,25 @@ namespace cw return rc; } - rc_t _open( af_t* p, const char* fn, const char* fileModeStr ) + rc_t _open( af_t* p, const char* fname, const char* fileModeStr ) { rc_t rc = kOkRC; - + char* fn = nullptr; + // zero the info record memset(&p->info,0,sizeof(p->info)); + // expand the path + if((fn = filesys::expandPath(fname)) == nullptr ) + { + rc = cwLogError(kOpFailRC,"File path expansion failed on '%s'.",cwStringNullGuard(fname)); + goto errLabel; + } + // open the file if((p->fp = fopen(fn,fileModeStr)) == NULL ) { - rc = cwLogError(kOpenFailRC,"Audio file open failed on '%s'.",cwStringNullGuard(fn)); + rc = cwLogError(kOpenFailRC,"Audio file open failed on '%s'.",cwStringNullGuard(fname)); goto errLabel; } @@ -521,6 +529,8 @@ namespace cw if( rc!=kOkRC ) _destroy(p); + mem::release(fn); + return rc; } @@ -1449,23 +1459,29 @@ cw::rc_t cw::audiofile::open( handle_t& h, const char* fn, info_t* info ) } -cw::rc_t cw::audiofile::create( handle_t& h, const char* fn, double srate, unsigned bits, unsigned chCnt ) +cw::rc_t cw::audiofile::create( handle_t& h, const char* fname, double srate, unsigned bits, unsigned chCnt ) { rc_t rc = kOkRC; af_t* p = nullptr; + char* fn = nullptr; if((rc = close(h)) != kOkRC ) return rc; - if( fn == NULL || strlen(fn)==0 ) + if( fname == NULL || strlen(fname)==0 ) return cwLogError(kInvalidArgRC,"Audio file create failed. The file name is blank."); + + if((fn = filesys::expandPath(fname)) == nullptr ) + { + rc = cwLogError(kOpFailRC,"File path expansion failed on '%s'.",cwStringNullGuard(fname)); + goto errLabel; + } p = mem::allocZ(1); - + if((rc = _filenameToAudioFileType(fn, p->info.flags )) != kOkRC ) goto errLabel; - // open the file for writing if((p->fp = fopen(fn,"wb")) == NULL ) { @@ -1495,6 +1511,9 @@ cw::rc_t cw::audiofile::create( handle_t& h, const char* fn, double srate, unsig h.set(p); } errLabel: + + mem::release(fn); + if( rc != kOkRC ) _destroy(p); diff --git a/cwAudioFile.h b/cwAudioFile.h index 4939438..dec54e1 100644 --- a/cwAudioFile.h +++ b/cwAudioFile.h @@ -74,9 +74,11 @@ namespace cw } info_t; + // The file path for fn is internally expanded if it begins with a '~' or '..'. rc_t open( handle_t& h, const char* fn, info_t* info ); // Set bits to 0 to write the file in IEEE float format. + // The file path for fn is internally expanded if it begins with a '~' or '..'. rc_t create( handle_t& h, const char* fn, double srate, unsigned bits, unsigned chN ); rc_t close( handle_t& h ); @@ -139,6 +141,11 @@ namespace cw rc_t writeFloat( handle_t h, unsigned frmCnt, unsigned chCnt, const float* const* bufPtrPtr ); rc_t writeDouble( handle_t h, unsigned frmCnt, unsigned chCnt, const double* const* bufPtrPtr ); + // Write a buffer of interleaved floating point samples. Note that no sample format conversion is + // implemented on this function. The samples are directly written to the current file location. + // This means that the file must have been 'created()' with 'bits' set to 0 to indicate that the + // file is using a single precision float sample format. This limitation could easily be removed + // by adding sample conversion to integer types. rc_t writeFloatInterleaved( handle_t h, unsigned frmCnt, unsigned chCnt, const float* bufPtr ); // File Writing Functions