User-visible symptom
A decoder can initialize successfully with remove_noise=false, but the exported compatibility function ps_start_stream() then returns -1. A binding or application that treats a negative return as a stream-start failure can therefore reject an otherwise valid decoder configuration.
This is especially surprising because remove_noise=false is the default, and the API documentation describes ps_start_stream() as retained for compatibility with the sole effect of resetting noise-removal statistics.
Mechanism in v5.1.1
These references are to commit 511126b492dcb267cf30d49d631946d7b61a9530 (v5.1.1).
src/fe/fe_interface.c:278-281 allocates fe->noise_stats only when remove_noise is true.
src/pocketsphinx.c:1072-1082 implements ps_start_stream() and returns -1 when noise_stats is null, at lines 1079-1080.
src/fe/fe_noise.c:253-258 shows that fe_reset_noisestats() is already null-safe.
src/config_macro.h:487-490 defines remove_noise with the default no.
include/pocketsphinx.h:769-780 documents the compatibility function and its return convention without stating that noise removal must be enabled.
The failure is therefore caused by a precondition that the reset helper itself does not require.
Minimal reproduction
Build PocketSphinx v5.1.1, copy the shipped English acoustic model, and make the effective model configuration disable noise removal (this avoids the shipped model's feat.params overriding the caller setting):
cp -R model/en-us/en-us /tmp/ps-no-noise-model
sed -i.bak 's/^-remove_noise .*/-remove_noise no/' /tmp/ps-no-noise-model/feat.params
Compile and run:
#include <pocketsphinx.h>
#include <stdio.h>
int main(void)
{
ps_config_t *config = ps_config_init(NULL);
ps_config_set_str(config, "hmm", "/tmp/ps-no-noise-model");
ps_config_set_str(config, "dict", "model/en-us/cmudict-en-us.dict");
ps_config_set_str(config, "lm", "model/en-us/en-us.lm.bin");
ps_decoder_t *ps = ps_init(config);
if (ps == NULL)
return 2;
printf("remove_noise=%d ps_start_stream=%d\n",
ps_config_bool(ps_get_config(ps), "remove_noise"),
ps_start_stream(ps));
ps_free(ps);
ps_config_free(config);
return 0;
}
With the pinned implementation, the expected output is:
remove_noise=0 ps_start_stream=-1
Changing the copied model's value to -remove_noise yes makes ps_start_stream() return 0.
What this does and does not establish
The allocation condition, failing branch, null-safe reset, default, and public API wording are directly established in the pinned source. The finding arose in application usage, not in PocketSphinx's test suite.
The standalone snippet above was not executed as part of this report; its result follows directly from the cited branches. ps_start_stream() is deprecated and is unnecessary for ordinary utterance processing, which limits the impact. This report does not claim that every caller invokes it or that disabling noise removal otherwise prevents decoding.
Smallest addressing change
Remove the noise_stats == NULL error return and call the already null-safe fe_reset_noisestats() unconditionally, or return 0 when the pointer is null. A focused regression test can initialize with an effective remove_noise=false configuration and assert that ps_start_stream() returns zero.
If the failure is intentional, the smaller alternative is to document the precondition explicitly, though that would make the compatibility function fail under the generic default.
User-visible symptom
A decoder can initialize successfully with
remove_noise=false, but the exported compatibility functionps_start_stream()then returns-1. A binding or application that treats a negative return as a stream-start failure can therefore reject an otherwise valid decoder configuration.This is especially surprising because
remove_noise=falseis the default, and the API documentation describesps_start_stream()as retained for compatibility with the sole effect of resetting noise-removal statistics.Mechanism in v5.1.1
These references are to commit
511126b492dcb267cf30d49d631946d7b61a9530(v5.1.1).src/fe/fe_interface.c:278-281allocatesfe->noise_statsonly whenremove_noiseis true.src/pocketsphinx.c:1072-1082implementsps_start_stream()and returns-1whennoise_statsis null, at lines 1079-1080.src/fe/fe_noise.c:253-258shows thatfe_reset_noisestats()is already null-safe.src/config_macro.h:487-490definesremove_noisewith the defaultno.include/pocketsphinx.h:769-780documents the compatibility function and its return convention without stating that noise removal must be enabled.The failure is therefore caused by a precondition that the reset helper itself does not require.
Minimal reproduction
Build PocketSphinx v5.1.1, copy the shipped English acoustic model, and make the effective model configuration disable noise removal (this avoids the shipped model's
feat.paramsoverriding the caller setting):cp -R model/en-us/en-us /tmp/ps-no-noise-model sed -i.bak 's/^-remove_noise .*/-remove_noise no/' /tmp/ps-no-noise-model/feat.paramsCompile and run:
With the pinned implementation, the expected output is:
Changing the copied model's value to
-remove_noise yesmakesps_start_stream()return0.What this does and does not establish
The allocation condition, failing branch, null-safe reset, default, and public API wording are directly established in the pinned source. The finding arose in application usage, not in PocketSphinx's test suite.
The standalone snippet above was not executed as part of this report; its result follows directly from the cited branches.
ps_start_stream()is deprecated and is unnecessary for ordinary utterance processing, which limits the impact. This report does not claim that every caller invokes it or that disabling noise removal otherwise prevents decoding.Smallest addressing change
Remove the
noise_stats == NULLerror return and call the already null-safefe_reset_noisestats()unconditionally, or return0when the pointer is null. A focused regression test can initialize with an effectiveremove_noise=falseconfiguration and assert thatps_start_stream()returns zero.If the failure is intentional, the smaller alternative is to document the precondition explicitly, though that would make the compatibility function fail under the generic default.