| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #ifdef HAVE_CONFIG_H |
| | #include <config.h> |
| | #endif |
| |
|
| | #include <string.h> |
| | #include <pocketsphinx.h> |
| | #include "util/byteorder.h" |
| | #include "util/ckd_alloc.h" |
| |
|
| | #define TRY_FREAD(ptr, size, nmemb, stream) \ |
| | if (fread(ptr, size, nmemb, stream) != (nmemb)) { \ |
| | E_ERROR_SYSTEM("Failed to read %d bytes", size * nmemb); \ |
| | rv = -1; \ |
| | goto error_out; \ |
| | } |
| |
|
| | int |
| | ps_config_soundfile(ps_config_t *config, FILE *infh, const char *file) |
| | { |
| | char header[4]; |
| | int rv = 0; |
| |
|
| | if (file == NULL) |
| | file = "(input filehandle)"; |
| | fseek(infh, 0, SEEK_SET); |
| | TRY_FREAD(header, 1, 4, infh); |
| | fseek(infh, 0, SEEK_SET); |
| |
|
| | if (0 == memcmp(header, "RIFF", 4)) { |
| | E_INFO("%s appears to be a WAV file\n", file); |
| | rv = ps_config_wavfile(config, infh, file); |
| | } |
| | else if (0 == memcmp(header, "NIST", 4)) { |
| | E_INFO("%s appears to be a NIST SPHERE file\n", file); |
| | rv = ps_config_nistfile(config, infh, file); |
| | } |
| | else if (0 == memcmp(header, "OggS", 4)) { |
| | E_INFO("%s appears to be an UNSUPPORTED Ogg file\n", file); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | else if (0 == memcmp(header, "fLaC", 4)) { |
| | E_INFO("%s appears to be an UNSUPPORTED FLAC file\n", file); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | else if (0 == memcmp(header, "\xff\xff\xff", 3) |
| | || 0 == memcmp(header, "\xff\xff\xfe", 3)) { |
| | E_INFO("%s might be an MP3 file, but who knows really! " |
| | "UNSUPPORTED!\n", file); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | else { |
| | E_INFO("%s appears to be raw data\n", file); |
| | } |
| |
|
| | error_out: |
| | return rv; |
| | } |
| |
|
| | int |
| | ps_config_wavfile(ps_config_t *config, FILE *infh, const char *file) |
| | { |
| | char id[4]; |
| | int32 intval, header_len; |
| | int16 shortval; |
| | int rv = 0; |
| |
|
| | if (file == NULL) |
| | file = "(input filehandle)"; |
| | |
| | |
| | ps_config_set_str(config, "input_endian", "little"); |
| |
|
| | |
| | TRY_FREAD(id, 1, 4, infh); |
| | |
| | TRY_FREAD(&intval, 4, 1, infh); |
| | |
| | TRY_FREAD(id, 1, 4, infh); |
| | if (0 != memcmp(id, "WAVE", 4)) { |
| | E_ERROR("%s is not a WAVE file\n", file); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | |
| | TRY_FREAD(id, 1, 4, infh); |
| | if (0 != memcmp(id, "fmt ", 4)) { |
| | E_ERROR("Format chunk missing\n"); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | |
| | TRY_FREAD(&intval, 4, 1, infh); |
| | SWAP_LE_32(&intval); |
| | header_len = intval; |
| |
|
| | |
| | TRY_FREAD(&shortval, 2, 1, infh); |
| | SWAP_LE_16(&shortval); |
| | if (shortval != 1) { |
| | E_ERROR("%s is not in PCM format\n", file); |
| | rv = -1; |
| | goto error_out; |
| | } |
| |
|
| | |
| | TRY_FREAD(&shortval, 2, 1, infh); |
| | SWAP_LE_16(&shortval); |
| | if (shortval != 1) { |
| | E_ERROR("%s is not single channel\n", file); |
| | rv = -1; |
| | goto error_out; |
| | } |
| |
|
| | |
| | TRY_FREAD(&intval, 4, 1, infh); |
| | SWAP_LE_32(&intval); |
| | if (ps_config_int(config, "samprate") == 0) |
| | ps_config_set_int(config, "samprate", intval); |
| | else if (ps_config_int(config, "samprate") != intval) { |
| | E_WARN("WAVE file sampling rate %d != samprate %d\n", |
| | intval, ps_config_int(config, "samprate")); |
| | } |
| |
|
| | |
| | TRY_FREAD(&intval, 4, 1, infh); |
| |
|
| | |
| | TRY_FREAD(&shortval, 2, 1, infh); |
| |
|
| | |
| | TRY_FREAD(&shortval, 2, 1, infh); |
| | SWAP_LE_16(&shortval); |
| | if (shortval != 16) { |
| | E_ERROR("%s is not 16-bit\n", file); |
| | rv = -1; |
| | goto error_out; |
| | } |
| |
|
| | |
| | if (header_len > 16) { |
| | |
| | char *spam = malloc(header_len - 16); |
| | if (fread(spam, 1, header_len - 16, infh) != (size_t)(header_len - 16)) { |
| | E_ERROR_SYSTEM("%s: Failed to read extra header", file); |
| | rv = -1; |
| | } |
| | ckd_free(spam); |
| | if (rv == -1) |
| | goto error_out; |
| | } |
| |
|
| | |
| | while (1) { |
| | TRY_FREAD(id, 1, 4, infh); |
| | if (0 == memcmp(id, "data", 4)) { |
| | |
| | TRY_FREAD(&intval, 4, 1, infh); |
| | break; |
| | } |
| | else { |
| | char *spam; |
| | |
| | |
| | TRY_FREAD(&intval, 4, 1, infh); |
| | SWAP_LE_32(&intval); |
| | |
| | spam = malloc(intval); |
| | if (fread(spam, 1, intval, infh) != (size_t)intval) { |
| | E_ERROR_SYSTEM("%s: Failed to read %s chunk", file, id); |
| | rv = -1; |
| | } |
| | ckd_free(spam); |
| | if (rv == -1) |
| | goto error_out; |
| | } |
| | } |
| |
|
| | error_out: |
| | return rv; |
| | } |
| |
|
| | int |
| | ps_config_nistfile(ps_config_t *config, FILE *infh, const char *file) |
| | { |
| | char hdr[1024]; |
| | char *line, *c; |
| | int rv = 0; |
| |
|
| | if (file == NULL) |
| | file = "(input filehandle)"; |
| |
|
| | TRY_FREAD(hdr, 1, 1024, infh); |
| | hdr[1023] = '\0'; |
| |
|
| | |
| | |
| | if ((line = strstr(hdr, "sample_rate")) == NULL) { |
| | E_ERROR("No sampling rate in NIST header!\n"); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | c = strchr(line, '\n'); |
| | if (c) *c = '\0'; |
| | c = strrchr(line, ' '); |
| | if (c == NULL) { |
| | E_ERROR("Could not find sampling rate!\n"); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | ++c; |
| | if (ps_config_int(config, "samprate") == 0) |
| | ps_config_set_int(config, "samprate", atoi(c)); |
| | else if (ps_config_int(config, "samprate") != atoi(c)) { |
| | E_WARN("NIST file sampling rate %d != samprate %d\n", |
| | atoi(c), ps_config_int(config, "samprate")); |
| | } |
| |
|
| | if (line + strlen(line) < hdr + 1023) |
| | line[strlen(line)] = ' '; |
| | if ((line = strstr(hdr, "sample_byte_format")) == NULL) { |
| | E_ERROR("No sample byte format in NIST header!\n"); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | c = strchr(line, '\n'); |
| | if (c) *c = '\0'; |
| | c = strrchr(line, ' '); |
| | if (c == NULL) { |
| | E_ERROR("Could not find sample byte order!\n"); |
| | rv = -1; |
| | goto error_out; |
| | } |
| | ++c; |
| | if (0 == memcmp(c, "01", 2)) { |
| | ps_config_set_str(config, "input_endian", "little"); |
| | } |
| | else if (0 == memcmp(c, "10", 2)) { |
| | ps_config_set_str(config, "input_endian", "big"); |
| | } |
| | else { |
| | E_ERROR("Unknown byte order %s\n", c); |
| | rv = -1; |
| | goto error_out; |
| | } |
| |
|
| | error_out: |
| | return rv; |
| | } |
| |
|