Class SampleConverter
Every public entry point of DtmfDecoder and
DtmfDetector that accepts non-double
PCM — short[] PCM16, float[] normalized float, int[]
PCM32, or int[] packed PCM24 — funnels through this class before
the shared analysis pipeline sees a sample. Concentrating the conversion
formulas in one place is how we guarantee Requirements 4.5, 4.6, and 4.7
hold identically on both the batch path (DtmfDecoder) and the push
path (DtmfDetector).
Two flavours are provided for every input type:
- An allocating variant —
fromShort(short[]),fromFloat(float[]),fromInt(int[]),fromPcm24(int[])— which returns a freshly allocateddouble[]. Used by the batchDtmfDecoder.decodeoverloads, which run exactly once per call and for which the allocation is proportional to input size — standard cost of format conversion. - A streaming
*Intovariant —fromShortInto(short[], double[]),fromFloatInto(float[], double[]),fromIntInto(int[], double[])— which writes into a caller-supplied destination array. Used by the push-styleDtmfDetector.process(short[])/process(float[])/process(int[])overloads, which own a reusabledouble[] scratchbuffer so no allocation happens per chunk on the hot path.
Conversion formulas (Requirements 4.5, 4.6, 4.7):
short→double: divide by32768.0(that is2^15). Chosen soShort.MIN_VALUEmaps exactly to-1.0andShort.MAX_VALUEmaps to32767/32768 ≈ 0.99996948. The alternative divisor32767.0would shift the zero-crossing and break the symmetry of the negative and positive extremes.float→double: direct widening cast, no scaling. Callers supply values already normalized to[-1.0, 1.0]. Special values (NaN,±Infinity) are preserved bit-exactly by Java's widening conversion.int→double: divide by2147483648.0(that is2^31). Chosen soInteger.MIN_VALUEmaps exactly to-1.0;Integer.MAX_VALUEmaps to2147483647/2147483648.- PCM24 packed in
int: the low 24 bits of each input carry a signed 24-bit value. Sign-extend from bit 23 (shift left 8, then arithmetic-shift right 8) so values in[0x800000, 0xFFFFFF]become negative, then divide by8388608.0(that is2^23). After sign extension0x800000is-8388608and maps exactly to-1.0;0x7FFFFFis8388607and maps to8388607/8388608.
Null and size handling: Every allocating variant rejects
null input with NullPointerException via
Objects.requireNonNull(Object, String) so the parameter name appears
in the message (Requirement 17.1). The *Into variants additionally
reject a destination shorter than the source with
IllegalArgumentException naming both lengths (Requirement 17.2).
Although the type is public so
com.tino1b2be.dtmf.DtmfDecoder in the sibling package can call it,
the convention is that com.tino1b2be.dtmf.internal.* is not part of
the published API. Callers go through DtmfDecoder
or DtmfDetector instead.
-
Method Summary
Modifier and TypeMethodDescriptionstatic double[]fromFloat(float[] src) Convert normalizedfloatsamples todoublein a new array via direct widening.static voidfromFloatInto(float[] src, double[] dst) Copy normalizedfloatsamples into a caller-supplieddouble[]destination via direct widening, starting at index 0.static double[]fromInt(int[] src) Convert signed PCM32 samples to normalizeddoublein a new array.static voidfromIntInto(int[] src, double[] dst) Convert signed PCM32 samples into a caller-supplied destination starting at index 0.static double[]fromPcm24(int[] src) Convert signed PCM24 samples packed into the low 24 bits of eachintto normalizeddoublein a new array.static double[]fromShort(short[] src) Convert signed PCM16 samples to normalizeddoublein a new array.static voidfromShortInto(short[] src, double[] dst) Convert signed PCM16 samples into a caller-supplied destination starting at index 0.
-
Method Details
-
fromShort
public static double[] fromShort(short[] src) Convert signed PCM16 samples to normalizeddoublein a new array.- Parameters:
src- PCM16 input; must be non-null- Returns:
- a new
double[]of the same length withdst[i] = src[i] / 32768.0 - Throws:
NullPointerException- ifsrcis null
-
fromFloat
public static double[] fromFloat(float[] src) Convert normalizedfloatsamples todoublein a new array via direct widening.- Parameters:
src- float input; must be non-null- Returns:
- a new
double[]of the same length withdst[i] = (double) src[i](exact widening, no scaling) - Throws:
NullPointerException- ifsrcis null
-
fromInt
public static double[] fromInt(int[] src) Convert signed PCM32 samples to normalizeddoublein a new array.- Parameters:
src- PCM32 input; must be non-null- Returns:
- a new
double[]of the same length withdst[i] = src[i] / 2147483648.0 - Throws:
NullPointerException- ifsrcis null
-
fromPcm24
public static double[] fromPcm24(int[] src) Convert signed PCM24 samples packed into the low 24 bits of eachintto normalizeddoublein a new array.Sign-extends each input from bit 23 before scaling, so the full two's-complement 24-bit range
[-8388608, 8388607]is handled and values whose bit-23 is set round-trip to negative output.- Parameters:
src- PCM24-packed input; must be non-null- Returns:
- a new
double[]of the same length withdst[i] = signExtend24(src[i]) / 8388608.0 - Throws:
NullPointerException- ifsrcis null
-
fromShortInto
public static void fromShortInto(short[] src, double[] dst) Convert signed PCM16 samples into a caller-supplied destination starting at index 0.- Parameters:
src- PCM16 input; must be non-nulldst- destination buffer; must be non-null and havedst.length >= src.length- Throws:
NullPointerException- if either argument is nullIllegalArgumentException- ifdst.length < src.length
-
fromFloatInto
public static void fromFloatInto(float[] src, double[] dst) Copy normalizedfloatsamples into a caller-supplieddouble[]destination via direct widening, starting at index 0.- Parameters:
src- float input; must be non-nulldst- destination buffer; must be non-null and havedst.length >= src.length- Throws:
NullPointerException- if either argument is nullIllegalArgumentException- ifdst.length < src.length
-
fromIntInto
public static void fromIntInto(int[] src, double[] dst) Convert signed PCM32 samples into a caller-supplied destination starting at index 0.- Parameters:
src- PCM32 input; must be non-nulldst- destination buffer; must be non-null and havedst.length >= src.length- Throws:
NullPointerException- if either argument is nullIllegalArgumentException- ifdst.length < src.length
-