Class DtmfDetector
DtmfTone emissions via a registered Consumer
callback.
DtmfDetector is the streaming half of the public API (pair with
the batch DtmfDecoder and the pull-style DtmfStream). Per
Requirements 6.1–6.8 and 4.9, it exposes:
onTone(Consumer)— register a callback; a second call replaces the first.process(double[]),process(double[], int, int),process(short[]),process(float[]),process(int[])— feed a chunk. The callback is invoked synchronously during the same call when the chunk contains the first non-confirming analysis block after a confirmed tone (the Tone_End_Event).flush()— finalise any tone still in flight.samplesProcessed()— cumulative input sample count.
Channel handling. The detector honours
DtmfConfig.channelMode():
MONO— one internalAnalysisPipeline, every emission taggedchannel = 0.STEREO_INDEPENDENT— two pipelines; even-index samples feed the left channel (0), odd-index samples feed the right (1). Odd-length chunks are rejected withIllegalArgumentException(Requirement 13.5).STEREO_DOWNMIX— adjacent pairs averaged into a single mono stream; emissions taggedchannel = 0. Odd-length chunks are rejected (Requirement 13.5).
Chunk invariance (Requirement 6.7). Calling
process repeatedly with chunks whose concatenation equals a single
buffer B emits the same tones, in the same order, with the same
cumulative sample indices, as a single process(B) call on a fresh
detector. This holds by construction because the pipeline does not buffer
chunks — it streams samples one at a time through a
block-synchronous state machine whose only non-trivial state is
analysis-block-local.
Cumulative sample indices (Requirement 6.8).
samplesProcessed() counts every sample ever passed to any
process overload, including both channels of a stereo input. For
stereo modes it is the number of interleaved samples consumed, not the
per-channel count. Emitted tones' startSample/endSample
come from the per-channel analysis pipeline, so for
STEREO_INDEPENDENT those indices advance half as fast as
samplesProcessed().
Format overloads (Requirement 4.9). The short[],
float[], and int[] overloads convert into a reusable
double[] scratch buffer owned by this detector and then feed the
normalised samples through the same path as process(double[]).
No per-chunk allocation occurs on the hot path — the scratch buffer
is resized only when a chunk exceeds its current capacity.
Thread safety (Requirement 6.6). Instances are not
thread-safe. Concurrent process calls on the same detector have
undefined behaviour.
- Since:
- 2.0.0
-
Constructor Summary
ConstructorsConstructorDescriptionDtmfDetector(DtmfConfig config) Construct a new detector for the given configuration. -
Method Summary
Modifier and TypeMethodDescriptionvoidflush()Finalise any tone still in flight.voidRegister the callback that receives every emittedDtmfTone.voidprocess(double[] chunk) Feed a full chunk ofdouble[]samples through the detector.voidprocess(double[] chunk, int offset, int length) Feed a sub-range of adouble[]through the detector.voidprocess(float[] chunk) Feed a chunk of normalisedfloatsamples through the detector.voidprocess(int[] chunk) Feed a chunk of signed PCM32 samples through the detector.voidprocess(short[] chunk) Feed a chunk of signed PCM16 samples through the detector.longReturns the cumulative number of samples passed to anyprocessoverload since construction.
-
Constructor Details
-
DtmfDetector
Construct a new detector for the given configuration.- Parameters:
config- detection configuration; non-null- Throws:
NullPointerException- ifconfigisnull
-
-
Method Details
-
onTone
Register the callback that receives every emittedDtmfTone. CallingonTonereplaces any previously-registered callback (Requirement 6.1). Passingnullclears the callback.- Parameters:
callback- consumer to receive emissions, ornullto clear
-
process
public void process(double[] chunk) Feed a full chunk ofdouble[]samples through the detector.Equivalent to
process(chunk, 0, chunk.length).- Parameters:
chunk- sample chunk; non-null. Samples are expected in the range[-1.0, 1.0]- Throws:
NullPointerException- ifchunkisnullIllegalArgumentException- if the channel mode is stereo andchunk.lengthis odd
-
process
public void process(double[] chunk, int offset, int length) Feed a sub-range of adouble[]through the detector. The callback registered viaonTone(Consumer)is invoked for every tone confirmed within this chunk, synchronously before this method returns.- Parameters:
chunk- sample buffer; non-nulloffset- starting index; must satisfy0 <= offset && offset + length <= chunk.lengthlength- number of samples to consume; must be>= 0- Throws:
NullPointerException- ifchunkisnullIndexOutOfBoundsException- ifoffset/lengthare out of rangeIllegalArgumentException- if the channel mode is stereo andlengthis odd
-
process
public void process(short[] chunk) Feed a chunk of signed PCM16 samples through the detector. Samples are normalised todoublevia division by32768.0(Requirement 4.5).- Parameters:
chunk- PCM16 sample chunk; non-null- Throws:
NullPointerException- ifchunkisnullIllegalArgumentException- if the channel mode is stereo andchunk.lengthis odd
-
process
public void process(float[] chunk) Feed a chunk of normalisedfloatsamples through the detector. Samples are widened todouble(Requirement 4.6).- Parameters:
chunk- float sample chunk; non-null. Samples are expected in the range[-1.0, 1.0]- Throws:
NullPointerException- ifchunkisnullIllegalArgumentException- if the channel mode is stereo andchunk.lengthis odd
-
process
public void process(int[] chunk) Feed a chunk of signed PCM32 samples through the detector. Samples are normalised todoublevia division by2^31(Requirement 4.7).- Parameters:
chunk- PCM32 sample chunk; non-null- Throws:
NullPointerException- ifchunkisnullIllegalArgumentException- if the channel mode is stereo andchunk.lengthis odd
-
flush
public void flush()Finalise any tone still in flight. Afterflush()returns, each internal pipeline is back in its idle state and can be fed further samples.If a tone was still Active or had just entered Ending when
flushwas called, it is emitted synchronously (via the registered callback) provided its duration so far meets the configured minimum (Requirement 6.3). -
samplesProcessed
public long samplesProcessed()Returns the cumulative number of samples passed to anyprocessoverload since construction.For stereo modes this counts interleaved input samples (i.e.
left + right), not per-channel samples.- Returns:
- the cumulative number of samples passed to any
processoverload since construction
-