/* ==================================================================== * AuCoreAHMhdr.h * Version: 0.500 * ==================================================================== */ #ifndef Au_AHM_HDR_H #define Au_AHM_HDR_H /* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * AuCoreAHMHDR is the AHM format header definition * * The structs and enums defined in this file are used * in the AuCoreAHM, AuCoreAHMF and AuCoreAHMIO classes. * Structs and enums defined: * struct aAHMF_th * struct aAHMF_bh * enum AHMwindowType * enum AHMdisplayEQType * struct ah_sequence_field * struct aAHMF_ASCIIh * struct ah_spec_bits * struct AH14_HDR_FMT * struct AH13_HDR_FMT * struct AH12_HDR_FMT * * ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ * 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) * Elizabeth J. Purswell (EJP) * Agnieszka Roginska (ARO) * -------------------------------------------------------------------- * Modification log: * 22Sep10 WLC 0.500 EQF 1.2, AHM 1.5, AFM 1.2 * 24Sep08 WLC 0.440 EQF 1.1 * 08Aug07 WLC 0.431 Reset of file version * 19Dec00 WLC 0.301 Completed redesign * 17Dec00 WLC 0.300 Redesigned for v1.410, made public * 05Dec00 ARO 0.200 Revamped for v1.4 * 14Sep99 EJP 0.101 Some commenting added. * 04Jan98 WlC 0.100 Created. * -------------------------------------------------------------------- * Keywords: Acoustic Head Map, file format, filter, HRTF * ==================================================================== */ #define AHM_VERSION 1.50 #define EQF_VERSION 1.20 #define AFM_VERSION 1.20 /* Notes: EQF v1.1 supports absolute compensation, relative compensation, band-pass filters, and the combination of absolute comp and band-pass. This version also supports the inclusion of SINKVECT and SINKLABEL within EQF files. AHM v1.44 now supports SINKVECT and SINKLABEL within AHM files. */ /* -------------------------------------------------------------------- The AHM format consists of 4 parts: * (1) an ASCII "title header" (required) this part is the only mandatory human readable section it does not normally contain detailed data, but does contain basic archiving information. The comment section may contain any data in ASCII format. * (2) a "binary header" (required) this part describes the dataset in an exhaustive detail if the dataset contains data that should be special interpretation not supported by the binary data structure, then the binary header directs the loader to alert the operator to read the comment within the title header. * (3) an ASCII "header extension" (optional) This section is normally used to provide an additional comment of any length. The existence of this section is indicated by a non-zero entry in the "thisMap" offset field of the binary header. "thisMap" defines the number of bytes between the last byte of the binary header and the first byte of the dataset. NOTE: Some contributors to the format specification requested that a completely human readable format option be supported. If Ctrl-Z is missing from the title header AND this ASCII header extension provides the complete description for interpreting the dataset, then the binary header part may be omitted. * (4) the data (required) the data always immediately follows the last byte of the binary header plus the "thisMap" offset. The format supports the creation of libraries of datasets with a common identifier. For such datasets, part (1), the title header, is present only at the beginning of the file; parts (2), (3), & (4) may be repeated as many times as needed. In such multi-dataset instances, the "nextMap" and "prevMap" fields for all binary headers must specify the non-zero offset from the byte after the end of the current binary header. All offsets are positive number of bytes. The usefulness of multi-datasets may include different filter types such as FIR, ARMA, and PCA; different samplerates, or different optimization lengths. --------------------------------------------------------------------- */ /* NOTE --------------------------------------------------------------- * All multi-byte datatypes are little-endian: * Little-endian means that the least significant byte of a field * comes first, followed up with more significant bytes until * finally reaching the most significant byte. * Thus if the unsigned long integer 0x9A78BC56 is in an AHM file, * the bytes would be read-in in the following order: * 0x56, 0xBC, 0x78, 0x9A * The little-endian rule is true for header and data. * -------------------------------------------------------------------- */ // utility macros #define ver_num2str(numver) "v" #numver #define ver_mac2str(macver) ver_num2str(macver) #define AHM_VER_STR "AH" ver_mac2str(AHM_VERSION) #define EQF_VER_STR "EQ" ver_mac2str(EQF_VERSION) #define AFM_VER_STR "AF" ver_mac2str(AFM_VERSION) /* -------------------------------------------------------------------- * Current AHM Structures -------------------------------------------- * -------------------------------------------------------------------- */ /* Acoustic Head Map Format Header-Title structure -------------------- * is common between both BINARY and ASCII forms * If "ctrlZtm"==^Z, then header is BINARY. */ #define AHMFHT_SIZ 192 /* header title section size */ #define VERSTR_SIZ 8 #define HIDSTR_SIZ 32 #define CMTSTR_SIZ 140 /* two lines of text */ #define TRESRV_OFS (VERSTR_SIZ+HIDSTR_SIZ+CMTSTR_SIZ+1) #define TRESRV_SIZ (AHMFHT_SIZ-TRESRV_OFS) /* 12 bytes of padding */ #define AFMF_SINKLABELSTR_SIZ 32 #define _CTRL_Z 0x1A /* ASCII header All AHM/EQF/AFM formats use this ASCII header structure, except v1.3 See AH13_HDR_FMT below. The fixed-sized v1.3 header is entirely ASCII. The interpretation of the first 40 bytes is exactly the same for all AHMs. */ struct aAHMF_th { char version[VERSTR_SIZ], head_id[HIDSTR_SIZ]; char comment[CMTSTR_SIZ], ctrlZtm, rsrvCh1[TRESRV_SIZ]; }; typedef struct aAHMF_th aAHMF_ht; // legacy name, do not use /* Acoustic Head Map Format BINARY Header structure ------------------- * aliased to the current version of the format */ typedef struct AH14_HDR_FMT aAHMF_bh; /* Sequence fields structure ----------------------------------------- * define the order for sections, subsections, & components * the structure consists of an array of enumerated values * each relating to a field to be ordered * followed by a format flag, which modifies the ordering. */ #define AHMF_MAX_SEQFIELD 7 struct ah_sequence_field { unsigned char fld[AHMF_MAX_SEQFIELD]; unsigned char flg; }; /* AHMF v1.4xx & v1.5xx use identical structures contain 208 bytes and elimates the bit-field (see AH12_HDR_FMT at bottom) */ struct AH14_HDR_FMT { unsigned long // 12 fields of 4 bytes each (48 bytes) // offsets are relative to first byte after header, // which is where the file pointer is pointing after sucking header. bhdrSiz, // size in bytes of this binary header structure (208 bytes) thisMap, // offset for this map (0 default), indicates comment nextMap, // offset next map (0 default) prevMap, // offset previous map (0 default) lotmDat, // low-dword of UTC time/date code, must be 64-bit boundary hitmDat, // high-dword contains epoch of lotmDat seconds count totlSiz, // total bytes in file, including header for verification totlRsp, // total responses stored (including caps) respTps, // response taps (for pure FIR) or total number of sections, see note rsrvLng[3]; float // 8 fields of 4 bytes each (32 bytes) smplRat, // sample rate in Hertz headSiz, // interaural distance in range units fixpCvt, // fixed point coefficient conversion value. bassFrq, // bass extension low-pass cut-off frequency spdoSnd, // speed of sound at which measurements were taken, 0.0 = 343 m/sec trebFrq, // treble extension high-pass cut-off frequency cutoSlp, // slope of frequency cut-offs; 0 = 12 dB/Octave rsrvFlt[1]; unsigned short // 12 fields of 2 bytes each (24 bytes) azimRsp, // grid azimuth responses elevRsp, // grid elevation responses rangRsp, // grid range responses rtapZrs, // response tap zero coefficients (zeros per tap) rtapPls, // response tap pole coefficients (poles per tap) respCmp, // response components (number of weights if PCA) optmTps, // compression optimization size (or weighting function length) sinkCnt, // number of sinks per transfer function (legacy 0==2) virtNod, // number of virtual nodes in vector triaCnt, // triangle count for triangulation of sinks and virtual nodes rsrvSht[2]; unsigned char // 32 fields of 1 bytes each (32 bytes) coefDat, // coefficient type (integer/float), see AHMdataType enum iatdDat, // time delay type (integer/float), see AHMdataType enum wghtDat, // component weight type (integer/float), see AHMdataType enum nlvlDat, // normalization level type (integer/float) coefSiz, // bits per coefficient iatdSiz, // bits per delay wghtSiz, // bits per weight nlvlSiz, // bits per normalization level distFmt, // dist units (inches/feet/cm/meters), see AHMscaleUnits enum anglFmt, // angular units (rads/degs/grads), see AHMscaleUnits enum timeFmt, // time units (sample/secs/millisecs), see AHMscaleUnits enum nlvlFmt, // level units (linear/decibel), see AHMscaleUnits enum azimInc, // azim increment (add/multiply/log), see AHMincrOperation enum elevInc, // elev increment (add/multiply/log), see AHMincrOperation enum rangInc, // rang increment (add/multiply/log), see AHMincrOperation enum rsrvInc[1], // spare axisCfg, // axis order and type (cart/cyl/sphr), see AHMaxesConfig wndoTyp, // filter window type, see AHMwindowType enum dseqTyp, // display equalization type, see AHMdisplayEQType enum fdeqTyp, // field equalization method, see AHMfieldEQType enum crptTyp, // encryption type, see AHMencryptType enum enhcMtd, // enhancement method (bass-extension), see AHMenhanceMethod OR bits trakDev, // Head Tracking device see AHMtrackingDevice enum nrmlTyp, // normalization type (peak/RMS), see AHMnormalizationType enum leftSrc, // left response (none/sampled/mirrored), see AHMrespSource enum rghtSrc, // right response (none/sampled/mirrored), see AHMrespSource enum NcapSrc, // north polarcap (none/sampled/infered), see AHMrespSource enum ScapSrc, // south polarcap (none/sampled/infered), see AHMrespSource enum readCmt, // specialized map boolean fileTyp, // AHM, EQF, AFM, see AFMfileType enum lveqTyp, // level equalization method, see AHMlevelEQType enum rsrvChr[1]; ah_sequence_field // 6 fields of 8 bytes each (48 bytes) coefSeq, // order of coefs/sections/section groups: zero, pole, cascade, parallel vectSeq, // order of vector: azim, elev, rang respSeq, // order of resps: resp, time, level regnSeq, // order of regions: mapgrid, northcap, southcap bnsdSeq, // order of bonusdata: weighting, sinkvect, sinklabel, sinktriangles rsrvSeq[1]; float // 6 fields of 4 bytes each (24 bytes) azimOrg, // primary axis, see AHMaxisConfig elevOrg, // secondary axis rangOrg, // tertiary axis azimInt, elevInt, rangInt; }; /* NOTE --------------------------------------------------------------- * Explanation of respTps, rtapZrs, rtapPls: * respTps, rtapZrs, rtapPls can easily be confused. * The file format always refers to number of coefficients, not poly order. * Unity coefficients must be explicitly stated. * Coefficients may be zero-padded and it is up to the loader to optimize the filters. * The total number of coefficients per function is IN ALL CASES * respTps * ( rtapZrs + rtapPls ) * Condition: respTps == Response Taps * Only valid for FIR filters. * Only valid for when rtapPls == 0, and rtapZrs == 1. * Older formats may have rtapZrs == 0, but this is promoted to 1. * coefSeq is ignored. * This condition is supported for 1) legacy, and 2) very long FIR filters. * Condition: respTps == Number of Sections * Valid for any filter. * Only valid for when either rtapPls > 0 or rtapZrs > 1. * If coefSeq.flg == 0, then all sections are in one cascade, * zero coefs precede zero coefs within a section, * and all coefSeq.fld are ignored. * If coefSeq.flg > 0, then coefSeq dictates how multiple sections are configured. * -------------------------------------------------------------------- */ /* NOTE --------------------------------------------------------------- * Explanation of Epoch storage in hitmDat: * high word contains the year AD of epoch * low word contains the number of hours into the epoch year * at which time the lotmDat would register zero seconds * -------------------------------------------------------------------- */ /* NOTE --------------------------------------------------------------- * Explanation of PCA or Palette representation: * For PCA, respCmp is non-zero and the left and right regions * represent weight vectors. A non-zero respCmp defines * both the number of Singular-Value-Decomposition components * as well as the number of weights in each PCA vector. * rspsTps, rtapZrs, rtapPls then describe the component filters. * The component filters, otherwise known as BASIS FUNCTIONS * are defined as independent regions. * The component filters will never be encrypted. * -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- * Type Enumerations ------------------------------------------------- * -------------------------------------------------------------------- */ /* AFMfileType enumeration - defines type of filters within file ------ */ enum AFMfileType { AFMfileAHM, // map of HRTF or SRTF filters AFMfileEQF, // v1.0 EQF file, interpreted as AFMfileEQFREL AFMfileAFM, // generic filter map AFMfileEQFREL, // v1.1 EQF file with relative compensation filter AFMfileEQFABS, // v1.1 EQF file with absolute compensation filter AFMfileEQFBPS, // v1.1 EQF file with band-pass filter AFMfileEQFCXO, // v1.1 EQF file with compensation and X-over band-pass filter AFMfileLast // end of enumeration }; /* AFMfileType notes: For all EQF v1.1 types, Response Sequence must be correct! AFMfileEQFREL - equivalent in use to original EQF file specifies compensation for relative position from each sink smooth compensation filter is in the first filter position raw compensation filter is in the second filter position raw data is in subsequent filter positions requires rangOrg to designate calibration position AFMfileEQFABS - loudspeaker compensation to absolute point specifies compensation at one absolute position from each sink smooth compensation filter is in the first filter position raw compensation filter is in the second filter position raw data is in subsequent filter positions requires to designate calibration position AFMfileEQFABS should include SINKVECT region for absolute sink positions AFMfileEQFBPS - band-pass filter typically used for loudspeaker cross-overs one sink may be a low-pass filter for a woofer another sink may be a high-pass filter for a tweeter band-pass filter is in first filter position design criteria is specified as first four coefficients in the second position AFMfileEQFCXO - loudspeaker compensation convolved with cross-over band-pass filterset smooth compensation filter is in the first filter position raw compensation filter is in the second filter position design criteria is specified as first four coefficients in the third position AFMfileEQFCXO should include SINKVECT region for absolute sink positions */ /* AHMdistUnits enumeration - defines geometric configuration -------- */ /* please note that these are identical to the ATRON.H enum */ enum AHMscaleUnits { AHMdistDefault = 0x00, AHMdistInches = AHMdistDefault, AHMdistFeet, AHMdistMMeters, AHMdistCMeters, AHMdistMeters, AHMdistUnitsLast, AHMdistSpecUnits, AHManglDefault = 0x10, AHManglRadians = AHManglDefault, AHManglDegrees, AHManglGradians, AHManglUnitsLast, AHManglSpecUnits, AHMtimeDefault = 0x20, AHMtimeSamples = AHMtimeDefault, AHMtimeSeconds, AHMtimeMSecs, AHMtimeUSecs, AHMtimeUnitsLast, AHMtimeSpecUnits, AHMlevelDefault = 0x30, AHMlevelLinear = AHMlevelDefault, AHMlevelDecibels, AHMlevelUnitsLast, AHMscaleUnitsLast = AHMlevelUnitsLast, AHMlevelSpecUnits }; /* AHMdataType enumeration - defines geometric configuration -------- */ enum AHMdataType { AHMdataTypeNone, AHMdataInteger, // all integers are signed, must be at least 8-bits AHMdataFloat, // all floats must be 32 or 64 bits AHMdataTypeLast }; /* AHMincrOperation enumeration - defines geometric configuration -------- */ /* typically used to describe non-linear densities */ enum AHMincrOperation { AHMincrNone, AHMincrAdd, AHMincrMult, AHMincrTangent, // converts angular to linear coordinates AHMincrLogN, AHMincrLog2, AHMincrLog10, AHMincrNoGrid, // must have RESPVECT region to specify locations AHMincrOpLast }; /* AHMaxesConfig enumeration - defines geometric configuration -------- */ enum AHMaxesConfig { AHMaxesConfigNone, AHMaxesDefault=4, // corrects for an early default error, equates to Spherical_ZYR // for spherical: first axis = azim, second axis = elev AHMaxesSpherical_ZYR=1, // CRE/UWMadison default AHMaxesSpherical_YXR=2, // UCDavis default (this should be YZR) AHMaxesSpherical_YZR=2, // UCDavis default (same rotations as type 9) AHMaxesSpherical_XZR=3, // for cylindrical: first axis = azim, height = elev AHMaxesCylindrical_ZHR=8, AHMaxesCylindrical_YHR=5, AHMaxesCylindrical_XHR=6, // for cartesian: azim = Y, elev = Z, rang = X AHMaxesCartesian_YZX=7, AHMaxesSpherical_RYZ=9, // special format with range first, elevation second, azimuth last AHMaxesNextConfig=10, // placeholder AHMaxesConfigLast = AHMaxesNextConfig }; /* AHMwindowType enumeration - defines filter derivation -------------- */ enum AHMwindowType { AHMwndoNone, AHMwndoBoxCar, AHMwndoBartlett, AHMwndoHamming, AHMwndoHanning, AHMwndoKaiser, AHMwndoGausian, AHMwndoLast }; /* AHMdisplayEQType enumeration - defines embedded display EQ --------- */ enum AHMdisplayEQType { AHMdseqNone, AHMdseqHeadPhones, AHMdseqNearPhones, AHMdseqFrontPhones, AHMdseqRearPhones, AHMdseqSennheiserHD250, AHMdseqSennheiserHD540, AHMdseqSennheiserHD560, AHMdseqSennheiserHD580, AHMdseqSennheiserHD570, AHMdseqSennheiserHD500, AHMdseqSennheiserEH2200, AHMdseqCustom, AHMdseqLast }; /* AHMfieldEQType enumeration - defines any full-field EQ ------------- */ enum AHMfieldEQType { AHMfdeqNone, AHMfdeqDiffuse, AHMfdeqFree, AHMfdeqLast }; /* AHMlevelEQType enumeration - defines method detecting levels for equalization ------------- */ enum AHMlevelEQType { AHMlveqNone, AHMlveqGolay, AHMlveqSine1K, AHMlveqMultiTone, AHMlveqWhite, AHMlveqPink, AHMlveqSwept, /* sine-sweep, assumed full-spectrum */ AHMlveqLast, AHMlveqContinuous = 32, /* longer than a burst; OR with other types */ AHMlveqWeighted = 64, /* OR with other types, look for weighting filter */ AHMlveqDistributed = 128 /* OR with other types */ }; /* AHMencryptType enumeration - defines encryption method ------------- */ enum AHMencryptType { AHMcryptNone, AHMcryptCRE, AHMcryptAuSIM1, AHMcryptLast }; /* AHMnormalizationType enumeration - defines normalization method ------------- */ enum AHMnormalizationType { AHMnlvlNone, AHMnlvlPeak, AHMnlvlRMS, AHMnlvlLast }; /* AHMrespSource enumeration - defines source of polar-cap data --- */ enum AHMrespSource { AHMrespNone, AHMrespSampled, AHMrespTimeInterpol, AHMrespFreqInterpol, AHMrespModeled, AHMrespMirrored, // valid for one of left or right AHMrespGeoCorrected, // corrected for geometric errors AHMrespSourceLast }; /* AHMtrackingDevice enumeration - defines head tracking device --- */ enum AHMtrackingDevice { AHMtrakNone, AHMtrakFastrak, AHMtrakIsotrak, AHMtrakIC2, AHMtrakICube, // any ISense IC, IC2, IC3, IC2+ AHMtrakLiberty, // any Liberty or Liberty LATUS AHMtrakPatriot, // Patriot or Minuteman AHMtrakFreespace, // any Freespace 3DOF AHMtrakUSDigital, // any encoder AHMtrakLast }; /* AHMenhanceMethod OR bits - define filter enhancement methods ------- */ #define AHM_ENH_None 0x00 #define AHM_ENH_BassExt 0x01 // see bassFrq for cut-off frequency #define AHM_ENH_CritBand 0x02 #define AHM_ENH_LowModel 0x04 // low-freq model #define AHM_ENH_LowPass 0x08 #define AHM_ENH_HighPass 0x10 #define AHM_ENH_BandPass 0x18 // low and high pass together /* these are constants for the format struct fields (ah_sequence_field) * each has seven ordered sequence fields and a flag field * Response format constants: */ /* Coef/Section format constants: */ #define AHMF_ZEROPOLE 0x00 // flag: zero coefficients precede pole coefs #define AHMF_POLEZERO 0x80 // flag: pole coefficients precede zero coefs #define AHMF_CASCADE_FIRST 0x00 // flag: cascade N sections #define AHMF_PARALLEL_FIRST 0x40 // flag: parallel N sections first /* coefSeq - definition If flag is zero, then it can be interpretted as prior to v1.50 format. However, all filters prior to v1.50 contained only zero coefficients. The low-nibble of the flag is a multiplier for N sections of each type. The high-nibble determines 1) the order of zeros vs. poles within a section. 2) the order of cascades vs. parallels in the sequencing of sections. The values of the fields are the number of sections in parallel or being cascaded. The total number of sections (respTps) must equal PRODUCT( [low-nibble of coefSeq.flg], [each non-zero coefSeq.fld] ) */ /* Note: all coefSeq fields and flags defined prior to AHM v1.5 (May 2010) are deprecated */ #define AHMF_ZERO_dep 0x1 // deprecated zero coefficient #define AHMF_POLE_dep 0x2 // deprecated pole coefficient #define AHMF_GAIN_dep 0x3 // deprecated gain coefficient #define AHMF_FINITE_dep 0x0 // deprecated flag: coefs are FIR #define AHMF_INFINITE_dep 0x2 // deprecated flag: coefs are IIR (poles and zeros) #define AHMF_CASCADE_dep 0x4 // deprecated flag: sections are in cascade format #define AHMF_BIQUAD_dep 0x8 // deprecated flag: coefs are biquads /* Vector format constants: */ #define AHMF_AZIM 0x1 // azimuth or primary axis #define AHMF_ELEV 0x2 // elevation or secondary axis #define AHMF_RANG 0x3 // range or tertiary axis /* vector sequence specifies the outer-most to inner-most loop */ /* response sequence constants: */ #define AHMF_NULL 0x0 // placeholder #define AHMF_LEFT 0x1 // left response #define AHMF_RGHT 0x2 // right response #define AHMF_LATD 0x3 // left aural time delay #define AHMF_RATD 0x4 // right aural time delay #define AHMF_LALO 0x5 // left aural level offset #define AHMF_RALO 0x6 // right aural level offset #define AHMF_IATD 0x8 // interaural time difference #define AHMF_IALD 0x9 // interaural level difference #define AHMF_RESP 0xA // response (multisink) #define AHMF_TIME 0xB // time delay (multisink) #define AHMF_LEVL 0xC // level offset (multisink) #define EQRS_SCMP 0x10 // EQ smooth compensation #define EQRS_RCMP 0x11 // EQ raw compensation #define EQRS_BPSF 0x12 // EQ band-pass filter #define EQRS_BPSD 0x13 // EQ band-pass design #define EQRS_RAWD 0x14 // EQ raw data used to derive filter #define AHMF_SECTIONED 0x0 // flag: LEFT, RIGHT, IATD, IALD separate sinks groups #define AHMF_INTERLEAV 0x1 // flag: LEFT, RIGHT, IATD, IALD interleaved #define AHMF_RSPINTRLV 0x2 // flag: responses (LEFT,RIGHT) interleaved, time&level separate table, only applies to interaural tables #define AHMF_INTERSECT 0x3 // flag: RESP, TIME, LEVL (interleaved sections) /* Region format constants: */ #define AHMF_MAPG 0x1 // Rectangular map grid #define AHMF_NCAP 0x2 // North cap #define AHMF_SCAP 0x3 // South cap #define AHMF_POLARCAPS 0x4 // North/South caps, see NcapSrc/ScapSrc if exist #define AHMF_BASIS 0x8 // Neutral basis functions #define AHMF_BASISLEFT 0x9 // Left basis functions #define AHMF_BASISRGHT 0xA // Right basis functions #define AHMF_BASISSINK 0xB // Basis functions per sink #define AHMF_TRAKDATA 0x10 // Actual 6DOF tracked location error vectors #define AHMF_TRAKDERR 0x11 // 3DOF tracked location error vectors #define AHMF_RESPVECT 0x20 // Actual response location vectors #define AHMF_noCAPS 0x0 // flag: No caps in file #define AHMF_CAPSwMAP 0x1 // flag: Caps are with section #define AHMF_CAPSxTRA 0x2 // flag: Caps are in own section /* track data are assumed to be 32-bit float sextuple of of difference */ /* Order of Basis Functions must mirror the responses */ /* Responses group all components for each sink together */ /* Thus all components for each sink shall be grouped. */ /* BonusData sequence constants: */ #define AHMF_WEIGHTING 0x0C // Weighting function, if exist, num taps = optmTaps, num pole/zeros same as resp #define AHMF_SINKVECT 0x21 // Actual sink Cartesian positions and deflection from the centerdirection, vectors . #define AHMF_SINKVECTBRG 0x22 // Actual sink Spherical bearings and deflection from the centerdirection, vectors . #define AHMF_SINKBANDFREQ 0x23 // sink band-pass/cross-over frequency pairs in hertz. Must be of type AFMfileEQFBPS or AFMfileEQFCXO #define AHMF_SINKCHNLMAP 0x30 // Sink channel map, allows for sparse sinks, by default 1,2,3... #define AHMF_SINKLABEL 0x31 // Sink labels, fixed-length text fields of AFMF_SINKLABEL_LEN size #define AHMF_SINKTRIANGLES 0x41 // List of 32-bit integer idx triples, each idx represents a sink/virtnode position #define AHMF_CALMICVECT 0x51 // Calibration microphone Cartesian positions and deflection from the centerdirection, vectors . #define AHMF_CALMICWEIGHT 0x52 // Calibration microphone weights. /* Sink positions are assumed to be 32-bit float */ /* All angle and length data must be in header units */ /* Sink Position/Labels: must be (sinkCnt + virtNod) entries */ /* Triangle list length given by triaCnt */ /* Preset preferred sequences and formats */ #define AHMF_NORMAL_SECFMT (AHMF_ZEROPOLE|0x01) #define AHMF_NORMAL_SCTSEQ { { 1, 0, 0, 0, 0, 0, 0 }, AHMF_NORMAL_SECFMT } #define AHMF_NORMAL_COEFMT_dep (AHMF_ZEROPOLE|0x01) #define AHMF_NORMAL_COESEQ_dep { { 1, 0, 0, 0, 0, 0, 0 }, AHMF_NORMAL_COEFMT } #define AHMF_NORMAL_VCTFMT 0 #define AHMF_NORMAL_VCTSEQ { { AHMF_RANG, AHMF_AZIM, AHMF_ELEV, 0, 0, 0, 0 }, AHMF_NORMAL_VCTFMT } /* in preparation for PCA rep and Multiple Sink AHM:s, we have redefined the default to: */ #define AHMF_NORMAL_RSPFMT AHMF_INTERSECT #define AHMF_NORMAL_RSPSEQ { { AHMF_RESP, AHMF_TIME, AHMF_LEVL, 0, 0, 0, 0 }, AHMF_NORMAL_RSPFMT } // #define AHMF_NORMAL_RSPFMT AHMF_INTERLEAV // #define AHMF_NORMAL_RSPSEQ { { AHMF_LEFT, AHMF_LALO, AHMF_LATD, AHMF_RGHT, AHMF_RALO, AHMF_RATD, 0 }, AHMF_NORMAL_RSPFMT } // #define AHMF_NORMAL_RSPFMT AHMF_INTERLEAV // #define AHMF_NORMAL_RSPSEQ { { AHMF_LEFT, AHMF_RGHT, AHMF_LALO, AHMF_RALO, \ // AHMF_LATD, AHMF_RATD, 0 }, AHMF_NORMAL_RSPFMT } // #define AHMF_NORMAL_RSPFMT AHMF_RSPINTRLV // #define AHMF_NORMAL_RSPSEQ { { AHMF_LEFT, AHMF_RGHT, AHMF_LATD, \ // AHMF_RATD, AHMF_LALO, AHMF_RALO, 0 }, AHMF_NORMAL_RSPFMT } // If TRAKDATA, TRAKDERR, RESPVECT are found in RGNSEQ, then they must exist in data. #define AHMF_NORMAL_RGNFMT AHMF_noCAPS #define AHMF_NORMAL_RGNSEQ { { AHMF_MAPG, AHMF_POLARCAPS, AHMF_BASISSINK, 0, 0, 0, 0 }, AHMF_NORMAL_RGNFMT } // If WEIGHTING, SINKVECT, SINKCHNLMAP, SINKLABEL, SINKTRIANGLES are found in BSDSEQ, then they must exist in data. #define AHMF_NORMAL_BSDFMT 0 #define AHMF_NORMAL_BSDSEQ { { 0, 0, 0, 0, 0, 0, 0 }, AHMF_NORMAL_BSDFMT } /* !!!! ---- The ASCII header is not up to date! ---- */ /* The following string differentiates the ASCII header from data. */ /* It must appear as the first string on a line. */ /* All text on the line after it is ignored. */ /* All text following it is interpretted as data, */ /* unless the symbol "!" appears in the first character of a line. */ #define AHMF_ASCII_DATA "AHMDATA" #define AHMF_ASCII_BANG '!' // non-interpreted comment #define AHMF_ASCII_CMNT '*' // concatenated comment /* Acoustic Head Map Format ASCII Header structure (upto 20 lines) */ struct aAHMF_ASCIIh { char *lng4flds, // smplRat, nextMap, prevMap, rsrvLg1 *int4rsps, // totlRsp, azimRsp, elevRsp, rangRsp, *int2taps, // respTps, rtapCfs *flt2flds, // headSiz, fixpCvt, rsrvRl1; *fmt4coef, // coefSeq; *fmt4vctr, // vctrSeq; *fmt4resp, // respSeq; *fmt4regn, // regnSeq; *siz2flds, // coefSiz, iatdSiz; *spc4fld1, // distFmt, anglFmt, realRsp, readCmt *spc4fld2, // NcapSrc, ScapSrc *spc4fld3, // azimInc, elevInc, rangInc *spc4fld4, // wndoTyp *flt3orgs, // azimOrg, elevOrg, rangOrg *flt3ints, // azimInt, elevInt, rangInt *comment ; // concatenates all lines marked by AHMF_ASCII_CMNT }; /* ASCII header print formats */ #define pfmtLng4Flds "SR:%-14ld NM:%-14ld PM:%-14ld \r\n" #define pfmtInt4Rsps "RESP T:%-8d A:%-8d E:%-8d R:%-8d\r\n" #define pfmtInt2Taps "TAPS N:%-8d C:%-8d\r\n" #define pfmtSiz2Flds "SIZE C:%-8d I:%-8d\r\n" #define pfmtSeq4Flds "FMT-%4s: %7s %7s %7s %7s\r\n" #define pfmtSpc4Flds "SPEC: %11s %11s %11s %11s\r\n" #define pfmtFlt2Flds "HS:%-8.4f FC:%-8.4f\r\n" #define pfmtFlt3Orgs "ORIGIN A:%-8.4f E:%-8.4f R:%-8.4f\r\n" #define pfmtFlt3Ints "INTERV A:%-8.4f E:%-8.4f R:%-8.4f\r\n" /* ASCII header scan formats */ #define sfmtLng4Flds "SR:%ld NM:%ld PM:%ld \r\n" #define sfmtInt4Rsps "RESP T:%d A:%d E:%d R:%d\r\n" #define sfmtInt2Taps "TAPS N:%d C:%d\r\n" #define sfmtSiz2Flds "SIZE C:%d I:%d\r\n" #define sfmtSeq4Flds "FMT-%s: %s %s %s %s\r\n" #define sfmtSpc4Flds "SPEC: %s %s %s %s\r\n" #define sfmtFlt2Flds "HS:%f FC:%f\r\n" #define sfmtFlt3Orgs "ORIGIN A:%f E:%f R:%f\r\n" #define sfmtFlt3Ints "INTERV A:%f E:%f R:%f\r\n" /* This is the special Snapshot ENCRYPTED format header * the version MUST BE: AHv1.3 */ struct AH13_HDR_FMT { char magic_number[2]; /* Always 'AH' */ char version[6]; /* Always in the form "v%4.2f" */ char subject[62]; /* Subject's name or initials */ char crlf_1[2]; char copyright[78]; char crlf_2[2]; char date[12]; char time[12]; char sample_rate[12]; char tap_count[12]; /* Number of taps */ char response_count[12]; /* Number of responses */ char crlf_3[12]; char notes[254]; char terminator[2]; /* CTRL-Z followed by a NULL */ }; /* ======================================================================== * * this bit-field structure was used in AHM v1.0, v1.1, and v1.2 * it was created as a highly dense packing for boolean data * in v1.4 the binary header was extended from 128 to 256 bytes * and thus this data was converted to unsigned chars --------------------- */ /* BINARY specification bit fields */ /* these should be necessary for interpreting the data. */ /* Since bit-fields are not portable across CPUs, */ /* the alignment lo-bit is always set, the hi-bit unset. */ struct ah_spec_bits { unsigned algnLow:2; // alignment low bit ALWAYS SET unsigned distFmt:2; // meters/inches unsigned anglFmt:2; // rads/degs/grads unsigned coefFlt:1; // integer/float coefficients unsigned readCmt:1; // specialized map unsigned NcapSrc:2; // none/sampled/infered unsigned ScapSrc:2; // none/sampled/infered unsigned wghtFlt:1; // integer/float component weights unsigned iatdFlt:1; // integer/float time delays unsigned timeFmt:2; // sample/secs/millisecs time delay unsigned azimInc:2; // add/multiply/log unsigned elevInc:2; // add/multiply/log unsigned rangInc:2; // add/multiply/log unsigned crptMap:1; // encryption off/on unsigned bassBst:1; // Bass-boosting unsigned rsrvBt1:6; // reserved bits -- future use unsigned algnHig:1; // alignment hi bit ALWAYS UNSET }; /* Acoustic Head Map Format v1.2 BINARY Header structure (128 bytes) */ struct AH12_HDR_FMT { unsigned long // 4 bytes each (32 bytes) // offsets are relative to first byte after header, // which is where the file pointer is pointing after sucking header. nextMap, // offset next map (0 default) prevMap, // offset previous map (0 default) thisMap, // offset for this map (0 default), indicates comment totlSiz, // total bytes in file, including header for verification totlRsp, // total responses stored (including caps) rsrvLng[1], lotmDat, // low-dword of UTC time/date code, must be 64-bit boundary hitmDat; // high-dword of UTC time/date code float // 4 bytes each (16 bytes) smplRat, // sample rate in Hertz headSiz, // interaural distance in range units fixpCvt, // fixed point coefficient conversion value. rsrvFlt[1]; unsigned short // 2 bytes each (16 bytes) azimRsp, // grid azimuth responses elevRsp, // grid elevation responses rangRsp, // grid range responses respTps, // response taps (poly order) rtapZrs, // response tap zero coefficients (zeros per tap) rtapPls, // response tap pole coefficients (poles per tap) respCmp, // response components (number of weights if PCA) cmprTps, // compression optimization size rsrvSht[1]; unsigned char // 1 bytes each (16 bytes) coefSiz, // bits per coefficient iatdSiz, // bits per delay wghtSiz, // bits per weight wndoTyp, // see WindowType enum dseqTyp, // display equalization type, see AHMdisplayEQType enum fdeqTyp, // field equalization method, see AHMfieldEQType enum sphrAxs, // spherical axis order, see AHMsphrAxis rsrvChr[9]; ah_sequence_field // 4 bytes each (16 bytes) coefSeq, // order of coefs: zero, pole, gain vectSeq, // order of vector: azim, elev, rang respSeq, // order of resps: left, right, iatd regnSeq; // order of regions: mapgrid, northcap, southcap union { // 4 bytes each ( 8 bytes) ah_spec_bits b; unsigned long codeSpc, rsrvBts; }; float // 4 bytes each (24 bytes) azimOrg, elevOrg, rangOrg, azimInt, elevInt, rangInt; }; #endif // Au_AHM_HDR_H