add support for multiple channels

git-svn-id: svn+ssh://svn.code.sf.net/p/cmusphinx/code/trunk/sphinxbase@10119 94700074-3cef-4d97-a70e-9c8c206c02f5
This commit is contained in:
dhdfu
2010-05-25 00:34:02 +00:00
parent 41b6f72cb2
commit ea4df05a94
6 changed files with 58 additions and 18 deletions
+2 -2
View File
@@ -184,8 +184,8 @@ static arg_t defn[] = {
{ "-whichchan",
ARG_INT32,
"1",
"Channel to process" },
"0",
"Channel to process (numbered from 1), or 0 to mix all channels" },
{ "-ofmt",
ARG_STRING,
+50 -16
View File
@@ -188,7 +188,7 @@ detect_nist(sphinx_wave2feat_t *wtf, char const *infile)
cmd_ln_set_float32_r(wtf->config, "-samprate", atof_c(words[2]));
}
if (0 == strcmp(words[0], "channel_count")) {
cmd_ln_set_float32_r(wtf->config, "-nchans", atoi(words[2]));
cmd_ln_set_int32_r(wtf->config, "-nchans", atoi(words[2]));
}
if (0 == strcmp(words[0], "sample_byte_format")) {
cmd_ln_set_str_r(wtf->config, "-input_endian",
@@ -284,6 +284,27 @@ detect_sphinx_mfc(sphinx_wave2feat_t *wtf, char const *infile)
return TRUE;
}
int
mixnpick_channels(int16 *buf, int32 nsamp, int32 nchans, int32 whichchan)
{
int i, j;
if (whichchan > 0) {
for (i = whichchan - 1; i < nsamp; i += nchans)
buf[i/nchans] = buf[i];
}
else {
for (i = 0; i < nsamp; i += nchans) {
float64 tmp = 0.0;
for (j = 0; j < nchans && i + j < nsamp; ++j) {
tmp += buf[i + j];
}
buf[i/nchans] = (int16)(tmp / nchans);
}
}
return i/nchans;
}
#ifdef HAVE_SNDFILE_H
/**
* Detect a file supported by libsndfile and parse its header if detected.
@@ -297,11 +318,11 @@ detect_sndfile(sphinx_wave2feat_t *wtf, char const *infile)
SF_INFO sfinfo;
memset(&sfinfo, 0, sizeof(sfinfo));
/* We let other detectors catch I/O errors, since there is
no way to tell them from format errors when opening :( */
if ((sf = sf_open(infile, SFM_READ, &sfinfo)) == NULL) {
E_ERROR_SYSTEM("Failed to open %s", infile);
return -1;
return FALSE;
}
/* Get relevant information. */
cmd_ln_set_int32_r(wtf->config, "-nchans", sfinfo.channels);
cmd_ln_set_float32_r(wtf->config, "-samprate", sfinfo.samplerate);
@@ -320,9 +341,11 @@ static int
decode_sndfile(sphinx_wave2feat_t *wtf)
{
size_t nsamp;
int32 nfr;
int32 nfr, nchans, whichchan;
int nfloat, n;
nchans = cmd_ln_int32_r(wtf->config, "-nchans");
whichchan = cmd_ln_int32_r(wtf->config, "-whichchan");
fe_start_utt(wtf->fe);
nfloat = 0;
while ((nsamp = sf_read_short(wtf->insfh,
@@ -331,6 +354,10 @@ decode_sndfile(sphinx_wave2feat_t *wtf)
int16 const *inspeech;
size_t nvec;
/* Mix or pick channels. */
if (nchans > 1)
nsamp = mixnpick_channels(wtf->audio, nsamp, nchans, whichchan);
inspeech = wtf->audio;
nvec = wtf->featsize;
/* Consume all samples. */
@@ -367,9 +394,11 @@ static int
decode_pcm(sphinx_wave2feat_t *wtf)
{
size_t nsamp;
int32 nfr;
int32 nfr, nchans, whichchan;
int nfloat, n;
nchans = cmd_ln_int32_r(wtf->config, "-nchans");
whichchan = cmd_ln_int32_r(wtf->config, "-whichchan");
fe_start_utt(wtf->fe);
nfloat = 0;
while ((nsamp = fread(wtf->audio, 2, wtf->blocksize, wtf->infh)) != 0) {
@@ -381,6 +410,10 @@ decode_pcm(sphinx_wave2feat_t *wtf)
for (n = 0; n < nsamp; ++n)
SWAP_INT16(wtf->audio + n);
}
/* Mix or pick channels. */
if (nchans > 1)
nsamp = mixnpick_channels(wtf->audio, nsamp, nchans, whichchan);
inspeech = wtf->audio;
nvec = wtf->featsize;
@@ -462,9 +495,6 @@ decode_sphinx_mfc(sphinx_wave2feat_t *wtf)
static const audio_type_t types[] = {
{ "-mswav", &detect_riff, &decode_pcm },
{ "-nist", &detect_nist, &decode_pcm },
#ifdef HAVE_SNDFILE_H
{ "-sndfile", &detect_sndfile, &decode_sndfile },
#endif
{ "-raw", &detect_raw, &decode_pcm }
};
static const int ntypes = sizeof(types)/sizeof(types[0]);
@@ -751,7 +781,7 @@ int
sphinx_wave2feat_convert_file(sphinx_wave2feat_t *wtf,
char const *infile, char const *outfile)
{
int minfft, nfft, nfloat, veclen;
int nchans, minfft, nfft, nfloat, veclen;
audio_type_t const *atype;
int fshift, fsize;
@@ -785,15 +815,19 @@ sphinx_wave2feat_convert_file(sphinx_wave2feat_t *wtf,
/* Set up the input and output buffers. */
fe_get_input_size(wtf->fe, &fshift, &fsize);
/* Want to get at least a whole frame plus shift in here. */
wtf->blocksize = cmd_ln_int32_r(wtf->config, "-blocksize");
if (wtf->blocksize < fsize + fshift) {
/* Want to get at least a whole frame plus shift in here. Also we
will either pick or mix multiple channels so we need to read
them all at once. */
nchans = cmd_ln_int32_r(wtf->config, "-nchans");
wtf->blocksize = cmd_ln_int32_r(wtf->config, "-blocksize") * nchans;
if (wtf->blocksize < (fsize + fshift) * nchans) {
E_INFO("Block size of %d too small, increasing to %d\n",
wtf->blocksize, fsize + fshift);
wtf->blocksize = fsize + fshift;
wtf->blocksize,
(fsize + fshift) * nchans);
wtf->blocksize = (fsize + fshift) * nchans;
}
wtf->audio = ckd_calloc(wtf->blocksize, sizeof(*wtf->audio));
wtf->featsize = (wtf->blocksize - fsize) / fshift;
wtf->featsize = (wtf->blocksize / nchans - fsize) / fshift;
/* Use the maximum of the input and output frame sizes to allocate this. */
veclen = wtf->veclen;
+1
View File
@@ -26,6 +26,7 @@ CLEANFILES = test*.err test*.out \
test-sphinx_fe.cepview \
test-sphinx_pitch.f0 \
chan3.sph.mfc \
chan3.2chan.wav.mfc \
chan3.wav.mfc \
chan3.raw.mfc
Binary file not shown.
+1
View File
@@ -1,3 +1,4 @@
chan3.raw
chan3.wav
chan3.2chan.wav
chan3.sph
+4
View File
@@ -27,6 +27,10 @@ if ! cmp chan3.wav.mfc chan3.raw.mfc; then
fail "WAV and RAW compare"
fi
if ! cmp chan3.2chan.wav.mfc chan3.wav.mfc; then
fail "WAV2 and WAV compare"
fi
if ! cmp chan3.raw.mfc chan3.sph.mfc; then
fail "SPH and RAW compare"
fi