/* ==================================================================== * AuAHMF.h * Version: 0.500 * ==================================================================== */ #ifndef Au_AHMF_H #define Au_AHMF_H /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * AuAHMF maintains the AHM file format and header information * * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * Copyright (C) 1998-2010 AuSIM, Inc. * * This document contains UNPUBLISHED PROPRIETARY SOURCE CODE of * AuSIM Engineering Solutions, Palo Alto, CA; * the contents of this file may not be disclosed to third parties, * copied or duplicated in any form, in whole or in part, * without the prior written permission of AuSIM Engineering Solutions. * * RESTRICTED RIGHTS LEGEND: * Use, duplication or disclosure by the Government is subject to * restrictions as set forth in subdivision (c)(1)(ii) of the Rights in * Technical Data and Computer Software clause at DFARS 252.227-7013, * and/or in similar or successor clauses in the FAR, DOD or NASA FAR * Supplements. * Unpublished - * rights reserved under the Copyright Laws of the United States. * * Authors: * William L. Chapin (WLC) * Agnieszka Roginska (ARO) * -------------------------------------------------------------------- * Modification log: * 27Oct04 WLC 0.500 PCA support * 19Dec00 WLC 0.301 Completed redesign * 18Dec00 WLC 0.300 Redesigned for AHM v1.410, made public * 05Dec00 ARO 0.200 Revamped for AHM v1.4 * 04Jan98 WlC 0.100 Created. * -------------------------------------------------------------------- * Keywords: Acoustic Head Map, file format, filter, HRTF * ==================================================================== */ #ifndef Au_AHM_HDR_H #include "AuAHMhdr.h" #endif struct AuAHMFSizes; #ifndef AuCORE_AHM_ERRORMGR_H //#include "AHMErrorCodes.h" #endif class AHMErrorMgr; enum AHMerrCode; const float SpeedOfSound20CSealevel_mps = 343.26f; // helper object for sequence fields class AuSeqField : public ah_sequence_field { public: AuSeqField(); AuSeqField(const AuSeqField &sf); AuSeqField(const ah_sequence_field &sf); AuSeqField &operator=(const AuSeqField &sf); AuSeqField &operator=(const ah_sequence_field &sf); bool operator==(const AuSeqField &sf); bool operator==(const ah_sequence_field &sf); bool IsConsistent(const AuSeqField &sf); bool IsConsistent(const ah_sequence_field &sf); void Set(const char flg, const char f0=0, const char f1=0, const char f2=0, const char f3=0, const char f4=0, const char f5=0, const char f6=0); }; class AuAHMF { protected: aAHMF_th txt_header; aAHMF_bh bin_header; char *p_asc_header; char *p_data_buffer; size_t l_data_bufsiz; size_t l_actual_filesiz; // bin_header.totlSiz is computed char c_type_by_extension; public: AuAHMF(AFMfileType typ=AFMfileAHM); AuAHMF(const AuAHMF &ahmf); AuAHMF(const char *ahmfilename, AFMfileType typ=AFMfileAHM); virtual ~AuAHMF() { delete_asc_header(); delete_data_buffer(); } bool Read(const char *ahmfilename); bool Write(const char *ahmfilename) const; bool ReadUsingFILEptr(void *fileptr, AHMErrorMgr &emgr); // lower level Read for file already open with *FILE handle float Version() const { return decypher_version(txt_header.version); } // cannot set the version const char * VerText() const { return txt_header.version; } const char * HeadID() const { return txt_header.head_id; } const char * Comment() const { return txt_header.comment; } int GetASCIIHeader(char *buffer, int bufsiz) const; const aAHMF_bh &GetBinHeader() const { return bin_header; } int FileType() const { return bin_header.fileTyp; } size_t FileSize() const { return bin_header.totlSiz; } // only valid after ComputeTotals() size_t TimeStampUTC() const { return bin_header.lotmDat; } bool TimeStampUTC(long &lo_dword, long &hi_dword) const; bool TimeStampUTC(int &year, int &month, int &day, int &hours, int &minutes, int &seconds) const; int TimeEpochYear() const { return ((bin_header.hitmDat>>16)&0x0FFF); } int TimeEpochHours() const { return (bin_header.hitmDat&0x0FFFF); } float SampleRate() const { return bin_header.smplRat; } // sample rate in Hertz float HeadSize() const { return bin_header.headSiz; } // interaural distance in range units float FixedPointConv() const { return bin_header.fixpCvt; } // fixed point coefficient conversion value float BassExtendFreq() const { return bin_header.bassFrq; } // bass extension low-pass cut-off frequency float TrebleExtendFreq() const { return bin_header.trebFrq; } // treble extension high-pass cut-off frequency float FreqCutoffSlope() const { return bin_header.cutoSlp; } // frequency cut-off slope float SpeedOfSound() const { return bin_header.spdoSnd; } // speed of sound at which measurements were taken size_t TotalResponses() const { return bin_header.totlRsp; } // total responses stored (including caps) int AzimResponses() const { return bin_header.azimRsp; } // grid azimuth responses int ElevResponses() const { return bin_header.elevRsp; } // grid elevation responses int RangeResponses() const { return bin_header.rangRsp; } // grid range responses int MeasuredFilters() const { return IsEQFType() ? bin_header.elevRsp : 1; } // for EQF only! size_t ResponseTaps() const { return CoefsPerFunc(); } // Returns the total number of coefficients size_t FilterSections() const; size_t CoefsPerFunc() const; // total coefficients per response function (all sections together) size_t CoefsPerSection() const; // total coefficients per section int ResponseTapZeros() const { return bin_header.rtapZrs; } // response tap zero coefficients int ResponseTapPoles() const { return bin_header.rtapPls; } // response tap pole coefficients int ZeroCoefficients() const; // numerator coefficients int PoleCoefficients() const { return bin_header.rtapPls; } // denominator coefficients int StagesPerFunc() const; int ResponseComponents() const { return bin_header.respCmp; } // response components (number of weights if PCA) // Must reinterpret this method, search all of AuSIMDev int OptimizedTaps() const { return exist_fld_in_seq(bin_header.bnsdSeq,AHMF_WEIGHTING) ? bin_header.respTps : bin_header.optmTps; } // compression optimization size int WeightingTaps() const { return exist_fld_in_seq(bin_header.bnsdSeq,AHMF_WEIGHTING) ? bin_header.optmTps : 0; } // weighting function size int SinkCount() const { return bin_header.sinkCnt; } // 0 == 2 for backward compatibility int VirtualNodeCount() const { return bin_header.virtNod; } // number of virtual nodes (affects sink vector, labels, triangles) int VirtualSinkCount() const { return bin_header.sinkCnt + bin_header.virtNod; } // number of virtual sinks (affects sink vector, labels, triangles) int TriangleCount() const { return bin_header.triaCnt; } // length of sink vector triangle list int CoefficientBits() const { return bin_header.coefSiz; } // bits per coefficient int TimeDelayBits() const { return bin_header.iatdSiz; } // bits per delay int WeightBits() const { return bin_header.wghtSiz; } // bits per weight int NormalLevelBits() const { return bin_header.nlvlSiz; } // bits per normal level int CoefficientDataType() const { return bin_header.coefDat; } // DataType per coefficient int TimeDelayDataType() const { return bin_header.iatdDat; } // DataType per delay int WeightDataType() const { return bin_header.wghtDat; } // DataType per weight int NormalLevelDataType() const { return bin_header.nlvlDat; } // DataType per normal level float AzimOrigin() const { return bin_header.azimOrg; } // primary axis, see AHMaxisConfig float AzimInterval() const { return bin_header.azimInt; } // primary axis, see AHMaxisConfig float ElevOrigin() const { return bin_header.elevOrg; } // secondary axis, see AHMaxisConfig float ElevInterval() const { return bin_header.elevInt; } // secondary axis, see AHMaxisConfig float RangeOrigin() const { return bin_header.rangOrg; } // tertiary axis, see AHMaxisConfig float RangeInterval() const { return bin_header.rangInt; } // tertiary axis, see AHMaxisConfig int AxisConfiguration() const { return bin_header.axisCfg; } // axis order and type, see AHMaxesConfig int WindowType() const { return bin_header.wndoTyp; } // filter window type, see AHMwindowType enum int DisplayEQType() const { return bin_header.dseqTyp; } // display EQ type, see AHMdisplayEQType enum int FieldEQType() const { return bin_header.fdeqTyp; } // field EQ method, see AHMfieldEQType enum int LevelEQType() const { return bin_header.lveqTyp; } // level EQ method, see AHMlevelEQType enum int EncryptionType() const { return bin_header.crptTyp; } // encryption type, see AHMencryptType enum int EnhanceMethods() const { return bin_header.enhcMtd; } // enhancement method, see AHMenhanceMethod OR bits int NormalizationType() const { return bin_header.nrmlTyp; } // normalization type (peak/RMS), see AHMnormalizationType enum int LeftRespSource() const { return bin_header.leftSrc; } // left responses, see AHMrespSource enum int RightRespSource() const { return bin_header.rghtSrc; } // right responses, see AHMrespSource enum int NorthCapSource() const { return bin_header.NcapSrc; } // north polarcap, see AHMrespSource enum int SouthCapSource() const { return bin_header.ScapSrc; } // south polarcap, see AHMrespSource enum int TrackingDevice() const { return bin_header.trakDev; } // head tracking device,see AHMtrackingDevice enum int DistanceUnits() const { return bin_header.distFmt; } // dist units, see AHMscaleUnits enum int AngleUnits() const { return bin_header.anglFmt; } // angular units, see AHMscaleUnits enum int TimeUnits() const { return bin_header.timeFmt; } // time units, see AHMscaleUnits enum int NormalLevelUnits() const { return bin_header.nlvlFmt; } // lin/db units, see AHMscaleUnits enum int AzimIncrOp() const { return bin_header.azimInc; } // azim increment, see AHMincrOperation enum int ElevIncrOp() const { return bin_header.elevInc; } // elev increment, see AHMincrOperation enum int RangeIncrOp() const { return bin_header.rangInc; } // rang increment, see AHMincrOperation enum // queries bool IsEQFType() const { return ((bin_header.fileTyp!=AFMfileAHM)&&(bin_header.fileTyp!=AFMfileAFM)); } bool IsDistanceInches() const { return (bin_header.distFmt==AHMdistInches); } bool IsDistanceMeters() const { return (bin_header.distFmt==AHMdistMeters); } bool IsAngleRadians() const { return (bin_header.anglFmt==AHManglRadians); } bool IsAngleDegrees() const { return (bin_header.anglFmt==AHManglDegrees); } bool IsAngleGrads() const { return (bin_header.anglFmt==AHManglGradians); } bool IsTimeSamples() const { return (bin_header.timeFmt==AHMtimeSamples); } bool IsTimeSeconds() const { return (bin_header.timeFmt==AHMtimeSeconds); } bool IsTimeMillisecs() const { return (bin_header.timeFmt==AHMtimeMSecs); } bool IsTimeMicrosecs() const { return (bin_header.timeFmt==AHMtimeUSecs); } bool IsEncrypted() const { return (bin_header.crptTyp!=0); } bool IsBassBoosted() const { return ((bin_header.enhcMtd&AHM_ENH_BassExt)!=0); } bool IsSmoothed() const { return ((bin_header.enhcMtd&AHM_ENH_CritBand)!=0); } bool IsCoefFloat() const { return (bin_header.coefDat==AHMdataFloat); } bool IsWeightFloat() const { return (bin_header.wghtDat==AHMdataFloat); } bool IsDelayFloat() const { return (bin_header.iatdDat==AHMdataFloat); } bool IsLevelFloat() const { return (bin_header.nlvlDat==AHMdataFloat); } bool ExistNorthCap() const { return (bin_header.NcapSrc!=0); } bool ExistSouthCap() const { return (bin_header.ScapSrc!=0); } bool IsCommentFlagged() const { return (bin_header.readCmt!=0); } bool IsTracked() const { return (bin_header.trakDev!=0); } bool IsDelayInteraural() const { return exist_fld_in_seq(bin_header.respSeq,AHMF_IATD); } bool IsLevelInteraural() const { return exist_fld_in_seq(bin_header.respSeq,AHMF_IALD); } int ExistASCIIHeader() const { return bin_header.thisMap; }; // returns number of bytes in ASCII allocation bool ExistRespData() const; // basis components are appended bool ExistTimeData() const; // basis components are appended bool ExistLevelData() const; // basis components are appended int ExistBasisFuncs() const; // basis components are appended bool ExistRespVectors() const; // map of vectors to each response are appended bool ExistTrackData() const; // map of tracking error for each response bool ExistTrackErrData() const; // map of tracking error for each response resolved to 3DOF bool ExistSinkVectors() const; // table of vectors for each sink bool ExistSinkBearings() const; // table of bearings for each sink bool ExistSinkLabels() const; // table of vectors for each sink bool ExistWeighting() const; // an EQ/normalization weighting filter of WeightingTaps() tap length bool ExistSinkTriangles() const; // table of triples connecting sinks/virtual nodes bool ExistSinkChannelMap() const; // list of channel for each sink bool IsAHM_1_43_RspSeq() const; // formerly ahm_1_43_type() bool IsSectionVersion() const; bool IsStrictSections() const; float LatestVersion() const; // returns most current version, based on filetype bool ComputeTotals(AuAHMFSizes &sd) const; // gathers intermediate data char ExtensionFileType() const { return c_type_by_extension; } bool ReportInconsistencies(char *report, int report_buf_size) const; bool ReportInconsistencies(char *report, int report_buf_size, int &nerrs, int &errsev) const; bool ErrorCheck(AHMerrCode *error_buffer, int errbufsiz, int &err_count, int &err_sev) const; bool ErrorCheck(AHMErrorMgr &emgr) const; // sequences AuSeqField VectorSequence() const { return (bin_header.vectSeq); } AuSeqField RegionSequence() const { return (bin_header.regnSeq); } AuSeqField ResponseSequence() const { return (bin_header.respSeq); } AuSeqField SectionSequence() const { return (bin_header.coefSeq); } AuSeqField BonusDataSequence() const { return (bin_header.bnsdSeq); } AuSeqField CoefSequence() const { return (bin_header.coefSeq); } int VectorSequence(int idx) const { return seq_fld(idx,bin_header.vectSeq); } int RegionSequence(int idx) const { return seq_fld(idx,bin_header.regnSeq); } int ResponseSequence(int idx) const { return seq_fld(idx,bin_header.respSeq); } int SectionSequence(int idx) const { return seq_fld(idx,bin_header.coefSeq); } int BonusDataSequence(int idx) const { return seq_fld(idx,bin_header.bnsdSeq); } int CoefSequence(int idx) const { return seq_fld(idx,bin_header.coefSeq); } const int * VectorSeqPtr() const { return (int*)(&bin_header.vectSeq); } const int * RegionSeqPtr() const { return (int*)(&bin_header.regnSeq); } const int * ResponseSeqPtr() const { return (int*)(&bin_header.respSeq); } const int * SectionSeqPtr() const { return (int*)(&bin_header.coefSeq); } const int * BonusDataSeqPtr() const { return (int*)(&bin_header.bnsdSeq); } const int * CoefSeqPtr() const { return (int*)(&bin_header.coefSeq); } static int FieldIndexInSequence(const AuSeqField &seq, int field, int test=0); static bool AnyMoreFieldsInSequence(const AuSeqField &seq, int idx=0); static int LastNonZeroFieldIndex(const AuSeqField &seq); // text header sets bool HeadID(const char *hid); bool Comment(const char *cmt); bool VerText(const char *ver); bool SetTimeStamp(); // current time&date bool SetTimeStampUTC(long lo_dword, long hi_dword); bool SetTimeEpoch(long lo_dword, int epoch_yr_ad, int epoch_hrs); bool SetTimeStamp(int year, int month, int day, int hours, int minutes, int seconds=0, int gmt=0); bool AzimResponses(int resps) { return set_ushrt(bin_header.azimRsp,resps); } bool ElevResponses(int resps) { return set_ushrt(bin_header.elevRsp,resps); } bool RangeResponses(int resps) { return set_ushrt(bin_header.rangRsp,resps); } bool ResponseTaps(size_t taps); bool FilterSections(size_t sections); // RespTps field is now indicates filterSections for IIR bool OptimizedTaps(int taps) { return exist_fld_in_seq(bin_header.bnsdSeq,AHMF_WEIGHTING) ? false : set_ushrt(bin_header.optmTps,taps); } // zero if un-smoothed bool WeightingTaps(int taps) { return exist_fld_in_seq(bin_header.bnsdSeq,AHMF_WEIGHTING) ? set_ushrt(bin_header.optmTps,taps) : false; } // zero if un-smoothed bool ResponseComponents(int comps) { return set_ushrt(bin_header.respCmp,comps); } bool ResponseTapZeros(int zeros) { return set_ushrt(bin_header.rtapZrs,zeros); } bool ResponseTapPoles(int poles) { return set_ushrt(bin_header.rtapPls,poles); } bool ZeroCoefficients(size_t zeros); // numerator coefficients bool PoleCoefficients(int poles); // denominator coefficients bool SinkCount(int sinks) { return set_ushrt(bin_header.sinkCnt,sinks); } bool TriangleCount(int trias) { return set_ushrt(bin_header.triaCnt,trias); } bool VirtualNodeCount(int nodes) { return set_ushrt(bin_header.virtNod,nodes); } bool AxisConfiguration(int type); // axis order and type, see AHMaxesConfig bool WindowType(int type); // filter window type, see AHMwindowType enum bool DisplayEQType(int type); // display EQ type, see AHMdisplayEQType enum bool FieldEQType(int type); // field EQ method, see AHMfieldEQType enum bool LevelEQType(int type); // level EQ method, see AHMlevelEQType enum bool EncryptionType(int type); // encryption type, see AHMencryptType enum bool NormalizationType(int type); // normalization type (peak/RMS), see AHMnormalizationType enum bool EnhanceMethods(int type); // enhancement method, see AHMenhanceMethod OR bits bool LeftRespSource(int type) { return set_rsrc(bin_header.leftSrc,type); } // see AHMrespSource enum bool RightRespSource(int type) { return set_rsrc(bin_header.rghtSrc,type); } // see AHMrespSource enum bool NorthCapSource(int type) { return set_rsrc(bin_header.NcapSrc,type); } // see AHMrespSource enum bool SouthCapSource(int type) { return set_rsrc(bin_header.ScapSrc,type); } // see AHMrespSource enum bool TrackingDevice(int type); // head tracking device see AHMrespSource enum bool FlagComment(bool flag=true) { return bin_header.readCmt = flag; } bool SampleRate(float rate); // assume data resampled properly bool SpeedOfSound(float spd, int dfmt=AHMdistSpecUnits, int tfmt=AHMtimeSpecUnits); // converts to internal units float FixedPointConv(float conv) { return bin_header.fixpCvt = conv; } float BassExtendFreq(float freq) { return bin_header.bassFrq = freq; } // bass extension low-pass cut-off frequency float TrebleExtendFreq(float freq) { return bin_header.trebFrq = freq; } // treble extension high-pass cut-off frequency float FreqCutoffSlope(float slope) { return bin_header.cutoSlp = slope; } // treble extension high-pass cut-off frequency float HeadSize(float size, int units=-1); float AzimOrigin(float orig, int units=-1); float ElevOrigin(float orig, int units=-1); float RangeOrigin(float orig, int units=-1); float AzimInterval(float intv, int units=-1); float ElevInterval(float intv, int units=-1); float RangeInterval(float intv, int units=-1); bool DistanceUnits(int units); // dist units, see AHMscaleUnits enum bool AngleUnits(int units); // angular units, see AHMscaleUnits enum bool TimeUnits(int units); // time units, see AHMscaleUnits enum bool NormalLevelUnits(int units); // lin/db units, see AHMscaleUnits enum bool CoefficientData(int type, int bits) { return set_bits(bin_header.coefSiz,type,bits); } bool TimeDelayData(int type, int bits) { return set_bits(bin_header.iatdSiz,type,bits); } bool WeightData(int type, int bits) { return set_bits(bin_header.wghtSiz,type,bits); } bool NormalLevelData(int type, int bits) { return set_bits(bin_header.nlvlSiz,type,bits); } int AzimIncrOp(int type) { return set_op(bin_header.azimInc,type); } int ElevIncrOp(int type) { return set_op(bin_header.elevInc,type); } int RangeIncrOp(int type) { return set_op(bin_header.rangInc,type); } bool VectorSequence(int idx, int fld) { return set_sqfld(bin_header.vectSeq,idx,fld); } bool RegionSequence(int idx, int fld) { return set_sqfld(bin_header.regnSeq,idx,fld); } bool ResponseSequence(int idx, int fld) { return set_sqfld(bin_header.respSeq,idx,fld); } bool SectionSequence(int idx, int fld) { return set_sqfld(bin_header.coefSeq,idx,fld); } bool BonusDataSequence(int idx, int fld) { return set_sqfld(bin_header.bnsdSeq,idx,fld); } bool CoefSequence(int idx, int fld) { return set_sqfld(bin_header.coefSeq,idx,fld); } bool VectorSequence(const AuSeqField &sf) { bin_header.vectSeq=sf; return true; } bool RegionSequence(const AuSeqField &sf) { bin_header.regnSeq=sf; return true; } bool ResponseSequence(const AuSeqField &sf) { bin_header.respSeq=sf; return true; } bool SectionSequence(const AuSeqField &sf) { bin_header.coefSeq=sf; return true; } bool BonusDataSequence(const AuSeqField &sf) { bin_header.bnsdSeq=sf; return true; } bool CoefSequence(const AuSeqField &sf) { bin_header.coefSeq=sf; return true; } static bool SequenceRemoveField(AuSeqField &sf, int idx=-1); static bool SequenceAddField(AuSeqField &sf, int fld, int idx=-1); bool Conform2Spec(AHMErrorMgr &emgr, float ver_target=1.3f); bool ConformIA2PerSink(AHMErrorMgr &emgr); bool SetASCIIHeader(const char *ascii); // sets the ascii header and thisMap offset bool ComputeTotals(); // sets totlSiz and totlRsp from current format settings void ResetDefault(AFMfileType typ=AFMfileAHM) { set_txt_default(typ); set_bin_default(typ); } void ExtensionFileType(int type) { c_type_by_extension = char(type&0x007F); } static const char *AppendExtension(const char *filename, char *buf, int bufsiz, int type=0); static bool Find(const char *filename, char *fullpathbuf, int pathbufsiz); static int FileTypeByExtension(const char *filename); static bool GetTypeVerSize(const char *filename, int &type, float &version, size_t &bytes); AuAHMF &operator=(const AuAHMF &ahmf); // low-level access char * TextData() { return (char*)&txt_header; } char * BinaryData() { return (char*)&bin_header; } const char * DataBlock() const { return p_data_buffer; } size_t ActualFileSize() const { return l_actual_filesiz; } // only good after a Read size_t DataBlockSize() const { return l_data_bufsiz; } // only valid after Read() // helpers - these probably should all be protected methods float AnglConversionFactor(int units, bool inv=false) const; float DistConversionFactor(int units, bool inv=false) const; float TimeConversionFactor(int units, bool inv=false) const; double MeterInDistanceUnits() const { return DistInAHMUnits(1); } double PiInAngleUnits() const; // { return AnglInAHMUnits(M_PI); } double SecondInTimeUnits() const { return TimeInAHMUnits(1); } double AnglInAHMUnits(double angl, int units=AHManglRadians) const; double DistInAHMUnits(double dist, int units=AHMdistMeters) const; double TimeInAHMUnits(double tval, int units=AHMtimeSeconds) const; double LevelChangeInAHMUnits(double lval, int units=AHMlevelDecibels) const; // Sizes size_t total_grid_locations() const; size_t respsize() const; size_t timesize() const; size_t levlsize() const; size_t compsize() const; size_t mapgsize() const; private: void set_txt_default(AFMfileType typ/*=AFMfileAHM*/); void set_bin_default(AFMfileType typ/*=AFMfileAHM*/); void delete_asc_header(); void delete_data_buffer(); bool create_ascii_header(); bool set_ushrt(unsigned short &fld, int val); bool set_op (unsigned char &fld, int op); bool set_rsrc (unsigned char &fld, int src); bool set_bits (unsigned char &fld, int typ, int bts); static bool valid_seq_fld_idx(int idx); static int seq_fld(int idx, const ah_sequence_field &sf); static bool set_sqfld(ah_sequence_field &fld, int idx, int type); static int get_fld_in_seq(const ah_sequence_field &sf, int type, int test=0); static bool exist_fld_in_seq(const ah_sequence_field &sf, int type); static bool exist_fld_range_in_seq(const ah_sequence_field &sf, int min, int max); static float decypher_version(const char *str); // cannot set the version static int decypher_filekey(const char *str); // cannot set the filekey }; // struct AuAHMFSizes is used in ComputeTotals struct AuAHMFSizes { size_t nlocations; // grid plus caps size_t nresponses; // sinks * nlocations size_t sz_header; // text + binary + extra size_t sz_filter; // taps * (zeros+poles) size_t ndelayploc; // delays per loc size_t nlevelploc; // levels per loc size_t nbases; // total bases in file, each with ncomps size_t sz_resps; // nlocs * nsnks * filt/comp size_t sz_delays; // nlocs * delays per loc size_t sz_levels; // nlocs * levels per loc size_t sz_basis; // ncomp * filt * nbase size_t sz_vectors; // nlocs * (trak+resp+sink) size_t sz_labels; // nsnks * AFMF_SINKLABELSTR_SIZ size_t sz_this; // size of the AuAHMFSizes structure for compatibility size_t sz_weighting; // (zeros+poles) * optmTaps if weighting exists size_t sz_triangles; // 12*triaCnt size_t sz_chnlmap; // 4*nsnks // datasegment is sz_resp + sz_delays + sz_levels + sz_basis + sz_vectors // total file size adds sz_header AuAHMFSizes() : nlocations(0) , nresponses(0) , sz_header(0) , sz_filter(0) , ndelayploc(0) , nlevelploc(0) , nbases(0) , sz_resps(0) , sz_delays(0) , sz_levels(0) , sz_basis(0) , sz_vectors(0) , sz_this(sizeof(AuAHMFSizes)) , sz_weighting(0) , sz_triangles(0) , sz_chnlmap(0) { ; } }; // ========================================================================== // ===================== INLINE PUBLIC METHOD IMPLEMENTATION: AuAHMF // ========================================================================== // Class: AuAHMF // Method: constructor // ------------------- // Creates a new AuAHMF object. If dflt is true, fill the AHMF with default values. // inline AuAHMF::AuAHMF(AFMfileType typ) : p_asc_header(0) , p_data_buffer(0) , l_data_bufsiz(0) , l_actual_filesiz(0) , c_type_by_extension(-1) { set_txt_default(typ); set_bin_default(typ); } // Class: AuAHMF // Method: constructor // -------------------- // Copy constructor. Creates a new AuAHMF object from an existing ahmf // inline AuAHMF::AuAHMF(const AuAHMF &ahmf) : p_asc_header(0) , p_data_buffer(0) , l_data_bufsiz(0) , l_actual_filesiz(0) , c_type_by_extension(-1) { *this = ahmf; } // Class: AuAHMF // Method: constructor // ------------------- // Creates a new AuAHMF object. If dflt is true, fill the AHMF with default values. // inline AuAHMF::AuAHMF(const char *ahmfilename,AFMfileType typ) : p_asc_header(0) , p_data_buffer(0) , l_data_bufsiz(0) , l_actual_filesiz(0) , c_type_by_extension(-1) { set_txt_default(typ); set_bin_default(typ); Read(ahmfilename); } // Class: AuAHMF // Method: FilterSections() // ----------------------------------- // Returns the number of filter sections per function/response // inline size_t AuAHMF::FilterSections() const { // This first condition has no coefficients, despite what respTps may say if ( (ResponseTapPoles() == 0) && (ResponseTapZeros() == 0) ) return 0; // This second condition is the legacy FIR case supporting very long FIR if ( (ResponseTapPoles() == 0) && (ResponseTapZeros() == 1) ) return 1; // number of filter sections per function/response // Final condition // Any IIR // Any FIR with rtapZrs > 1 which is cascaded (or maybe parallel but uncommon) return bin_header.respTps; } // Class: AuAHMF // Method: CoefsPerFunc() // ----------------------------------- // Returns the total number of coefficients including all filter sections // in the response. // inline size_t AuAHMF::CoefsPerFunc() const { return FilterSections()*(ZeroCoefficients() + PoleCoefficients()); // total number of coefs per response } // Class: AuAHMF // Method: StagesPerFunc() // ----------------------------------- // Returns the total number of stages of the filter inline int AuAHMF::StagesPerFunc() const { const AuSeqField &sseq = SectionSequence(); int nstages = LastNonZeroFieldIndex(sseq) + 1; return ( (nstages < 1) ? 0 : (sseq.flg == 0) ? 1 : nstages); } // Class: AuAHMF // Method: CoefsPerSection() // ----------------------------------- // Returns the number of coefficients per filter section // in the response filter. // inline size_t AuAHMF::CoefsPerSection() const { return (ZeroCoefficients() + PoleCoefficients()); // total number of coefs per filter section } inline int AuAHMF::ZeroCoefficients() const { // legacy case if ( (bin_header.rtapZrs <= 1) && (bin_header.rtapPls == 0) ) return bin_header.respTps; return bin_header.rtapZrs; } // Class: AuAHMF // Method: SampleRate(sample_rate) // ----------------------------------- // Sets the sampling rate (between 11025 and 100,000Hz) // inline bool AuAHMF::SampleRate(float rate) // assume data resampled properly { if ( (rate < 4000.0) || (rate > 192000.0) ) return false; bin_header.smplRat = rate; return true; } // Class: AuAHMF // Method: SpeedOfSound(spd,dfmt,tfmt) // ----------------------------------- // Sets the speed of sound at time of sampling, converts to AHM units // inline bool AuAHMF::SpeedOfSound(float spd, int dfmt, int tfmt) { bin_header.spdoSnd = spd * DistConversionFactor(dfmt) / TimeConversionFactor(tfmt); return true; } // Class: AuAHMF // Method: ResponseTaps(num_taps) // ----------------------------------- // Sets the number of taps (coefficients) in an FIR filter. // Has no effect on IIR filters (returns false) // inline bool AuAHMF::ResponseTaps(size_t taps) { // do nothing for IIR filters if (bin_header.rtapPls > 0) return false; // if there are already multiple sections of FIR, // then must use more specific methods of FilterSections() and ZeroCoefficients() if ( (bin_header.respTps > 1) && (bin_header.rtapZrs > 1) ) return false; // make sure not a super long FIR filter (greater than 31 bits) // super long FIR must use multiple sections if ((unsigned __int64)taps > 0x7FFFFFFF) return false; // if already using legacy method, then continue if (bin_header.rtapZrs == 1) { bin_header.respTps = (unsigned long)taps; return true; } // if number of taps > 15-bits [32767 (2^15 - 1)], // then must use legacy method if ((unsigned long)taps > 0x00007FFF) { bin_header.rtapZrs = 1; // one coef per tap bin_header.respTps = (unsigned long)taps; return true; } // finally use single section, with taps stored in zero coefs bin_header.respTps = 1; // one section bin_header.rtapZrs = (unsigned short)taps; return true; } // Class: AuAHMF // Method: FilterSections(num_sections) // ----------------------------------- // Sets the number of sections in the response filter. // inline bool AuAHMF::FilterSections(size_t sections) // RespTps field is now indicates filterSections for IIR { // Cannot set FilterSections on legacy FIR format if ( (bin_header.rtapZrs == 1) && (bin_header.rtapPls == 0) ) return false; // Must set PoleCoefficients and ZeroCoefficients appropriately prior to FilterSections if ( (sections >= 1) && (bin_header.rtapZrs == 0) && (bin_header.rtapPls == 0)) return false; if ( (sections == 0) && ( (bin_header.rtapZrs > 0) || (bin_header.rtapPls > 0) ) ) return false; // save filter sections value in the old response taps structure field bin_header.respTps = (unsigned long)sections; return true; } // numerator coefficients inline bool AuAHMF::ZeroCoefficients(size_t zeros) { if ((unsigned __int64)zeros > 0x7FFFFFFF) return false; // if number of taps > 15-bits [32767 (2^15 - 1)], // then must use legacy method if ((unsigned long)zeros > 0x00007FFF) return ResponseTaps(zeros); bin_header.rtapZrs = (unsigned short)zeros; return true; } // denominator coefficients inline bool AuAHMF::PoleCoefficients(int poles) { if ( (bin_header.rtapZrs == 1) && (bin_header.respTps > 0x07FFF) ) return false; // big FIR filter return set_ushrt(bin_header.rtapPls,poles); } // Class: AuAHMF // Method: AxisConfiguration(type) // ------------------------ inline bool AuAHMF::AxisConfiguration(int type) // axis order and type, see AHMaxesConfig { switch (type) { case AHMaxesDefault: // corrects for an early default error, equates to Spherical_ZYR case AHMaxesSpherical_ZYR: // CRE/UWMadison default case AHMaxesSpherical_YXR: // UCDavis default case AHMaxesSpherical_XZR: // for cylindrical: first axis = azim, height = elev case AHMaxesCylindrical_ZHR: case AHMaxesCylindrical_YHR: case AHMaxesCylindrical_XHR: // for cartesian: azim = Y, elev = Z, rang = X case AHMaxesCartesian_YZX: case AHMaxesSpherical_RYZ: // special format with range first, elevation second, azimuth last bin_header.axisCfg = (unsigned char)type; return true; } return false; } // Class: AuAHMF // Method: WindowType(type) // ------------------------ // Sets the window type. "type" must be one of the WindowType enum. // WindowType enum is defined in AuAHMhdr.h // inline bool AuAHMF::WindowType(int type) { if ( (type < AHMwndoNone) || (type >= AHMwndoLast) ) return false; bin_header.wndoTyp = (unsigned char)type; return true; } // Class: AuAHMF // Method: DisplayEQType // ---------------------- // Sets the equalization type. "type" must be one of the AHMdisplayEQType enum // AHMdisplayEQType enum is defined in AuAHMhdr.h // inline bool AuAHMF::DisplayEQType(int type) { if ( (type < AHMdseqNone) || (type >= AHMdseqLast) ) return false; bin_header.dseqTyp = (unsigned char)type; return true; } // Class: AuAHMF // Method: FieldEQType(type) // ------------------------ inline bool AuAHMF::FieldEQType(int type) // field EQ method, see AHMfieldEQType enum { if ( (type < AHMfdeqNone) || (type >= AHMfdeqLast) ) return false; bin_header.fdeqTyp = (unsigned char)type; return true; } // Class: AuAHMF // Method: LevelEQType(type) // ------------------------ inline bool AuAHMF::LevelEQType(int type) // field EQ method, see AHMfieldEQType enum { if ( (type < AHMlveqNone) || (type >= AHMlveqLast) ) return false; bin_header.lveqTyp = (unsigned char)type; return true; } // Class: AuAHMF // Method: EncryptionType(type) // ------------------------ inline bool AuAHMF::EncryptionType(int type) // encryption type, see AHMencryptType enum { if ( (type < AHMcryptNone) || (type >= AHMcryptLast) ) return false; bin_header.crptTyp = (unsigned char)type; return true; } // Class: AuAHMF // Method: NormalizationType(type) // ------------------------ inline bool AuAHMF::NormalizationType(int type) // Normalization type, see AHMnormalizationType enum { if ( (type < AHMnlvlNone) || (type >= AHMnlvlLast) ) return false; bin_header.nrmlTyp = (unsigned char)type; return true; } // Class: AuAHMF // Method: EnhanceMethods(type) // ------------------------ inline bool AuAHMF::EnhanceMethods(int type) // enhancement method, see AHMenhanceMethod OR bits { if ( (type < 0) || (type > 0x0FF) ) return false; bin_header.enhcMtd = (unsigned char)type; return true; } // Class: AuAHMF // Method: TimeUnits(units) // ------------------------ // Change the current units of time measurement. inline bool AuAHMF::TimeUnits(int units) { switch (units) { case AHMtimeSamples: case AHMtimeSeconds: case AHMtimeMSecs: case AHMtimeUSecs: bin_header.timeFmt = (unsigned char)units; return true; } return false; } // Class: AuAHMF // Method: NormalLevelUnits(units) // ------------------------ // Change the current units of normalization level. inline bool AuAHMF::NormalLevelUnits(int units) { switch (units) { case AHMlevelLinear: case AHMlevelDecibels: bin_header.nlvlFmt = (unsigned char)units; return true; } return false; } // Class: AuAHMF // Method: TrackingDevice(type) // ------------------------ inline bool AuAHMF::TrackingDevice(int type) // tracking device, see AHMtrackingDevice { if ( (type < AHMtrakNone) || (type > AHMtrakLast) ) return false; bin_header.trakDev = (unsigned char)type; return true; } inline bool AuAHMF::ExistRespData() const { if (!bin_header.respTps || !bin_header.totlRsp) return false; if (!total_grid_locations()) return false; if (exist_fld_in_seq(bin_header.respSeq,AHMF_RESP)) return true; if (exist_fld_range_in_seq(bin_header.respSeq,AHMF_LEFT,AHMF_RGHT)) return true; if (exist_fld_range_in_seq(bin_header.respSeq,EQRS_SCMP,EQRS_RAWD)) return true; return false; } inline bool AuAHMF::ExistTimeData() const { if (!total_grid_locations()) return false; if (exist_fld_in_seq(bin_header.respSeq,AHMF_TIME)) return true; if (exist_fld_range_in_seq(bin_header.respSeq,AHMF_LATD,AHMF_RATD)) return true; if (exist_fld_in_seq(bin_header.respSeq,AHMF_IATD)) return true; return false; } inline bool AuAHMF::ExistLevelData() const { if (!total_grid_locations()) return false; if (exist_fld_in_seq(bin_header.respSeq,AHMF_LEVL)) return true; if (exist_fld_range_in_seq(bin_header.respSeq,AHMF_LALO,AHMF_RALO)) return true; if (exist_fld_in_seq(bin_header.respSeq,AHMF_IALD)) return true; return false; } inline int AuAHMF::ExistBasisFuncs() const { int nbases = 0; if (exist_fld_in_seq(bin_header.regnSeq,AHMF_BASISLEFT)) nbases++; if (exist_fld_in_seq(bin_header.regnSeq,AHMF_BASISRGHT)) nbases++; if (exist_fld_in_seq(bin_header.regnSeq,AHMF_BASIS)) nbases++; if (exist_fld_in_seq(bin_header.regnSeq,AHMF_BASISSINK)) nbases += bin_header.sinkCnt; return nbases; } inline bool AuAHMF::ExistRespVectors() const { return ( ( (bin_header.azimInc == AHMincrNoGrid) // azim increment (add/multiply/log) || (bin_header.elevInc == AHMincrNoGrid) // elev increment (add/multiply/log) || (bin_header.rangInc == AHMincrNoGrid) // rang increment (add/multiply/log) ) && (FieldIndexInSequence(RegionSequence(), AHMF_RESPVECT) > -1) ); } inline bool AuAHMF::ExistTrackData() const { return (FieldIndexInSequence(RegionSequence(), AHMF_TRAKDATA) > -1); } inline bool AuAHMF::ExistTrackErrData() const { return (FieldIndexInSequence(RegionSequence(), AHMF_TRAKDERR) > -1); } inline bool AuAHMF::ExistSinkVectors() const { return (bin_header.sinkCnt > 0) && ((FieldIndexInSequence(RegionSequence(), AHMF_SINKVECT) > -1) || (FieldIndexInSequence(BonusDataSequence(), AHMF_SINKVECT) > -1)); } inline bool AuAHMF::ExistSinkBearings() const { return (bin_header.sinkCnt > 0) && (FieldIndexInSequence(BonusDataSequence(), AHMF_SINKVECTBRG) > -1); } inline bool AuAHMF::ExistSinkLabels() const { return (bin_header.sinkCnt > 0) && ((FieldIndexInSequence(RegionSequence(), AHMF_SINKLABEL) > -1) || (FieldIndexInSequence(BonusDataSequence(), AHMF_SINKLABEL) > -1)); } // list of channel for each sink inline bool AuAHMF::ExistSinkChannelMap() const { return (bin_header.sinkCnt > 0) && ((FieldIndexInSequence(RegionSequence(), AHMF_SINKCHNLMAP) > -1) || (FieldIndexInSequence(BonusDataSequence(), AHMF_SINKCHNLMAP) > -1)); } // table of triples connecting sinks/virtual nodes inline bool AuAHMF::ExistSinkTriangles() const { return (bin_header.triaCnt > 0) && ((FieldIndexInSequence(RegionSequence(), AHMF_SINKTRIANGLES) > -1) || (FieldIndexInSequence(BonusDataSequence(), AHMF_SINKTRIANGLES) > -1)); } // an EQ/normalization weighting filter of WeightingTaps() tap length inline bool AuAHMF::ExistWeighting() const { return (bin_header.optmTps > 0) && ((FieldIndexInSequence(RegionSequence(), AHMF_WEIGHTING) > -1) || (FieldIndexInSequence(BonusDataSequence(), AHMF_WEIGHTING) > -1)); } // Class: AuAHMF // Method: ahm_1_43_type() (formerly ahm_1_43_type()) // Used to check if it is an 1.43 type AHM file // --------------------------------- inline bool AuAHMF::IsAHM_1_43_RspSeq() const { ah_sequence_field rseq = { { AHMF_RESP, AHMF_TIME, AHMF_LEVL, 0, 0, 0, 0 }, AHMF_INTERSECT }; AuSeqField respSeq(rseq); if (ResponseSequence() == respSeq) return true; return false; } // Class: AuAHMF // Method: IsSectionVersion() // --------------------------------- inline bool AuAHMF::IsSectionVersion() const { // sectioned AHM's are v1.5+ if (bin_header.fileTyp == AFMfileAHM) return (Version() >= 1.5f); // sectioned AFM's and EQF's are v1.2+ return (Version() >= 1.2f); } // Class: AuAHMF // Method: IsSectionVersion() // --------------------------------- inline bool AuAHMF::IsStrictSections() const { // do not tolerate deprecated coefSeq if (!bin_header.coefSeq.fld[0] || !bin_header.coefSeq.flg) return false; // do not tolerate FIR's specifed in respTps // even very long FIR's must be sectioned if ( (bin_header.respTps > 1) && (bin_header.rtapPls == 0) && ( (bin_header.rtapZrs == 0) || (bin_header.rtapZrs == 1) ) ) return false; return true; } // Class: AuAHMF // Method: LatestVersion() // --------------------------------- // returns most current version, based on filetype inline float AuAHMF::LatestVersion() const { switch (bin_header.fileTyp) { case AFMfileAHM: return float(AHM_VERSION); case AFMfileAFM: return float(AFM_VERSION); case AFMfileEQF: return float(EQF_VERSION); } return float(AHM_VERSION); } inline double AuAHMF::AnglInAHMUnits(double angl, int units/*=AHManglRadians*/) const { return angl*AnglConversionFactor(units); } inline double AuAHMF::DistInAHMUnits(double dist, int units/*=AHMdistMeters*/) const { return dist*DistConversionFactor(units); } inline double AuAHMF::TimeInAHMUnits(double tval, int units/*=AHMtimeSeconds*/) const { return tval*TimeConversionFactor(units); } // ========================================================================== // ===================== INLINE PRIVATE METHOD IMPLEMENTATION: AuAHMF // ========================================================================== // Class: AuAHMF // Method: delete_header() // ------------------------ // Frees up the memory allocated to hold the ascii header. // inline void AuAHMF::delete_asc_header() { if (p_asc_header) { delete p_asc_header; p_asc_header = 0; } } // Class: AuAHMF // Method: delete_data_buffer() // ------------------------ // Frees up the memory allocated to hold the data. // inline void AuAHMF::delete_data_buffer() { if (p_data_buffer || l_data_bufsiz) { delete p_data_buffer; p_data_buffer = 0; l_data_bufsiz = 0; } } // Class: AuAHMF // Method: valid_seq_fld_idx(index) // ------------------------- // Returns TRUE if index is less than the maximum allowed seqfield. // inline bool AuAHMF::valid_seq_fld_idx(int idx) { return ((unsigned)idx < AHMF_MAX_SEQFIELD); } // Class: AuAHMF // Method: seq_fld(index) // ------------------------- // Returns field as indexed from the given sequence // inline int AuAHMF::seq_fld(int idx, const ah_sequence_field &sf) { if (valid_seq_fld_idx(idx)) return sf.fld[idx]; return ((idx==AHMF_MAX_SEQFIELD) ? sf.flg : 0); } // Class: AuAHMF // Method: get_fld_in_seq(seq,type) // ------------------------------ // Returns the existence of the field in sequence. // related to higher level FieldIndexInSequence() method // inline bool AuAHMF::exist_fld_in_seq(const ah_sequence_field &sf, int type) { return get_fld_in_seq(sf,type) >= 0; } // Class: AuAHMF // Method: set_op(type) // ------------------------ // Change the operation for interval increment. inline bool AuAHMF::set_ushrt(unsigned short &fld, int val) { if ((unsigned long)val > 0x0FFFF) return false; fld = (unsigned short)val; return true; } // Class: AuAHMF // Method: set_op(type) // ------------------------ // Change the operation for interval increment. inline bool AuAHMF::set_op(unsigned char &fld, int op) { switch (op) { case AHMincrAdd: case AHMincrMult: case AHMincrTangent: // converts angular to linear coordinates case AHMincrLogN: case AHMincrLog2: case AHMincrLog10: fld = op; return true; } return false; } // Class: AuAHMF // Method: set_rsrc(type) // ------------------------ inline bool AuAHMF::set_rsrc(unsigned char &fld, int type) // see AHMrespSource enum { if ( (type < AHMrespNone) || (type >= AHMrespSourceLast) ) return false; fld = (unsigned char)type; return true; } // Class: AuAHMF // Method: set_bits(fld, typ, bts) // ------------------------ // Change the operation for interval increment. inline bool AuAHMF::set_bits(unsigned char &fld, int typ, int bts) { if ( (bts < 8) || (bts > 64) ) return false; if ( (typ != AHMdataInteger) && (typ != AHMdataFloat) ) return false; if ( (typ == AHMdataFloat) && (bts != 32) && (bts != 64) ) return false; unsigned char *data_type = &bin_header.coefDat; int index = int(&fld - &bin_header.coefSiz); if (index > 3) return false; fld = bts; data_type[index] = typ; return true; } // Class: AuAHMF // Method: set_sqfld(seq, fld, typ) // ------------------------ // Set field in a sequence. inline bool AuAHMF::set_sqfld(ah_sequence_field &seq, int idx, int type) { if ((unsigned)type >= 128) return false; if (valid_seq_fld_idx(idx)) { seq.fld[idx] = (unsigned char)type; return true; } if (idx==AHMF_MAX_SEQFIELD) { seq.flg = (unsigned char)type; return true; } return false; } // Methods that return array sizes. // Class: AuAHMF // total_grid_locations() // ------------------------ inline size_t AuAHMF::total_grid_locations() const { return (bin_header.azimRsp * bin_header.elevRsp * bin_header.rangRsp); } // Class: AuAHMF // respsize() // ------------------------ inline size_t AuAHMF::respsize() const { size_t base_size = this->total_grid_locations() * bin_header.sinkCnt; return base_size * (bin_header.respCmp ? bin_header.respCmp : CoefsPerFunc() ); } // Class: AuAHMF // timesize() // ------------------------ inline size_t AuAHMF::timesize() const { size_t timesize = ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_IATD) > -1) ? this->total_grid_locations() : 0); timesize += ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_LATD) > -1) ? this->total_grid_locations() : 0); timesize += ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_RATD) > -1) ? this->total_grid_locations() : 0); timesize += ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_TIME) > -1) ? this->total_grid_locations() * bin_header.sinkCnt : 0); return timesize; } // Class: AuAHMF // levlsize() // ------------------------ inline size_t AuAHMF::levlsize() const { size_t levlsize = ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_IALD) > -1) ? this->total_grid_locations() : 0); levlsize += ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_LALO) > -1) ? this->total_grid_locations() : 0); levlsize += ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_RALO) > -1) ? this->total_grid_locations() : 0); levlsize += ((this->FieldIndexInSequence(bin_header.respSeq,AHMF_LEVL) > -1) ? this->total_grid_locations() * bin_header.sinkCnt : 0); return levlsize; } // Class: AuAHMF // compsize() // ------------------------ inline size_t AuAHMF::compsize() const { return bin_header.respCmp * ExistBasisFuncs() * CoefsPerFunc(); } // Class: AuAHMF // mapgsize() // ------------------------ inline size_t AuAHMF::mapgsize() const { return ( this->respsize() + this->levlsize() + this->timesize() ); } // ========================================================================== // ===================== INLINE PUBLIC METHOD IMPLEMENTATION: AuSeqField // ========================================================================== inline AuSeqField::AuSeqField() { fld[0] = fld[1] = fld[2] = fld[3] = fld[4] = fld[5] = fld[6] = flg = 0; } inline void AuSeqField::Set(const char flag, const char f0, const char f1, const char f2, const char f3, const char f4, const char f5, const char f6) { fld[0] = f0; fld[1] = f1; fld[2] = f2; fld[3] = f3; fld[4] = f4; fld[5] = f5; fld[6] = f6; flg = flag; } inline AuSeqField::AuSeqField(const AuSeqField &sf) { *this = sf; } inline AuSeqField & AuSeqField::operator=(const AuSeqField &sf) { *this = static_cast(sf); return *this; } inline AuSeqField::AuSeqField(const ah_sequence_field &sf) { fld[0] = sf.fld[0]; fld[1] = sf.fld[1]; fld[2] = sf.fld[2]; fld[3] = sf.fld[3]; fld[4] = sf.fld[4]; fld[5] = sf.fld[5]; fld[6] = sf.fld[6]; flg = sf.flg; } inline AuSeqField & AuSeqField::operator=(const ah_sequence_field &sf) { fld[0] = sf.fld[0]; fld[1] = sf.fld[1]; fld[2] = sf.fld[2]; fld[3] = sf.fld[3]; fld[4] = sf.fld[4]; fld[5] = sf.fld[5]; fld[6] = sf.fld[6]; flg = sf.flg; return *this; } inline bool AuSeqField::operator==(const AuSeqField &sf) { return ( (fld[0] == sf.fld[0]) && (fld[1] == sf.fld[1]) && (fld[2] == sf.fld[2]) && (fld[3] == sf.fld[3]) && (fld[4] == sf.fld[4]) && (fld[5] == sf.fld[5]) && (fld[6] == sf.fld[6]) && (flg == sf.flg) ); } inline bool AuSeqField::operator==(const ah_sequence_field &sf) { return ( (fld[0] == sf.fld[0]) && (fld[1] == sf.fld[1]) && (fld[2] == sf.fld[2]) && (fld[3] == sf.fld[3]) && (fld[4] == sf.fld[4]) && (fld[5] == sf.fld[5]) && (fld[6] == sf.fld[6]) && (flg == sf.flg) ); } // if either field is zero, than they may still be consistent inline bool AuSeqField::IsConsistent(const AuSeqField &sf) { return ( (fld[0] == sf.fld[0]) && ((fld[1] == sf.fld[1]) || !fld[1] || !sf.fld[1]) && ((fld[2] == sf.fld[2]) || !fld[2] || !sf.fld[2]) && ((fld[3] == sf.fld[3]) || !fld[3] || !sf.fld[3]) && ((fld[4] == sf.fld[4]) || !fld[4] || !sf.fld[4]) && ((fld[5] == sf.fld[5]) || !fld[5] || !sf.fld[5]) && ((fld[6] == sf.fld[6]) || !fld[6] || !sf.fld[6]) && ((flg == sf.flg) || !fld[1] || !sf.fld[1]) ); } // if either field is zero, than they may still be consistent inline bool AuSeqField::IsConsistent(const ah_sequence_field &sf) { return ( (fld[0] == sf.fld[0]) && ((fld[1] == sf.fld[1]) || !fld[1] || !sf.fld[1]) && ((fld[2] == sf.fld[2]) || !fld[2] || !sf.fld[2]) && ((fld[3] == sf.fld[3]) || !fld[3] || !sf.fld[3]) && ((fld[4] == sf.fld[4]) || !fld[4] || !sf.fld[4]) && ((fld[5] == sf.fld[5]) || !fld[5] || !sf.fld[5]) && ((fld[6] == sf.fld[6]) || !fld[6] || !sf.fld[6]) && ((flg == sf.flg) || !fld[1] || !sf.fld[1]) ); } #endif // AuCORE_AHMF_H