== Instrument Scratch Memory Map == ==Intricon (former RTI) Circuits== ===Map of Manufacturer's Reserved Space=== ^ ^Bits (Little Endian)^^^^^^^^^^^^^^^^Notes^ ^ ^15^14^13^12^11^10^09^08^07^06^05^04^03^02^01^00| | ^Word1 / MDA 0|Autofit 4 |||| Autofit 3||||Audiogram\\ (top 2-bits, out of 50-bit)||Year Code used in Serial Number (6 bits)\\ Space specified by RTI||||||Clari-D only supports 8-bits| ^Word2 / MDA 1|In Situ\\ (1 bit)|PrescriptionType\\ (4 bits)||||UserVCPos\\ (3 bits)|||Instrument Model Code (8 bits)\\ Space specified by RTI|||||||| | ^Word3 / MDA 2|Autofit 2 |||| Autofit 1||||Serial Number - 1st part (upper 8-bits, out of 24-bit)\\ Space specified by RTI||||||||Clari-D only supports 8-bits| ^Word4 / MDA 3|Serial Number - 2nd part (lower 16-bits, out of 24-bit)\\ Space specified by RTI|||||||||||||||| | ^Word5 / MDA 4|Audiogram\\ (upper 16-bits, out of 50-bit)||||||||||||||||N/A in Intuition2 & Clari-D| ^Word6 / MDA 5|Audiogram\\ (mid 16-bits, out of 50-bit)||||||||||||||||N/A in Intuition2 & Clari-D| ^Word7 / MDA 6|Audiogram\\ (lower 16-bits, out of 50-bit)||||||||||||||||N/A in Intuition2 & Clari-D| ^Word8 / MDA 7|Company code\\ (7 bits) ||||||| Vent Size\\ (5-bits) |||||Tubing Type (OTE)\\ (upper 2-bits, out of 3-bit) ||Has Directional Mic\\ (1-bit)|Tubing Type (OTE)\\ (former BTE Earhook)\\ (lower 1-bit, out of 3-bit)|N/A in Intuition2 & Clari-D| ^Word8 / MDA 7\\ (Sonetik only)| PGM file loaded\\ (16 bits) |||||||||||||||| Sonetik only| ^Word9 / MDA 8|Acclimatization\\ (2-bits)||Dome Size\\ (4-bits)||||Tubing Length\\ (4-bits)||||Has Push Button/\\ Toggle Switch/None\\ (lower 2-bits) ||Has Auto-TCoil\\ (1-bit)|Has TCoil\\ (1-bit)|Has Digital VC\\ (1-bit) |Has External VC\\ (1-bit) |N/A in Intuition2 & Clari-D| ^Word9 / MDA 8\\ (Sonetik only)| Work order number\\ (upper 16-bits, out of 32-bit)||||||||||||||||Sonetik only| ^Word10 / MDA 9| [[ezfit:SoftTouch]] (1 bit) | | | | | | | | | | | |Has Rocker VC\\ (1-bit) |Circuit Compatibility\\ Version\\ (3-bits)|||N/A in Intuition2 & Clari-D| ^Word10 / MDA 9\\ (Sonetik only)| Work order number\\ (lower 16-bits, out of 32-bit)||||||||||||||||Sonetik only| ==OnSemi (formerly Sound Design Technologies/Gennum) Circuits== ===Map of Scratch Memory (128-bit)=== ^ ^ 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6 ^ 7 ^ ^Byte 0 |Serial Number (4 bytes) Bytes 0 - 3 ||||Encryption (16 bytes) Bytes 4 - 19 |||| ^Byte 8 |Encryption Bytes 4 - 19 |||||||| ^Byte 16 |Encryption Bytes 4 - 19 ||||ExternalVC\\ (Foundation/BTE478P) Byte 20|Directional Microphone (Foundation) Byte 21 |Telecoil\\ (Foundation) Byte 22 |UserVC\\ (All Digitals\\ except Nueve) Byte 23 | ^Byte 24 |PrescriptionType\\ (All Digitals except Nueve) Byte 24 | Impulse Protection \\ (Intellio) Byte 25 | Dome Size (4-bits) \\ Tubing Length (4-bits) Byte 26 | Acclimatization (2-bits) \\ Has Push Button/Toggle \\ Switch/None (2-bits) \\ Has Auto-TCoil (1-bit) \\ Has TCoil (1-bit) \\ Has Digital VC (1-bit) Has External VC (1-bit) Byte 27 |Company code (7 bits) \\ Has Directional Mic (1-bit) Byte 28 | Vent Size (5-bits) \\ Tubing Type (OTE) (3-bit) Byte 29 | | | ^Byte 32 | Memory 1 Melody\\ (Intellio) Byte 32 | Memory 2 Melody\\ (Intellio) Byte 33 | Memory 3 Melody\\ (Intellio) Byte 34 | Memory 4 Melody\\ (Intellio) Byte 35 | Melody volume (1-50)\\ (Intellio) Byte 36 | Volume Change Melody\\ (Intellio) Byte 37 | Volume Min/Max Melody\\ (Intellio) Byte 38 | Low Battery Melody\\ (Intellio) Byte 39 | ^Byte 40 | | | | | | | | | ^Byte 48 | | | | | | | | | ^Byte 56 | | | | | | | | | ^Byte 64 | | | | | | | | | ^Byte 72 | | | | | | | | | ^Byte 80 | | | | | | | | | ^Byte 88 | Sonetik - Stored Stock Program Byte 88 | Sonetik - Order Number Bytes 89-92 |||| | | | ^Byte 96 |flag ''isAutofitSaved'' (boolean) Byte 96 |Autofit Mem 1 (integer) Byte 97 |Autofit Mem 2 (integer) Byte 98 |Autofit Mem 3 (integer) Byte 99 |Autofit Mem 4 (integer) Byte 100 |Audiogram\\ (11 bytes: 1 byte for length, 10 bytes for data) Bytes 101 - 111 ||| ^Byte 104 |Audiogram Bytes 101 - 111 |||||||| ^Byte 112 |In Situ Audiogram (11 bytes: 1 byte for length, 10 bytes for data) Bytes 112 - 122 |||||||| ^Byte 120 |In Situ Audiogram (continued) Bytes 112 - 122 |||flag ''isUsingInSituAudiogram'' (boolean) Byte 123 | Manufacturer code Byte 124 | Circuit Compatibility Version Byte 125 | | | ===Methods for Serial Number Storage and Retrieval=== To save the serial number to scratch memory: ScratchData[0] := SerialNum shr 24; ScratchData[1] := (SerialNum shr 16) and 255; ScratchData[2] := (SerialNum shr 8) and 255; ScratchData[3] := SerialNum and 255; To read the serial number from scratch memory (Gennum circuits): SerialNo := (ScratchData[0] shl 24) + (ScratchData[1] shl 16) + (ScratchData[2] shl 8) + ScratchData[3]; Operators ^ shl | bitwise shift left | ^ shr | bitwise shift right | ^ and | bitwise AND | ^ 255 | bitmask of 1111 1111 (i.e. all 8 bits on) | == Instrument Model Code == Instrument Model Code is selected from this table: **Instructions:** Use the lower 8 bits of Word 2 to indicate all of the models. Make each combination of shell size and circuit to be a unique model number. This method works nicely because each model has a set of associated transducer curves. This scheme allows 256 model combinations if we only use the lower 8 bits of word 2, but we could use all 16 bits, if necessary, and not have any practical limitation on the number of models into the future. Starting with ezFIT 4.20, supporting the Ethos circuit, model codes start at 00 for every new circuit. Previous circuits are kept with the original notations, for backwards compatibility. Basically, instruments are uniquely identified by the CircuitID + ProductID + StyleID. See [[ezfit:logic_and_rationale#guaranteeing_unique_circuit_instrument_references|Guaranteeing Unique Circuit Instrument References]] for a more detailed explanation. ==== Circuit ID ==== ===== Circuit IDs for Intricon (former RTI) products ===== ^ Circuit ^ID ^ Description ^ | ci_None | 0 | none | | ci_Unknown | 0 | unknown | | ci_DigitalOne2TestBox | 0 | legacy code | | ci_DigitalOne2ITE | 1 | legacy code | | ci_DigitalOne2CT | 2 | DigitalOne2CT (Change Tones): Intuition 2, Simplex 2P BTE | | ci_DigitalOne4AFC | 5 | DigitalOne4AFC: Clari-D | | ci_DigitalOne4NRPlus | 6 | DigitalOne4NR+: Intuition 4, Clari-D NR, Sparo, TransEar | | ci_Essential | 18 | Essential 150: Simplex 2P+, BTE 478P+, BTE 675DP+ | | ci_Audion4 | 21 | Audion 4: Flx 4 | | ci_Audion6 | 20 | Audion 6: Intuition 6, Flx 6, BTE D6P, BTE 6AD | | ci_Audion8 | 23 | Audion 8: Octane 12 | | ci_Intune | 7 | InTune: Intuition 4AD, Intuition 4+, IRIC 4, Sparo AD | | ci_Spin | 9 | Spin: Intuition 2FC, Sparo 2 | | ci_SpinNR | 16 | SpinNR: Intuition 2+, Intuition 2FC+, Intuition 2ER, Sparo 2ER | | ci_Ethos | 10 | Ethos: Intuition 12, Sparo 12, Flx, Clik | | ci_EthosOvertus | 10 | Overtus (circuit based on Ethos): Cue | | ci_Other | 999 | Other (non-zero) undefined circuit ID | ==== Ordered by Circuit ==== ^Circuit ^ Instrument Model ^ Style ^ Model Code ^ |ci_Unknown | Optitrim | BTE | 00 | |ci_DigitalOne2 | Intuition 2 | BTE | 03 | |ci_DigitalOne2 | Intuition 2 | Full Shell | 04 | |ci_DigitalOne2 | Intuition 2 | ITC | 05 | |ci_DigitalOne2 | Intuition 2 | CIC | 21 | |ci_DigitalOne2 | Intuition 2 | Half Shell | 22 | |ci_DigitalOne2 | Intuition 2 | Mini Canal | 23 | |ci_DigitalOne2 | Intuition 2 | Canal | 24 | |ci_DigitalOne2 | Intuition 2 | Super60 | 25 | |ci_DigitalOne2 | Simplex 2P | BTE | 53 | |ci_DigitalOne4AFC | Clari-D | FSS | 14 | |ci_DigitalOne4AFC | Clari-D | CIC | 15 | |ci_DigitalOne4AFC | Clari-D | Half Shell | 16 | |ci_DigitalOne4AFC | Clari-D | Mini Canal | 17 | |ci_DigitalOne4AFC | Clari-D | Canal | 18 | |ci_DigitalOne4AFC | Clari-D | Super60 | 19 | |ci_DigitalOne4AFC | Clari-D | Mini CIC | 20 | |ci_DigitalOne4NRPlus | Intuition 4 | BTE | 01 | |ci_DigitalOne4NRPlus | Intuition 4D | BTE | 02 | |ci_DigitalOne4NRPlus | Intuition 4 | Full Shell | 06 | |ci_DigitalOne4NRPlus | Intuition 4 | ITC | 07 | |ci_DigitalOne4NRPlus | Intuition 4 | CIC | 08 | |ci_DigitalOne4NRPlus | Intuition 4 | Half Shell | 09 | |ci_DigitalOne4NRPlus | Intuition 4 | Mini Canal | 10 | |ci_DigitalOne4NRPlus | Intuition 4 | Canal | 11 | |ci_DigitalOne4NRPlus | Intuition 4 | Super60 | 12 | |ci_DigitalOne4NRPlus | Intuition 4 | ezHear | 13 | |ci_DigitalOne4NRPlus | Intuition 4 | Mini CIC | 14 | |ci_DigitalOne4NRPlus | Sparo | OTE | 26 | |ci_DigitalOne4NRPlus | TransEar | TransEar | 27 | |ci_DigitalOne4NRPlus | nVe 4 | RIC | 60 | |ci_Ethos | Intuition 8/12 | CIC | 01 | |ci_Ethos | Intuition 8/12 | CIC + Power | 02 | |ci_Ethos | Intuition 8/12 | Mini Canal | 03 | |ci_Ethos | Intuition 8/12 | Mini Canal + Power | 04 | |ci_Ethos | Intuition 8/12 | Canal | 05 | |ci_Ethos | Intuition 8/12 | Canal + Power | 06 | |ci_Ethos | Intuition 8/12 | Half Shell | 07 | |ci_Ethos | Intuition 8/12 | Half Shell + Power | 08 | |ci_Ethos | Intuition 8/12 | Full Shell | 09 | |ci_Ethos | Intuition 8/12 | Full Shell + Power | 10 | |ci_Ethos | Intuition 8/12 | Super60 | 11 | |ci_Ethos | Intuition 8/12 | ezHear | 12 | |ci_Ethos | Flx | OTE | 13 | |ci_Ethos | Sparo 8/12 | OTE | 14 | |ci_Ethos | Clik | OTE | 15 | |ci_Ethos | Loon | OTE | 16 | |ci_Ethos | Pluros | OTE | 17 | |ci_EthosOvertus | Cue | Mini CIC | 18 | |ci_EthosOvertus | Cue | CIC | 19 | |ci_Ethos | Intuition 8/12 | Mini CIC | 20 | |ci_Ethos | Intuition 8/12 | BTE | 21 | |ci_Ethos | Intuition 8/12 | BTE + Power | 22 | |ci_Ethos | TransEar 12 | BTE | 23 | |ci_Ethos | IRIC 12 | RIC | 26 | |ci_EthosOvertus | Cue | mRIC w/o SoftTouch | 210 | |ci_EthosOvertus | Cue | mRIC | 211 | |ci_EthosOvertus | Cue | mRIC w/ Tcoil | 212 | |ci_Intune | Sparo AD | OTE | 29 | |ci_Intune | Intuition 4AD | Full Shell | 30 | |ci_Intune | Intuition 4AD | Half Shell | 31 | |ci_Intune | Intuition 4AD | Super60 | 32 | |ci_Intune | Intuition 4AD | BTE | 33 | |ci_Intune | TransEar+ | OTE | 37 | |ci_Intune | Intuition 4+ | CIC | 45 | |ci_Intune | Intuition 4+ | Mini Canal | 46 | |ci_Intune | Intuition 4+ | Canal | 47 | |ci_Intune | Intuition 4+ | Half Shell | 48 | |ci_Intune | Intuition 4+ | Full Shell | 49 | |ci_Intune | Intuition 4+ | Super60 | 50 | |ci_Intune | Intuition 4+ | ezHear | 51 | |ci_Intune | Intuition 4+ | BTE | 52 | |ci_Intune | Intuition 4+ | Mini CIC | 52 | |ci_Intune | Intuition 4+ | CIC + Power | 55 | |ci_Intune | Intuition 4+ | Mini Canal + Power | 56 | |ci_Intune | Intuition 4+ | Canal + Power | 57 | |ci_Intune | Intuition 4+ | Half Shell + Power | 58 | |ci_Intune | Intuition 4+ | Full Shell + Power | 59 | |ci_Intune | Intuition 4+ | Mini CIC + Power | 60 | |ci_Intune | nVe AD | RIC | 62 | |ci_Intune | IRIC 4 | RIC | 63 | |ci_Spin | Sparo 2 | OTE | 28 | |ci_Spin | Intuition 2FC | Full Shell | 38 | |ci_Spin | Intuition 2FC | CIC | 39 | |ci_Spin | Intuition 2FC | Half Shell | 40 | |ci_Spin | Intuition 2FC | Mini Canal | 41 | |ci_Spin | Intuition 2FC | Canal | 42 | |ci_Spin | Intuition 2FC | Super60 | 43 | |ci_Spin | Intuition 2FC | BTE | 44 | |ci_Spin | Intuition 2FC | Mini CIC | 45 | |ci_Spin | Intuition 2FC | Security | 54 | |ci_Spin | nVe 2 | RIC | 61 | |ci_SpinNR | Intuition 2ER | Full Shell | 01 | |ci_SpinNR | Intuition 2ER | Full Shell + Power | 02 | |ci_SpinNR | Intuition 2ER | CIC | 03 | |ci_SpinNR | Intuition 2ER | CIC + Power | 04 | |ci_SpinNR | Intuition 2ER | Half Shell | 05 | |ci_SpinNR | Intuition 2ER | Half Shell + Power | 06 | |ci_SpinNR | Intuition 2ER | Mini Canal | 07 | |ci_SpinNR | Intuition 2ER | Mini Canal + Power | 08 | |ci_SpinNR | Intuition 2ER | Canal | 09 | |ci_SpinNR | Intuition 2ER | Canal + Power | 10 | |ci_SpinNR | Intuition 2ER | Super60 | 11 | |ci_SpinNR | Intuition 2ER | BTE | 12 | |ci_SpinNR | Intuition 2ER | ezHear | 13 | |ci_SpinNR | Sparo 2ER | OTE | 14 | |ci_SpinNR | Intuition 2FC+ | Mini CIC | 19 | |ci_SpinNR | Intuition 2FC+ | CIC | 20 | |ci_SpinNR | Intuition 2FC+ | CIC + Power | 21 | |ci_SpinNR | Intuition 2FC+ | Mini Canal | 22 | |ci_SpinNR | Intuition 2FC+ | Mini Canal + Power | 23 | |ci_SpinNR | Intuition 2FC+ | Canal | 24 | |ci_SpinNR | Intuition 2FC+ | Canal + Power | 25 | |ci_SpinNR | Intuition 2FC+ | Half Shell | 26 | |ci_SpinNR | Intuition 2FC+ | Half Shell + Power | 27 | |ci_SpinNR | Intuition 2FC+ | Full Shell | 28 | |ci_SpinNR | Intuition 2FC+ | Full Shell + Power | 29 | |ci_SpinNR | Intuition 2FC+ | Super60 | 30 | |ci_SpinNR | Intuition 2FC+ | BTE | 31 | |ci_SpinNR | Intuition 2FC+ | ezHear | 32 | |ci_SpinNR | Intuition 2+ | Mini CIC | 33 | |ci_SpinNR | Intuition 2+ | CIC | 34 | |ci_SpinNR | Intuition 2+ | CIC + Power | 35 | |ci_SpinNR | Intuition 2+ | Mini Canal | 36 | |ci_SpinNR | Intuition 2+ | Mini Canal + Power | 37 | |ci_SpinNR | Intuition 2+ | Canal | 38 | |ci_SpinNR | Intuition 2+ | Canal + Power | 39 | |ci_SpinNR | Intuition 2+ | Half Shell | 40 | |ci_SpinNR | Intuition 2+ | Half Shell + Power | 41 | |ci_SpinNR | Intuition 2+ | Full Shell | 42 | |ci_SpinNR | Intuition 2+ | Full Shell + Power | 43 | |ci_SpinNR | Intuition 2+ | Super60 | 44 | |ci_SpinNR | Intuition 2+ | BTE | 45 | |ci_SpinNR | Intuition 2+ | ezHear | 46 | |ci_SpinNR | IRIC 2 | RIC | 47 | |ci_Essential | Simplex 2P+ | Mini CIC | 01 | |ci_Essential | Simplex 2P+ | CIC | 02 | |ci_Essential | Simplex 2P+ | CIC + Power | 03 | |ci_Essential | Simplex 2P+ | Mini Canal | 04 | |ci_Essential | Simplex 2P+ | Mini Canal + Power | 05 | |ci_Essential | Simplex 2P+ | Canal | 06 | |ci_Essential | Simplex 2P+ | Canal + Power | 07 | |ci_Essential | Simplex 2P+ | Half Shell | 08 | |ci_Essential | Simplex 2P+ | Half Shell + Power | 09 | |ci_Essential | Simplex 2P+ | Full Shell | 10 | |ci_Essential | Simplex 2P+ | Full Shell + Power | 11 | |ci_Essential | Simplex 2P+ | Super60 | 12 | |ci_Essential | Simplex 2P+ | BTE | 13 | |ci_Essential | Simplex 2P+ | ezHear | 14 | |ci_Essential | 478P+ | BTE | 15 | |ci_Essential | 675DP+ | BTE | 16 | |ci_Audion4 | Flx 4 | OTE | 13 | |ci_Audion6 | Intuition 6 | CIC | 01 | |ci_Audion6 | Intuition 6 | CIC + Power | 02 | |ci_Audion6 | Intuition 6 | Mini Canal | 03 | |ci_Audion6 | Intuition 6 | Mini Canal + Power | 04 | |ci_Audion6 | Intuition 6 | Canal | 05 | |ci_Audion6 | Intuition 6 | Canal + Power | 06 | |ci_Audion6 | Intuition 6 | Half Shell | 07 | |ci_Audion6 | Intuition 6 | Half Shell + Power | 08 | |ci_Audion6 | Intuition 6 | Full Shell | 09 | |ci_Audion6 | Intuition 6 | Full Shell + Power | 10 | |ci_Audion6 | Intuition 6 | Super 60 | 11 | |ci_Audion6 | Flx 6 | OTE | 13 | |ci_Audion6 | Intuition 6 | Mini CIC | 16 | |ci_Audion6 | IRIC 6 | RIC | 27 | |ci_Audion6 | BTE D6P | BTE | 28 | |ci_Audion6 | BTE 6AD | BTE | 29 | |ci_Audion6 | BTE D6HP | BTE | 30 | === Product and Style ID: Methods for Storage and Retrieval === To save the field ProdAndStyleID manufacturer's reserved space: procedure TEzNzBase.SetFieldProdAndStyleID(ProdAndStyleID: integer; var Word2: word); var BitMask: word; begin // word2 format in bits: xPPP PVVV IIII IIII (x=UsingInSitu, P=prescription, V=VCpos, I=ProdAndStyleID) // store ProdAndStyleID code: // 1. clear ProdAndStyleID field using bitmask. // 2. store ProdAndStyleID field (and preserve other data in Word2). BitMask := 255; // 0000 0000 1111 1111 Word2 := (Word2 and not BitMask) {clear field} xor ProdAndStyleID {store}; end; To read the field ProdAndStyleID from manufacturer's reserved space: function TEzNzBase.GetFieldProdAndStyleID(word2: word): integer; var BitMask: word; begin // word2 format in bits: xPPP PVVV IIII IIII (x=UsingInSitu, P=prescription, V=VCpos, I=ProdAndStyleID) BitMask := 255; {bitmask of 8-bits} result := (Word2 and BitMask); end; === Serial Number: Methods for Storage and Retrieval === Serial Number storage format: SerialNumber = 05108567 (Format: YearCode + Serial Upper 8-bits + Serial Lower 16-bits) YearCode = CalendarYear - 2000 To save the serial number to manufacturer's reserved space: procedure SetRTISerialNum(SerialNum: integer; var Word1, Word3, Word4: word); var BitMask: word; YearCode: string; PlainSerialNumStr: string; PlainSerialNum: integer; begin YearCode := Copy( Format('%.8d',[SerialNum]), 1, 2); // extract yearcode PlainSerialNumStr := Copy( Format('%.8d',[SerialNum]), 3, 6); // extract just serial number (no yearcode included) PlainSerialNum := StrToInt(PlainSerialNumStr); // store yearcode used in serial number: // 1. clear yearcode field using bitmask. // 2. store yearcode field (and preserve other data in Word1). BitMask := 65472; // binary equiv: 1111 1111 1100 0000 Word1 := (Word1 and Bitmask {clear field}) xor StrToInt(YearCode) {store}; // store serial number by spliting its 24-bit content between Word3 and Word4 //Word3 := PlainSerialNum shr 16; // strip lower 16-bits & store only upper 8-bits (shift right 16 places (bits) of this 24-bit code) BitMask := 65280; // binary equiv: 1111 1111 0000 0000 Word3 := (Word3 and Bitmask {clear field}) xor (PlainSerialNum shr 16); // strip lower 16-bits & store only upper 8-bits (shift right 16 places (bits) of this 24-bit code) Word4 := PlainSerialNum and 65535; // store in entire word4 (bitmask 65535 has all 32 bits on) end; To read the serial number from manufacturer's reserved space: function GetRTISerialNum(word1, word3, word4: word): integer; var YearCode: string; SerialNum: integer; begin //-------------------------------------------- // 1111 1111 11xx xxxx (Word1) // AND 0000 0000 0011 1111 (63 bitmask) YearCode can be max 2063 (i.e. 63) // ----------------------- // 0000 0000 00xx xxxx (YearCode) //-------------------------------------------- YearCode := format('%.2d', [Word1 and 63] ); // 63 = bitmask 111111 (6-bits) SerialNum := ((Word3 and 255 {upper 8-bits}) shl 16 ) + Word4 {lower 16-bits}; // create basic serial number SerialNum := StrToInt(format('%s%.6d', [YearCode, SerialNum])); // add yearcode to serial number result := SerialNum; end; === Audiogram: Methods for Storage and Retrieval === Set the audiogram data in the scratch memory. 10 frequencies are stored in 50 bits, representing each value as a 5 bit number. The value stored is the hearing threshold divided by 5. This is rounded to the nearest 5, so 26 becomes 5 and 48 becomes 10. The minimum stored value is 0, the maximum stored value is 150. //------------------------------------------------------------------------------ // Procedure : SetScratchMemAudiogram // Description: To save the audiogram to manufacturer's reserve space (RTI circuits) // Arguments : Autofit: integer; var Word3: word // Result : None //------------------------------------------------------------------------------ procedure TEzNzBase.SetScratchMemAudiogram(AnAudiogram: TAudiogram; var Word1: word; var Word5: word; var Word6: word; var Word7: word); var BitMask: word; CompressedAudiogram: array [0..6] of Byte; i, BytePos, BitPos, BitPosInByte, FreqIdx, Overflow: integer; CompressedGainVal: Byte; begin if FHasAudiogram then begin // only store to hearing aid if Audiogram exist for i:=0 to high(CompressedAudiogram) do begin CompressedAudiogram[i] := 0; // clear all bits end; // encode audiogram for FreqIdx := 0 to AnAudiogram.Highest {9} do begin BitPos := FreqIdx * 5; BitPosInByte := BitPos mod 8; BytePos := BitPos div 8; Overflow := (5 {field size in bits} - (8 {bitsperbyte} - BitPosInByte {good bits})); BitMask := 31; // binary equiv: 0000 0000 0001 1111 BitMask := (not (BitMask shl BitPosInByte)); // binary equiv: 1111 1111 1110 0000 (if BitPosInType = 0) // let's calculate compressed gain value if AnAudiogram.FOriginal[FreqIdx] <> -1 then begin // if Gain in current frequency is not empty (-1) ... CompressedGainVal := (AnAudiogram.FOriginal[FreqIdx] div 5); end else begin CompressedGainVal := 31; // code for empty field (-1) end; // store first part of freq value (gain index, actually) // gain index = (gain value @ freq) / 5 // Gain in current frequency is not empty (-1). Let's store it CompressedAudiogram[BytePos] := (CompressedAudiogram[BytePos] and BitMask {clear field}) xor (CompressedGainVal shl BitPosInByte) {store}; // store overflow bits in next byte (second part of freq value, if there is overflow in previous storage unit) if Overflow > 0 then begin //BitMask := GetBitMask(5 {field size in bits} - (8 {bitsperbyte} - Overflow)); // get count of missing bits that need storing //GetBitMask(Overflow); // get bitmask based on count of missing bits that need storing BitMask := 65535 shl Overflow; // get bitmask based on count of missing bits that need storing CompressedAudiogram[BytePos+1] := (CompressedAudiogram[BytePos+1] and BitMask {clear field}) xor (CompressedGainVal shr (5 {fieldsize} - Overflow) {store}); {store only missing bits} end; {endif} end; {endfor} // store compressed audiogram: // 1. clear audiogram field using bitmask. // 2. store audiogram field (and preserve other data in Word1 and Word5..Word7). //BitMask := 65343; // binary equiv: 1111 1111 0011 1111 BitMask := (3 shl 6); // binary equiv: 0000 0000 1100 0000 BitMask := not BitMask; // binary equiv: 1111 1111 0011 1111 Word1 := (Word1 and BitMask {clear field}) xor (CompressedAudiogram[6] shl 6 {store}); // upper 2-bits Word5 := (Word5 and 0 {clear field}) xor CompressedAudiogram[4] {store} xor (CompressedAudiogram[5] shl 8) {store}; // upper 16-bits Word6 := (Word6 and 0 {clear field}) xor CompressedAudiogram[2] {store} xor (CompressedAudiogram[3] shl 8) {store}; // mid 16-bits Word7 := (Word7 and 0 {clear field}) xor CompressedAudiogram[0] {store} xor (CompressedAudiogram[1] shl 8) {store}; // lower 16-bits end; //endif end; Get the audiogram data from the scratch memory: //------------------------------------------------------------------------------ // Procedure : GetScratchMemAudiogram // Description: To read the audiogram from manufacturer's reserve space (RTI circuits) // Arguments : Word1, Word5, Word6, Word7: word; var AnAudiogram: array of integer; // Result : void //------------------------------------------------------------------------------ function TEzNzBase.GetScratchMemAudiogram(Word1, Word5, Word6, Word7: word; var AnAudiogram: array of integer): Boolean; var CompressedAudiogram: array [0..6] of Byte; AudiogramFromInstrument: array [0..9] of integer; BitMask: word; i, BytePos, BitPos, BitPosInByte, GainIdx, GainVal, FreqIdx, Overflow: integer; AudiogramExists: Boolean; begin AudiogramExists := False; for i:=0 to high(CompressedAudiogram) do begin CompressedAudiogram[i] := 0; // clear all bits end; // unpack data CompressedAudiogram[0] := (Word7 and (255 shl 0)) shr 0; // lower freq CompressedAudiogram[1] := (Word7 and (255 shl 8)) shr 8; CompressedAudiogram[2] := (Word6 and (255 shl 0)) shr 0; // mid freq CompressedAudiogram[3] := (Word6 and (255 shl 8)) shr 8; CompressedAudiogram[4] := (Word5 and (255 shl 0)) shr 0; // upper freq CompressedAudiogram[5] := (Word5 and (255 shl 8)) shr 8; CompressedAudiogram[6] := (Word1 and (3 shl 6)) shr 6; // remaining upper 2-bits // check whether we have an audiogram for i:=0 to High(CompressedAudiogram) do begin if CompressedAudiogram[i] <> 0 then begin AudiogramExists := True; // we have an audiogram stored end; end; if AudiogramExists then begin // decode audiogram (stored in bitmap) BitMask := 31; {Bitmask = 11111} for FreqIdx := 0 to 9 do begin // init variables BitPos := (FreqIdx * 5); BitPosInByte := BitPos mod 8; BytePos := BitPos div 8; Overflow := (5 {field size in bits} - (8 {bitsperbyte} - BitPosInByte {good bits})); // get gain value for current frequency GainIdx := (CompressedAudiogram[BytePos] and (BitMask shl BitPosInByte) {extract}) shr BitPosInByte {store as Int}; if Overflow > 0 then begin GainIdx := GainIdx xor (CompressedAudiogram[BytePos+1] and (BitMask shr (8 {bitsperbyte} - BitPosInByte {good bits})) {extract}) shl (8 {bitsperbyte} - BitPosInByte) {store as Int}; end; if (GainIdx <> 31) and (GainIdx <> 0) then begin GainVal := GainIdx * 5; // get gain value (based on gain index) end else begin GainVal := -1; // gain value is empty (-1) end; AudiogramFromInstrument[FreqIdx] := GainVal; end; for i:=0 to high(AudiogramFromInstrument) do begin AnAudiogram[i] := AudiogramFromInstrument[i]; end; end; result := AudiogramExists; end; ===Prescription Type: Methods for Storage and Retrieval=== ^ Name ^ Code ^ Value ^ Description ^ | Unassigned | presc_Unassigned | 0 | Unassigned prescription. | | FIG6 Audina v.1 2001 | presc_FIG6AudinaV1 | 1 | Audina Prescription version 1 (2001), based on FIG6. | | FIG6 Audina v.2 2006 | presc_FIG6AudinaV2 | 2 | Audina Prescription version 2 (2006), based on FIG6. | | NAL-NL1 | presc_NALNL1 | 3 | NAL-NL1 Prescription. | | FIG6 Audina v.3 2009 | presc_FIG6AudinaV3 | 4 | Audina Prescription version 3 (2009), based on FIG6 and Steve Armstrong's algorithms. | To save the prescription type to manufacturer's reserved space: procedure TEzNzBase.SetFieldPrescriptionType(Prescription: TNZPrescriptionType; var Word2: word); var ValToStore, BitMask: word; begin // word2 format in bits: xPPP PVVV IIII IIII (x=UsingInSitu, P=prescription, V=VCpos, I=ProdAndStyleID) // 0xx xx|<----------- // Move data (prescription) to correct location by shifting-left 11 bits: 0XXX X000 0000 0000. ValToStore := (integer(Prescription) shl 11 {move}); // Note: we only suport up to 15 possible prescriptions, i.e. we only save // 4 bits of Prescription. The bitmask takes care of that. BitMask := 34815; // binary equivalent: 1000 0111 1111 1111 // Clear Prescription field, then store new value while preserving old data in Word1 // Eg: 1. Clear field: x001 0xxx xxxx xxxx --> x000 0xxx xxxx xxxx // 2. Store value 5: x000 0xxx xxxx xxxx --> x010 1xxx xxxx xxxx (and preseve other data) Word2 := (Word2 and Bitmask {clear field}) xor ValToStore {store}; end; To read the prescription type from manufacturer's reserved space: function GetFieldPrescriptionType(word2: word): TNZPrescriptionType; begin // move 11 bits to right, and extract 4 bits (bitmask 15(dec)=1111(bin)) result := TNZPrescriptionType( (Word2 shr 11) and 15 ); end; === Autofit Settings: Methods for Storage and Retrieval === ^ ezFIT 4.x Name ^ Code ^ Value ^ Description ^ | Normal WDRC | autofit_NormalWDRC | 0 | Normal using Wide Dynamic Range Compression (WDRC). | | AGC-o | autofit_AGCo | 1 | Automatic Gain Control - Output. | | Linear | autofit_Linear | 2 | Linear. | | Restaurant / Party | autofit_RestaurantParty | 3 | Restaurant, or Party. | | Telephone / Acoustic Telephone / Induction Loop | autofit_TelephoneInductionLoop | 4 | Telephone, Acoustic Telephone, or Induction Loop (FM Loops, etc.). | | Music | autofit_Music | 5 | Music or other pure tones. | | Television | autofit_HomeOfficeTV | 6 | Television. | | Theatre / Place of Worship | autofit_TheatrePlaceWorship | 7 | Automatic Gain Control - Output. | | Intense Noise | autofit_IntenseNoise | 8 | Intense Noise. | | AutoAdapt | autofit_AutoAdapt | 9 | Auto adapt with Adaptive Directionality technology. | | AutoSceneDetection | autofit_AutoSceneDetect | 10 | Auto scene detection using iSceneDetect or similar technology. | ^ ezFIT 5.x Name ^ Code ^ Value ^ Description ^ | Normal WDRC | autofit_NormalWDRC | 0 | Normal using Wide Dynamic Range Compression (WDRC). | | AGC-o | autofit_AGCo | 1 | Automatic Gain Control - Output. | | Linear | autofit_Linear | 2 | Linear. | | Restaurant / Party | autofit_RestaurantParty | 3 | Restaurant, or Party. | | Telephone / Acoustic Telephone / Induction Loop | autofit_TelephoneInductionLoop | 4 | Telephone (Telecoil), Acoustic Telephone (No Telecoil), or Induction Loop (FM Loops, etc.). | | Music | autofit_Music | 5 | Music or other pure tones. | | Home / Office / TV | autofit_HomeOfficeTV | 6 | Home, Office, or TV. | | Theatre / Place of Worship | autofit_TheatrePlaceWorship | 7 | Theatre, or Place of Worship. | | Intense Noise | autofit_IntenseNoise | 8 | Intense Noise. | | AutoAdapt | autofit_AutoAdapt | 9 | Auto adapt with Adaptive Directionality technology. | | AutoSceneDetection | autofit_AutoSceneDetect | 10 | Auto scene detection using iSceneDetect or similar technology. | | Speech Optimizer | autofit_SpeechOptimizer | 11 | Speech Optimizer. | | Background Noise / Car / Machines | autofit_BackgroundNoiseCarMachines | 12 | Background Noise, car/traffic, machines. | | Loop System | autofit_Loop | 13 | Induction Loop Systems (FM Loops, etc.). | To save the Autofit Settings to manufacturer's reserved space: procedure TEzNzBase.SetFieldAutofitSettings(Autofit: TAutofitSettings; var Word1: word; var Word3: word); var BitMask: word; begin // store autofit code: // 1. clear autofitcode field using bitmask. // 2. store autofitcode field (and preserve other data in Word1 and Word3). BitMask := 15; // 0000 0000 0000 1111 Word3 := (Word3 and not (BitMask shl 8) {clear field}) xor (Autofit.MemoryA shl 8) {store}; Word3 := (Word3 and not (BitMask shl 12) {clear field}) xor (Autofit.MemoryB shl 12) {store}; Word1 := (Word1 and not (BitMask shl 8) {clear field}) xor (Autofit.MemoryC shl 8) {store}; Word1 := (Word1 and not (BitMask shl 12) {clear field}) xor (Autofit.MemoryD shl 12) {store}; end; To read the prescription type from manufacturer's reserved space: procedure TEzNzBase.GetFieldAutofitSettings(Word1, Word3: word; var Autofit: TAutofitSettings); var BitMask: integer; begin // get field values (each 6-bit long) BitMask := 15; // 0000 0000 0000 1111 Autofit.MemoryA := (Word3 and (BitMask shl 8)) shr 8; Autofit.MemoryB := (Word3 and (BitMask shl 12)) shr 12; Autofit.MemoryC := (Word1 and (BitMask shl 8)) shr 8; Autofit.MemoryD := (Word1 and (BitMask shl 12)) shr 12; end; === Using In Situ Audiogram: Methods for Storage and Retrieval === To save the field UsingInSituAudiogram to manufacturer's reserved space: procedure TEzNzBase.SetFieldUsingInSituAudiogram(UsingInSituAudiogram: Boolean; var Word2: word); var BitMask: word; begin // store UsingInSituAudiogram code: // 1. clear UsingInSituAudiogram field using bitmask. // 2. store UsingInSituAudiogram field (and preserve other data in Word2). BitMask := 1; // 0000 0000 0000 0001 Word2 := (Word2 and not (BitMask shl 15) {clear field}) xor (integer(UsingInSituAudiogram) shl 15) {store}; end; To read the field UsingInSituAudiogram from manufacturer's reserved space: function TEzNzBase.GetFieldUsingInSituAudiogram(Word2: word): Boolean; var BitMask: integer; begin // word2 format in bits: xPPP PVVV IIII IIII (x=UsingInSitu, P=prescription, V=VCpos, I=ProdAndStyleID) // get UsingInSituAudiogram setting (upper bit in word) BitMask := 1; // 0000 0000 0000 0001 result := ( ((Word2 and (BitMask shl 15)) shr 15) = 1 ); end; === VC Pos: Methods for Storage and Retrieval === To save the field VCPos manufacturer's reserved space: procedure TEzNzBase.SetFieldVCPos(VCPos: integer; var Word2: word); var BitMask: word; begin // word2 format in bits: xPPP PVVV IIII IIII (x=UsingInSitu, P=prescription, V=VCpos, I=ProdAndStyleID) // store FUserVCAutofittedPos code: // 1. clear FUserVCAutofittedPos field using bitmask. // 2. store FUserVCAutofittedPos field (and preserve other data in Word2). BitMask := 7; // 0000 0000 0000 0111 Word2 := (Word2 and not (BitMask shl 8) {clear field}) xor (VCPos shl 8) {store}; end; To read the field VCPos from manufacturer's reserved space: function TEzNzBase.GetFieldVCPos(word2: word): integer; begin // word2 format in bits: xPPP PVVV IIII IIII (x=UsingInSitu, P=prescription, V=VCpos, I=ProdAndStyleID) // move 8 bits to right, and extract 3 bits (bitmask 15(dec)=1111(bin)) result := (Word2 shr 8) and 7 {bitmask}; end; === BTE Earhook (deprecated in favor of TubingType): Methods for Storage and Retrieval === To save the field BTEEarhook manufacturer's reserved space: procedure TEzNzBase.SetFieldBTEEarhook(BTEEarhook : boolean; var Word8: word); var BitMask: word; begin // store BTEEarhook code: // 1. clear BTEEarhook field using bitmask. // 2. store BTEEarhook field (and preserve other data in Word8). BitMask := 1; // 0000 0000 0000 0001 Word8 := (Word8 and not BitMask) {clear field} xor ifthen(BTEEarhook,1,0) {store}; end; To read the field BTEEarhook from manufacturer's reserved space: function TEzNzBase.GetFieldBTEEarhook(word8: word): Boolean; var BitMask: word; begin BitMask := 1; {bitmask of 1-bits} result := (Word8 and BitMask)=1; end; === Tubing Type: Methods for Storage and Retrieval === To save the field TubingType manufacturer's reserved space: procedure TEzNzBase.SetFieldTubingType(TubingType: TTubingType; var Word8: word); var BitMask: word; begin // this field is split in two: // - Lower 1-bit is in Word8.bit00 // - Upper 2-bits are in Word8.bit02 & bit03 // store TubingType code: // 1. clear lower 1-bit TubingType field using bitmask. // 2. store lower 1-bit TubingType field (and preserve other data in Word8). // 3. clear upper 2-bits TubingType field using bitmask. // 4. store upper 2-bits TubingType field (and preserve other data in Word8). // lower 1-bit BitMask := 1; // 0000 0000 0000 0001 //Word8 := (Word8 and not BitMask) {clear field} xor ifthen(TubingType,1,0) {store}; Word8 := (Word8 and not BitMask) {clear field} xor (integer(TubingType) and Bitmask) {store}; // upper 2-bits BitMask := 4; // 0000 0000 0000 0011 Word8 := (Word8 and not (BitMask shl 2)) {clear field} xor ((integer(TubingType) and (Bitmask shl 1 {mask for upper 2-bits}) {grab 2-bits}) and (Bitmask shl 2)) {store}; end; To read the field TubingType from manufacturer's reserved space: function TEzNzBase.GetFieldTubingType(word8: word): TTubingType; var BitMask: word; lower1bit, upper2bits: word; begin // this field is split in two: // - Lower 1-bit is in Word8.bit00 // - Upper 2-bits are in Word8.bit02 & bit03 // get lower 1-bit BitMask := 1; {bitmask of 1-bits} lower1bit := (Word8 and BitMask); // get upper 2-bits BitMask := 4; {bitmask of 2-bits} upper2bits := (Word8 and (BitMask shl 2)); result := TTubingType((upper2bits shr 1 {move to correct position}) and lower1bit); end; === Has Directional Mic: Methods for Storage and Retrieval === To save the field HasDirMic manufacturer's reserved space: procedure TEzNzBase.SetFieldHasDirMic(UsingInSituAudiogram: Boolean; var Word8: word); var BitMask: word; begin // store HasDirMic code: // 1. clear HasDirMic field using bitmask. // 2. store HasDirMic field (and preserve other data in Word8). BitMask := 1; // 0000 0000 0000 0001 Word8 := (Word8 and not (BitMask shl 1) {clear field}) xor (integer(HasDirMic) shl 1) {store}; end; To read the field HasDirMic from manufacturer's reserved space: function TEzNzBase.GetFieldHasDirMic(Word8: word): Boolean; var BitMask: integer; begin // word8 format in bits: 0000 0000 0000 00DB (D=HasDirMic, B=BTE Earhook) // get HasDirMic setting (2nd low bit in word) BitMask := 1; // 0000 0000 0000 0001 result := ( ((Word8 and (BitMask shl 1)) shr 1) = 1 ); end; **Operators** ^ shl | bitwise shift left (usually, move to position before storing) | ^ shr | bitwise shift right (usually, move to position before retrieving) | ^ and | bitwise AND (to store) | ^ or |bitwise OR | ^ xor | bitwise XOR (to store new data, and preserve other old data in same data structure, or reverse bits) | ^ 63 | bitmask of 111111 (i.e. all 6 bits on) | ^ 65535 | bitmask of 11111111 11111111 (i.e. all 16 bits on) |