cwAudioFile.h/cpp, cwMtx.cpp, Makefile.am : Added cwAudioFile and cwMtx.cpp.
This commit is contained in:
parent
d492374df7
commit
1af6b58667
@ -5,6 +5,7 @@ libcwHDR += src/libcw/cwCommon.h src/libcw/cwCommonImpl.h src/libcw/cwMem.h
|
||||
libcwSRC += src/libcw/cwCommonImpl.cpp src/libcw/cwMem.cpp src/libcw/cwLog.cpp src/libcw/cwUtility.cpp
|
||||
|
||||
libcwHDR += src/libcw/cwMtx.h
|
||||
libcwSRC += src/libcw/cwMtx.cpp
|
||||
|
||||
libcwHDR += src/libcw/cwFileSys.h src/libcw/cwText.h src/libcw/cwFile.h src/libcw/cwTime.h src/libcw/cwLex.h src/libcw/cwNumericConvert.h
|
||||
libcwSRC += src/libcw/cwFileSys.cpp src/libcw/cwText.cpp src/libcw/cwFile.cpp src/libcw/cwTime.cpp src/libcw/cwLex.cpp
|
||||
@ -18,8 +19,8 @@ libcwSRC += src/libcw/cwThread.cpp src/libcw/cwMutex.cpp src/libcw/cwThreadMach
|
||||
libcwHDR += src/libcw/cwMpScNbQueue.h src/libcw/cwSpScBuf.h src/libcw/cwSpScQueueTmpl.h
|
||||
libcwSRC += src/libcw/cwSpScBuf.cpp src/libcw/cwSpScQueueTmpl.cpp
|
||||
|
||||
libcwHDR += src/libcw/cwSvg.h
|
||||
libcwSRC += src/libcw/cwSvg.cpp
|
||||
libcwHDR += src/libcw/cwSvg.h src/libcw/cwAudioFile.h
|
||||
libcwSRC += src/libcw/cwSvg.cpp src/libcw/cwAudioFile.cpp
|
||||
|
||||
libcwHDR += src/libcw/cwWebSock.h src/libcw/cwWebSockSvr.h src/libcw/cwLib.h
|
||||
libcwSRC += src/libcw/cwWebSock.cpp src/libcw/cwWebSockSvr.cpp src/libcw/cwLib.cpp
|
||||
|
1962
cwAudioFile.cpp
Normal file
1962
cwAudioFile.cpp
Normal file
File diff suppressed because it is too large
Load Diff
183
cwAudioFile.h
Normal file
183
cwAudioFile.h
Normal file
@ -0,0 +1,183 @@
|
||||
#ifndef cwAudioFile_h
|
||||
#define cwAudioFile_h
|
||||
|
||||
#ifndef cwAudioFile_MAX_FRAME_READ_CNT
|
||||
// Maximum number of samples which will be read in one call to fread().
|
||||
// This value is only significant in that an internal buffer is created on the stack
|
||||
// whose size must be limited to prevent stack overflows.
|
||||
#define cwAudioFile_MAX_FRAME_READ_CNT (8192)
|
||||
#endif
|
||||
|
||||
|
||||
namespace cw
|
||||
{
|
||||
namespace audiofile
|
||||
{
|
||||
typedef handle<struct audiofile_str> handle_t;
|
||||
|
||||
// Informational flags used by audioFileInfo
|
||||
enum
|
||||
{
|
||||
kAiffAfFl = 0x01, // this is an AIFF file
|
||||
kWavAfFl = 0x02, // this is a WAV file
|
||||
kSwapAfFl = 0x04, // file header bytes must be swapped
|
||||
kAifcAfFl = 0x08, // this is an AIFC file
|
||||
kSwapSamplesAfFl = 0x10 // file sample bytes must be swapped
|
||||
};
|
||||
|
||||
|
||||
// Constants
|
||||
enum
|
||||
{
|
||||
kAudioFileLabelCharCnt = 256,
|
||||
|
||||
kAfBextDescN = 256,
|
||||
kAfBextOriginN = 32,
|
||||
kAfBextOriginRefN = 32,
|
||||
kAfBextOriginDateN = 10,
|
||||
kAfBextOriginTimeN = 8
|
||||
};
|
||||
|
||||
// Aiff marker record
|
||||
typedef struct
|
||||
{
|
||||
unsigned id;
|
||||
unsigned frameIdx;
|
||||
char label[kAudioFileLabelCharCnt];
|
||||
} marker_t;
|
||||
|
||||
// Broadcast WAV header record As used by ProTools audio files. See http://en.wikipedia.org/wiki/Broadcast_Wave_Format
|
||||
// When generated from Protools the timeRefLow/timeRefHigh values appear to actually refer
|
||||
// to the position on the Protools time-line rather than the wall clock time.
|
||||
typedef struct
|
||||
{
|
||||
char desc[ kAfBextDescN + 1 ];
|
||||
char origin[ kAfBextOriginN + 1 ];
|
||||
char originRef[ kAfBextOriginRefN + 1 ];
|
||||
char originDate[kAfBextOriginDateN + 1 ];
|
||||
char originTime[kAfBextOriginTimeN + 1 ];
|
||||
unsigned timeRefLow; // sample count since midnight low word
|
||||
unsigned timeRefHigh; // sample count since midnight high word
|
||||
} bext_t;
|
||||
|
||||
// Audio file information record used by audioFileNew and audioFileOpen
|
||||
typedef struct
|
||||
{
|
||||
unsigned bits; // bits per sample
|
||||
unsigned chCnt; // count of audio file channels
|
||||
double srate; // audio file sample rate in samples per second
|
||||
unsigned frameCnt; // total number of sample frames in the audio file
|
||||
unsigned flags; // informational flags
|
||||
unsigned markerCnt; // count of markers in markerArray
|
||||
marker_t* markerArray; // array of markers
|
||||
bext_t bextRecd; // only used with Broadcast WAV files
|
||||
} info_t;
|
||||
|
||||
|
||||
rc_t open( handle_t& h, const char* fn, info_t* info );
|
||||
|
||||
rc_t create( handle_t& h, const char* fn, double srate, unsigned bits, unsigned chN );
|
||||
|
||||
rc_t close( handle_t& h );
|
||||
|
||||
// Return true if the handle is open.
|
||||
bool isOpen( handle_t h );
|
||||
|
||||
// Return true if the current file position is at the end of the file.
|
||||
bool isEOF( handle_t h );
|
||||
|
||||
// Return the current file position as a frame index.
|
||||
unsigned tell( handle_t h );
|
||||
|
||||
// Set the current file position as an offset from the first frame.
|
||||
rc_t seek( handle_t h, unsigned frmIdx );
|
||||
|
||||
// Sample Reading Functions.
|
||||
//
|
||||
// Fill a user suppled buffer with up to frmCnt samples.
|
||||
// If less than frmCnt samples are available at the specified audio file location then the unused
|
||||
// buffer space is set to zero. Check *actualFrmCntPtr for the count of samples actually available
|
||||
// in the return buffer. Functions which do not include a begFrmIdx argument begin reading from
|
||||
// the current file location (see seek()). The buf argument is always a pointer to an
|
||||
// array of pointers of length chCnt. Each channel buffer specified in buf[] must contain at least
|
||||
// frmCnt samples.
|
||||
//
|
||||
//
|
||||
// h An audio file handle returned from an earlier call to audioFileNew()
|
||||
// fn The name of the audio file to read.
|
||||
// begFrmIdx The frame index of the first sample to read. Functions that do not use this parameter begin reading at the current file location (See tell()).
|
||||
// frmCnt The number of samples allocated in buf.
|
||||
// chIdx The index of the first channel to read.
|
||||
// chCnt The count of channels to read.
|
||||
// buf An array containing chCnt pointers to arrays of frmCnt samples.
|
||||
// actualFrmCntPtr The number of frames actually written to the return buffer (ignored if NULL)
|
||||
|
||||
rc_t readInt( handle_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr );
|
||||
rc_t readFloat( handle_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr );
|
||||
rc_t readDouble( handle_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr );
|
||||
|
||||
rc_t getInt( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr, info_t* afInfoPtr);
|
||||
rc_t getFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, info_t* afInfoPtr);
|
||||
rc_t getDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, info_t* afInfoPtr);
|
||||
|
||||
// Sum the returned samples into the output buffer.
|
||||
rc_t readSumInt( handle_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr );
|
||||
rc_t readSumFloat( handle_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr );
|
||||
rc_t readSumDouble( handle_t h, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr );
|
||||
|
||||
rc_t getSumInt( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, int** buf, unsigned* actualFrmCntPtr, info_t* afInfoPtr);
|
||||
rc_t getSumFloat( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, float** buf, unsigned* actualFrmCntPtr, info_t* afInfoPtr);
|
||||
rc_t getSumDouble( const char* fn, unsigned begFrmIdx, unsigned frmCnt, unsigned chIdx, unsigned chCnt, double** buf, unsigned* actualFrmCntPtr, info_t* afInfoPtr);
|
||||
|
||||
// Sample Writing Functions
|
||||
rc_t writeInt( handle_t h, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr );
|
||||
rc_t writeFloat( handle_t h, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr );
|
||||
rc_t writeDouble( handle_t h, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr );
|
||||
|
||||
rc_t writeFileInt( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, int** bufPtrPtr);
|
||||
rc_t writeFileFloat( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, float** bufPtrPtr);
|
||||
rc_t writeFileDouble( const char* fn, double srate, unsigned bit, unsigned frmCnt, unsigned chCnt, double** bufPtrPtr);
|
||||
|
||||
|
||||
// Scan an entire audio file and return the minimum, maximum and mean sample value.
|
||||
// On error *minPtr, *maxPtr, and *meanPtr are set to -acSample_MAX, cmSample_MAX, and 0 respectively
|
||||
rc_t minMaxMean( handle_t h, unsigned chIdx, float* minPtr, float* maxPtr, float* meanPtr );
|
||||
rc_t minMaxMeanFn( const char* fn, unsigned chIdx, float* minPtr, float* maxPtr, float* meanPtr );
|
||||
|
||||
// Return the file name associated with a audio file handle.
|
||||
const char* name( handle_t h );
|
||||
unsigned channelCount( handle_t h );
|
||||
double sampleRate( handle_t h );
|
||||
|
||||
// Return the info_t record associated with a file.
|
||||
rc_t getInfo( const char* fn, info_t* infoPtr );
|
||||
|
||||
// Print the info_t to a file.
|
||||
void printInfo( const info_t* infoPtr, log::handle_t logH );
|
||||
|
||||
rc_t reportInfo( const char* audioFn );
|
||||
|
||||
// Print the file header information and frmCnt sample values beginning at frame index frmIdx.
|
||||
rc_t report( handle_t h, log::handle_t logH, unsigned frmIdx=0, unsigned frmCnt=kInvalidCnt );
|
||||
rc_t reportFn( const char* fn, log::handle_t logH, unsigned frmIdx=0, unsigned frmCnt=kInvalidCnt );
|
||||
|
||||
// Change the sample rate value in the header. Note that this function does not resample the audio
|
||||
// signal it simply changes the value of the sample rate in the header.
|
||||
rc_t setSrate( const char* audioFn, unsigned srate );
|
||||
|
||||
// Generate a sine tone and write it to a file.
|
||||
rc_t sine( const char* fn, double srate, unsigned bits, double hz, double gain, double secs );
|
||||
|
||||
// Mix a set of audio files.
|
||||
rc_t mix( const char* fnV[], const float* gainV, unsigned srcN, const char* outFn, unsigned outBits );
|
||||
rc_t mix( const object_t* cfg );
|
||||
|
||||
// Testing and example routine for functions in .h.
|
||||
// Also see cmProcTest.c readWriteTest()
|
||||
rc_t test( const object_t* cfg );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
164
cwMtx.cpp
Normal file
164
cwMtx.cpp
Normal file
@ -0,0 +1,164 @@
|
||||
#include "cwCommon.h"
|
||||
#include "cwLog.h"
|
||||
#include "cwCommonImpl.h"
|
||||
#include "cwMem.h"
|
||||
#include "cwObject.h"
|
||||
#include "cwMtx.h"
|
||||
|
||||
|
||||
namespace cw
|
||||
{
|
||||
namespace mtx
|
||||
{
|
||||
bool _mtx_object_is_list( const object_t* cfg, unsigned& dimN )
|
||||
{
|
||||
if( cfg->is_list() )
|
||||
{
|
||||
dimN += 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned _mtx_object_get_degree( const object_t* cfg )
|
||||
{
|
||||
unsigned dimN = 0;
|
||||
const object_t* o = cfg;
|
||||
while( _mtx_object_is_list(o,dimN) )
|
||||
o = o->child_ele(0);
|
||||
|
||||
return dimN;
|
||||
}
|
||||
|
||||
rc_t _mtx_object_get_shape( const object_t* cfg, unsigned i, unsigned* dimV, unsigned dimN, unsigned& eleN )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
if( !cfg->is_list() )
|
||||
return kOkRC;
|
||||
|
||||
dimV[i] = cfg->child_count();
|
||||
|
||||
eleN = eleN == 0 ? dimV[i] : eleN * dimV[i];
|
||||
|
||||
if((rc = _mtx_object_get_shape(cfg->child_ele(0), i+1, dimV, dimN, eleN )) != kOkRC )
|
||||
return rc;
|
||||
|
||||
if( cfg->child_ele(0)->is_list() )
|
||||
{
|
||||
unsigned ch0 = cfg->child_ele(0)->child_count();
|
||||
for(unsigned j=1; j<dimV[i]; ++j)
|
||||
if( ch0 != cfg->child_ele(j)->child_count())
|
||||
return cwLogError(kSyntaxErrorRC,"A matrix contains an inconsistent dimension length on dimension index %i",i+1);
|
||||
|
||||
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
unsigned _offsetMulV( const unsigned* mulV, unsigned dimN, unsigned* idxV )
|
||||
{
|
||||
unsigned n = 0;
|
||||
for(unsigned i=0; i<dimN; ++i)
|
||||
n += idxV[i] * mulV[i];
|
||||
return n;
|
||||
}
|
||||
|
||||
unsigned _offsetDimV( const unsigned* dimV, unsigned dimN, unsigned* idxV )
|
||||
{
|
||||
unsigned n = idxV[0];
|
||||
for(unsigned i=1; i<dimN; ++i)
|
||||
{
|
||||
unsigned m = idxV[i];
|
||||
for(int j=i-1; j>=0; --j)
|
||||
m *= dimV[j];
|
||||
n += m;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
cw::rc_t cw::mtx::test( const object_t* cfg )
|
||||
{
|
||||
rc_t rc = kOkRC;
|
||||
|
||||
d_t* mtx0 = nullptr;
|
||||
d_t* mtx1 = nullptr;
|
||||
d_t* mtx2 = nullptr;
|
||||
d_t* mtx3 = nullptr;
|
||||
d_t* mtx_y0 = nullptr;
|
||||
d_t* mtx_y1 = nullptr;
|
||||
d_t y;
|
||||
|
||||
const object_t* m0 = cfg->find("m0");
|
||||
if( m0 != nullptr )
|
||||
mtx0 = allocCfg<double>(m0);
|
||||
|
||||
const object_t* m1 = cfg->find("m1");
|
||||
if( m1 != nullptr )
|
||||
mtx1 = allocCfg<double>(m1);
|
||||
|
||||
const object_t* m2 = cfg->find("m2");
|
||||
if( m2 != nullptr )
|
||||
mtx2 = allocCfg<double>(m2);
|
||||
|
||||
const object_t* m3 = cfg->find("m3");
|
||||
if( m3 != nullptr )
|
||||
mtx3 = allocCfg<double>(m3);
|
||||
|
||||
const object_t* y0 = cfg->find("y0");
|
||||
if( y0 != nullptr )
|
||||
mtx_y0 = allocCfg<double>(y0);
|
||||
|
||||
const object_t* y1 = cfg->find("y1");
|
||||
if( y1 != nullptr )
|
||||
mtx_y1 = allocCfg<double>(y1);
|
||||
|
||||
unsigned n = offset(mtx1,1,1);
|
||||
printf("offset: %i\n",n);
|
||||
|
||||
|
||||
report(*mtx0,"m0");
|
||||
report(*mtx1,"m1");
|
||||
report(*mtx2,"m2");
|
||||
report(*mtx3,"m3");
|
||||
report(*mtx_y0,"y0");
|
||||
report(*mtx_y1,"y1");
|
||||
|
||||
|
||||
if( mtx_mul(y,*mtx1,*mtx0) == kOkRC )
|
||||
{
|
||||
report(y,"y0");
|
||||
if( !is_equal(*mtx_y0,y) )
|
||||
rc = cwLogError(kTestFailRC,"Test 0 fail.");
|
||||
}
|
||||
|
||||
|
||||
transpose(*mtx0);
|
||||
transpose(*mtx1);
|
||||
|
||||
if( mtx_mul(y,*mtx1,*mtx0) == kOkRC )
|
||||
{
|
||||
report(y,"y1");
|
||||
if( !is_equal(*mtx_y1,y) )
|
||||
rc = cwLogError(kTestFailRC,"Test 1 fail.");
|
||||
}
|
||||
|
||||
release(mtx0);
|
||||
release(mtx1);
|
||||
release(mtx2);
|
||||
release(mtx3);
|
||||
release(mtx_y0);
|
||||
release(mtx_y1);
|
||||
release(y);
|
||||
return rc;
|
||||
}
|
Loading…
Reference in New Issue
Block a user