1 /* libSoX file format: HTK (c) 2008 robs@users.sourceforge.net
3 * See http://labrosa.ee.columbia.edu/doc/HTKBook21/HTKBook.html
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Lesser General Public License as published by
7 * the Free Software Foundation; either version 2.1 of the License, or (at
8 * your option) any later version.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
13 * General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public License
16 * along with this library; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 Waveform
, Lpc
, Lprefc
, Lpcepstra
, Lpdelcep
, Irefc
,
24 Mfcc
, Fbank
, Melspec
, User
, Discrete
, Unknown
} kind_t
;
25 static char const * const str
[] = {
26 "Sampled waveform", "Linear prediction filter", "Linear prediction",
27 "LPC cepstral", "LPC cepstra plus delta", "LPC reflection coef in",
28 "Mel-frequency cepstral", "Log mel-filter bank", "Linear mel-filter bank",
29 "User defined sample", "Vector quantised data", "Unknown"};
31 static int start_read(sox_format_t
* ft
)
33 uint32_t period_100ns
, num_samples
;
34 uint16_t bytes_per_sample
, parmKind
;
36 if (lsx_readdw(ft
, &num_samples
) ||
37 lsx_readdw(ft
, &period_100ns
) ||
38 lsx_readw (ft
, &bytes_per_sample
) ||
39 lsx_readw (ft
, &parmKind
)) return SOX_EOF
;
40 if (parmKind
!= Waveform
) {
41 int n
= min(parmKind
& 077, Unknown
);
42 lsx_fail_errno(ft
, SOX_EFMT
, "unsupported HTK type `%s' (0%o)", str
[n
], parmKind
);
45 return lsx_check_read_params(ft
, 1, 1e7
/ period_100ns
, SOX_ENCODING_SIGN2
,
46 (unsigned)bytes_per_sample
<< 3, (uint64_t)num_samples
, sox_true
);
49 static int write_header(sox_format_t
* ft
)
51 double period_100ns
= 1e7
/ ft
->signal
.rate
;
52 uint64_t len
= ft
->olength
? ft
->olength
:ft
->signal
.length
;
56 lsx_warn("length greater than 32 bits - cannot fit actual length in header");
59 if (!ft
->olength
&& floor(period_100ns
) != period_100ns
)
60 lsx_warn("rounding sample period %f (x 100ns) to nearest integer", period_100ns
);
61 return lsx_writedw(ft
, (unsigned)len
)
62 || lsx_writedw(ft
, (unsigned)(period_100ns
+ .5))
63 || lsx_writew(ft
, ft
->encoding
.bits_per_sample
>> 3)
64 || lsx_writew(ft
, Waveform
) ? SOX_EOF
: SOX_SUCCESS
;
67 LSX_FORMAT_HANDLER(htk
)
69 static char const * const names
[] = {"htk", NULL
};
70 static unsigned const write_encodings
[] = {SOX_ENCODING_SIGN2
, 16, 0, 0};
71 static sox_format_handler_t handler
= {
73 "PCM format used for Hidden Markov Model speech processing",
74 names
, SOX_FILE_BIG_END
| SOX_FILE_MONO
| SOX_FILE_REWIND
,
75 start_read
, lsx_rawread
, NULL
,
76 write_header
, lsx_rawwrite
, NULL
,
77 lsx_rawseek
, write_encodings
, NULL
, 0