Package com.tino1b2be.dtmf.io.internal
Class SampleConversion
java.lang.Object
com.tino1b2be.dtmf.io.internal.SampleConversion
Shared PCM sample normalisation helper for the
dtmf-io family of
modules. Bytes-to-double decoding for every
(bitDepth, byteOrder, encoding) tuple this project supports lives
here in a single place, so the normalisation formulas cannot drift between
RawPcmAudioSource, the clean-room WAV reader in
dtmf-io-wav, and the mp3spi-backed decoder in
dtmf-io-mp3.
This class is not part of the published API. It lives
in com.tino1b2be.dtmf.io.internal, whose stability contract
(see the package Javadoc) explicitly allows breakage between any two
releases. It is public at the type level purely so the WAV and
MP3 provider modules — which live in sibling Java packages —
can reach it; external callers MUST NOT depend on it.
Conversion formulas (Requirements 3.6, 7.12, 9.14)
The normalisation matchesdtmf-core's
com.tino1b2be.dtmf.internal.SampleConverter contract exactly:
- Signed integer PCM: decoded as a two's-complement
signed integer in the requested byte order, then divided by
2^(bitDepth - 1).Short.MIN_VALUEmaps exactly to-1.0;Short.MAX_VALUEmaps to32767/32768 ≈ 0.99996948. The analogous exact-and-near mapping holds at 24, 32, and 64 bits. - Unsigned integer PCM: decoded as an unsigned
integer in the requested byte order, then the midpoint
2^(bitDepth - 1)is subtracted and the result is divided by2^(bitDepth - 1). An unsigned sample whose value is the midpoint therefore maps to exactly0.0; an unsigned sample of0maps to-1.0; the maximum unsigned value maps just below+1.0. - IEEE float: the raw bit pattern is assembled in
the requested byte order and reinterpreted via
Float.intBitsToFloat(int)(32-bit) orDouble.longBitsToDouble(long)(64-bit). No scaling is applied — float PCM samples are already in[-1.0, 1.0]by convention. The 32-bit variant widens todoubleby direct cast.
Supported tuples
Every(bitDepth, byteOrder, encoding) combination that appears in
the PCM sample-formats table of design.md is supported:
SIGNED_INT:bitDepth ∈ {16, 24, 32, 64}×byteOrder ∈ {LITTLE_ENDIAN, BIG_ENDIAN}.UNSIGNED_INT:bitDepth ∈ {16, 24, 32, 64}×byteOrder ∈ {LITTLE_ENDIAN, BIG_ENDIAN}.IEEE_FLOAT:bitDepth ∈ {32, 64}×byteOrder ∈ {LITTLE_ENDIAN, BIG_ENDIAN}.
decoderFor(int, ByteOrder, PcmEncoding) with an
IllegalArgumentException; callers upstream (notably
RawPcmAudioSource's constructor) are expected to have validated
their inputs before asking for a decoder, so this dispatcher's rejection
is the second line of defence.- Since:
- 2.1.0
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic interfacePrimitive functional interface for a single-frame PCM decoder. -
Method Summary
Modifier and TypeMethodDescriptionstatic doubledecodeFloat32BE(byte[] b, int offset) Decode a big-endian IEEE 754 32-bit float sample and widen todoublewithout scaling.static doubledecodeFloat32LE(byte[] b, int offset) Decode a little-endian IEEE 754 32-bit float sample and widen todoublewithout scaling.static doubledecodeFloat64BE(byte[] b, int offset) Decode a big-endian IEEE 754 64-bit double sample bit-exactly.static doubledecodeFloat64LE(byte[] b, int offset) Decode a little-endian IEEE 754 64-bit double sample bit-exactly.static doubledecodePcm16BE(byte[] b, int offset) Decode a big-endian signed PCM16 sample and normalise by2^15.static doubledecodePcm16LE(byte[] b, int offset) Decode a little-endian signed PCM16 sample and normalise by2^15.static doubledecodePcm24BE(byte[] b, int offset) Decode a big-endian signed PCM24 sample, sign-extend from bit 23, and normalise by2^23.static doubledecodePcm24LE(byte[] b, int offset) Decode a little-endian signed PCM24 sample, sign-extend from bit 23, and normalise by2^23.static doubledecodePcm32BE(byte[] b, int offset) Decode a big-endian signed PCM32 sample and normalise by2^31.static doubledecodePcm32LE(byte[] b, int offset) Decode a little-endian signed PCM32 sample and normalise by2^31.static doubledecodePcm64BE(byte[] b, int offset) Decode a big-endian signed PCM64 sample and normalise by2^63.static doubledecodePcm64LE(byte[] b, int offset) Decode a little-endian signed PCM64 sample and normalise by2^63.decoderFor(int bitDepth, ByteOrder order, PcmEncoding encoding) Return theSampleConversion.SampleDecoderfor a given(bitDepth, byteOrder, encoding)tuple.static doubledecodeUnsignedPcm16BE(byte[] b, int offset) Decode a big-endian unsigned PCM16 sample, subtract the midpoint2^15, and normalise by2^15.static doubledecodeUnsignedPcm16LE(byte[] b, int offset) Decode a little-endian unsigned PCM16 sample, subtract the midpoint2^15, and normalise by2^15.static doubledecodeUnsignedPcm24BE(byte[] b, int offset) Decode a big-endian unsigned PCM24 sample, subtract the midpoint2^23, and normalise by2^23.static doubledecodeUnsignedPcm24LE(byte[] b, int offset) Decode a little-endian unsigned PCM24 sample, subtract the midpoint2^23, and normalise by2^23.static doubledecodeUnsignedPcm32BE(byte[] b, int offset) Decode a big-endian unsigned PCM32 sample, subtract the midpoint2^31, and normalise by2^31.static doubledecodeUnsignedPcm32LE(byte[] b, int offset) Decode a little-endian unsigned PCM32 sample, subtract the midpoint2^31, and normalise by2^31.static doubledecodeUnsignedPcm64BE(byte[] b, int offset) Decode a big-endian unsigned PCM64 sample, subtract the midpoint2^63, and normalise by2^63.static doubledecodeUnsignedPcm64LE(byte[] b, int offset) Decode a little-endian unsigned PCM64 sample, subtract the midpoint2^63, and normalise by2^63.
-
Method Details
-
decoderFor
public static SampleConversion.SampleDecoder decoderFor(int bitDepth, ByteOrder order, PcmEncoding encoding) Return theSampleConversion.SampleDecoderfor a given(bitDepth, byteOrder, encoding)tuple.- Parameters:
bitDepth- one of16,24,32,64order-ByteOrder.LITTLE_ENDIANorByteOrder.BIG_ENDIANencoding- PCM numeric encoding- Returns:
- decoder for the requested tuple
- Throws:
NullPointerException- iforderorencodingisnullIllegalArgumentException- if the(bitDepth, encoding)pair is not supported (for exampleIEEE_FLOATwithbitDepth == 16)
-
decodePcm16LE
public static double decodePcm16LE(byte[] b, int offset) Decode a little-endian signed PCM16 sample and normalise by2^15.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodePcm16BE
public static double decodePcm16BE(byte[] b, int offset) Decode a big-endian signed PCM16 sample and normalise by2^15.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodePcm24LE
public static double decodePcm24LE(byte[] b, int offset) Decode a little-endian signed PCM24 sample, sign-extend from bit 23, and normalise by2^23.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodePcm24BE
public static double decodePcm24BE(byte[] b, int offset) Decode a big-endian signed PCM24 sample, sign-extend from bit 23, and normalise by2^23.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodePcm32LE
public static double decodePcm32LE(byte[] b, int offset) Decode a little-endian signed PCM32 sample and normalise by2^31.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodePcm32BE
public static double decodePcm32BE(byte[] b, int offset) Decode a big-endian signed PCM32 sample and normalise by2^31.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodePcm64LE
public static double decodePcm64LE(byte[] b, int offset) Decode a little-endian signed PCM64 sample and normalise by2^63.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodePcm64BE
public static double decodePcm64BE(byte[] b, int offset) Decode a big-endian signed PCM64 sample and normalise by2^63.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm16LE
public static double decodeUnsignedPcm16LE(byte[] b, int offset) Decode a little-endian unsigned PCM16 sample, subtract the midpoint2^15, and normalise by2^15.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm16BE
public static double decodeUnsignedPcm16BE(byte[] b, int offset) Decode a big-endian unsigned PCM16 sample, subtract the midpoint2^15, and normalise by2^15.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm24LE
public static double decodeUnsignedPcm24LE(byte[] b, int offset) Decode a little-endian unsigned PCM24 sample, subtract the midpoint2^23, and normalise by2^23.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm24BE
public static double decodeUnsignedPcm24BE(byte[] b, int offset) Decode a big-endian unsigned PCM24 sample, subtract the midpoint2^23, and normalise by2^23.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm32LE
public static double decodeUnsignedPcm32LE(byte[] b, int offset) Decode a little-endian unsigned PCM32 sample, subtract the midpoint2^31, and normalise by2^31.The unsigned value is read into a
long(since2^32 - 1does not fit inint), so the subtraction is exact.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm32BE
public static double decodeUnsignedPcm32BE(byte[] b, int offset) Decode a big-endian unsigned PCM32 sample, subtract the midpoint2^31, and normalise by2^31.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm64LE
public static double decodeUnsignedPcm64LE(byte[] b, int offset) Decode a little-endian unsigned PCM64 sample, subtract the midpoint2^63, and normalise by2^63.2^63is not representable as a signedlong, so the raw 64-bit payload is widened todoubleviatoUnsignedDouble(long)before the subtraction; the result is therefore approximate at the ULP level ofdoublebut exact for the telephony-scale magnitudes real callers have.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeUnsignedPcm64BE
public static double decodeUnsignedPcm64BE(byte[] b, int offset) Decode a big-endian unsigned PCM64 sample, subtract the midpoint2^63, and normalise by2^63.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- normalised sample in
[-1.0, 1.0]
-
decodeFloat32LE
public static double decodeFloat32LE(byte[] b, int offset) Decode a little-endian IEEE 754 32-bit float sample and widen todoublewithout scaling.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- the widened float value
-
decodeFloat32BE
public static double decodeFloat32BE(byte[] b, int offset) Decode a big-endian IEEE 754 32-bit float sample and widen todoublewithout scaling.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- the widened float value
-
decodeFloat64LE
public static double decodeFloat64LE(byte[] b, int offset) Decode a little-endian IEEE 754 64-bit double sample bit-exactly.- Parameters:
b- source bytesoffset- index of the low byte of the sample- Returns:
- the decoded double value
-
decodeFloat64BE
public static double decodeFloat64BE(byte[] b, int offset) Decode a big-endian IEEE 754 64-bit double sample bit-exactly.- Parameters:
b- source bytesoffset- index of the high byte of the sample- Returns:
- the decoded double value
-