Esempio n. 1
0
static int startread(sox_format_t * ft)
{
  char     magic[4];
  float    rate;
  uint32_t channels, ft_encoding;
  unsigned i, bits_per_sample;
  sox_encoding_t encoding;
  uint16_t code, size;

  if (lsx_readchars(ft, magic, sizeof(magic)))
    return SOX_EOF;

  for (i = 0; id[i].desc && memcmp(magic, id[i].str, sizeof(magic)); ++i);
  if (!id[i].desc) {
    lsx_fail_errno(ft, SOX_EHDR, "sf: can't find IRCAM identifier");
    return SOX_EOF;
  }
  lsx_report("found %s identifier", id[i].desc);
  ft->encoding.reverse_bytes = id[i].reverse_bytes;

  if (lsx_readf(ft, &rate) || lsx_readdw(ft, &channels) || lsx_readdw(ft, &ft_encoding))
    return SOX_EOF;

  if (!(encoding = sox_enc(ft_encoding, &bits_per_sample))) {
    lsx_fail_errno(ft, SOX_EFMT, "sf: unsupported encoding %#x)", ft_encoding);
    return SOX_EOF;
  }
  do {
    if (lsx_readw(ft, &code) || lsx_readw(ft, &size))
      return SOX_EOF;
    if (code == SF_COMMENT) {
      char * buf = lsx_calloc(1, (size_t)size + 1); /* +1 ensures null-terminated */
      if (lsx_readchars(ft, buf, (size_t) size) != SOX_SUCCESS) {
        free(buf);
        return SOX_EOF;
      }
      sox_append_comments(&ft->oob.comments, buf);
      free(buf);
    }
    else if (lsx_skipbytes(ft, (size_t) size))
      return SOX_EOF;
  } while (code);
  if (lsx_skipbytes(ft, FIXED_HDR - (size_t)lsx_tell(ft)))
    return SOX_EOF;

  return lsx_check_read_params(ft, channels, rate, encoding, bits_per_sample, (uint64_t)0, sox_true);
}
Esempio n. 2
0
static int start_read(sox_format_t * ft)
{
  char buf[sizeof(ID1)];
  uint32_t num_samples;

  if (lsx_readchars(ft, buf, sizeof(buf)) || lsx_readdw(ft, &num_samples) ||
      lsx_skipbytes(ft, sizeof(ID2)))
    return SOX_EOF;
  if (memcmp(ID1, buf, sizeof(buf))) {
    lsx_fail_errno(ft, SOX_EHDR, "wve: can't find Psion identifier");
    return SOX_EOF;
  }
  return lsx_check_read_params(ft, 1, 8000., SOX_ENCODING_ALAW, 8, (off_t)num_samples, sox_true);
}
Esempio n. 3
0
static int startread(sox_format_t * ft)
{
  char     magic_[sizeof(magic[0])];
  uint32_t headers_bytes, num_channels, comments_bytes;
  uint64_t num_samples;
  double   rate;

  if (lsx_readdw(ft, (uint32_t *)&magic_))
    return SOX_EOF;

  if (memcmp(magic[MACHINE_IS_BIGENDIAN], magic_, sizeof(magic_))) {
    if (memcmp(magic[MACHINE_IS_LITTLEENDIAN], magic_, sizeof(magic_))) {
      lsx_fail_errno(ft, SOX_EHDR, "can't find sox file format identifier");
      return SOX_EOF;
    }
    ft->encoding.reverse_bytes = !ft->encoding.reverse_bytes;
    lsx_report("file is opposite endian");
  }
  if (lsx_readdw(ft, &headers_bytes) ||
      lsx_readqw(ft, &num_samples) ||
      lsx_readdf(ft, &rate) ||
      lsx_readdw(ft, &num_channels) ||
      lsx_readdw(ft, &comments_bytes))
    return SOX_EOF;

  if (((headers_bytes + 4) & 7) || headers_bytes < FIXED_HDR + comments_bytes ||
      (num_channels > 65535)) /* Reserve top 16 bits */ {
    lsx_fail_errno(ft, SOX_EHDR, "invalid sox file format header");
    return SOX_EOF;
  }

  if (comments_bytes) {
    char * buf = lsx_calloc(1, (size_t)comments_bytes + 1); /* ensure nul-terminated */
    if (lsx_readchars(ft, buf, (size_t)comments_bytes) != SOX_SUCCESS) {
      free(buf);
      return SOX_EOF;
    }
    sox_append_comments(&ft->oob.comments, buf);
    free(buf);
  }
  
  /* Consume any bytes after the comments and before the start of the audio
   * block.  These may include comment padding up to a multiple of 8 bytes,
   * and further header information that might be defined in future. */
  lsx_seeki(ft, (off_t)(headers_bytes - FIXED_HDR - comments_bytes), SEEK_CUR);

  return lsx_check_read_params(
      ft, num_channels, rate, SOX_ENCODING_SIGN2, 32, (off_t)num_samples, sox_true);
}
Esempio n. 4
0
static int start_read(sox_format_t * ft)
{
  unsigned long header_size_ul = 0, num_samples_ul = 0;
  sox_encoding_t encoding = SOX_ENCODING_SIGN2;
  size_t     header_size, bytes_read;
  size_t     num_samples = 0;
  unsigned       bytes_per_sample = 0;
  unsigned       channels = 1;
  unsigned       rate = 16000;
  char           fldname[64], fldtype[16], fldsval[128];
  char           * buf;

  /* Magic header */
  if (lsx_reads(ft, fldname, (size_t)8) || strncmp(fldname, "NIST_1A", (size_t)7) != 0) {
    lsx_fail_errno(ft, SOX_EHDR, "Sphere header does not begin with magic word `NIST_1A'");
    return (SOX_EOF);
  }

  if (lsx_reads(ft, fldsval, (size_t)8)) {
    lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header");
    return (SOX_EOF);
  }

  /* Determine header size, and allocate a buffer large enough to hold it. */
  sscanf(fldsval, "%lu", &header_size_ul);
  buf = lsx_malloc(header_size = header_size_ul);

  /* Skip what we have read so far */
  header_size -= 16;

  if (lsx_reads(ft, buf, header_size) == SOX_EOF) {
    lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header");
    free(buf);
    return (SOX_EOF);
  }

  header_size -= (strlen(buf) + 1);

  while (strncmp(buf, "end_head", (size_t)8) != 0) {
    if (strncmp(buf, "sample_n_bytes", (size_t)14) == 0)
      sscanf(buf, "%63s %15s %u", fldname, fldtype, &bytes_per_sample);
    else if (strncmp(buf, "channel_count", (size_t)13) == 0)
      sscanf(buf, "%63s %15s %u", fldname, fldtype, &channels);
    else if (strncmp(buf, "sample_count ", (size_t)13) == 0)
      sscanf(buf, "%53s %15s %lu", fldname, fldtype, &num_samples_ul);
    else if (strncmp(buf, "sample_rate ", (size_t)12) == 0)
      sscanf(buf, "%53s %15s %u", fldname, fldtype, &rate);
    else if (strncmp(buf, "sample_coding", (size_t)13) == 0) {
      sscanf(buf, "%63s %15s %127s", fldname, fldtype, fldsval);
      if (!strcasecmp(fldsval, "ulaw") || !strcasecmp(fldsval, "mu-law"))
        encoding = SOX_ENCODING_ULAW;
      else if (!strcasecmp(fldsval, "pcm"))
        encoding = SOX_ENCODING_SIGN2;
      else {
        lsx_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval);
        free(buf);
        return SOX_EOF;
      }
    }
    else if (strncmp(buf, "sample_byte_format", (size_t)18) == 0) {
      sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval);
      if (strcmp(fldsval, "01") == 0)         /* Data is little endian. */
        ft->encoding.reverse_bytes = MACHINE_IS_BIGENDIAN;
      else if (strcmp(fldsval, "10") == 0)    /* Data is big endian. */
        ft->encoding.reverse_bytes = MACHINE_IS_LITTLEENDIAN;
      else if (strcmp(fldsval, "1")) {
        lsx_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval);
        free(buf);
        return SOX_EOF;
      }
    }

    if (lsx_reads(ft, buf, header_size) == SOX_EOF) {
      lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header");
      free(buf);
      return (SOX_EOF);
    }

    header_size -= (strlen(buf) + 1);
  }

  if (!bytes_per_sample)
    bytes_per_sample = encoding == SOX_ENCODING_ULAW? 1 : 2;

  while (header_size) {
    bytes_read = lsx_readbuf(ft, buf, header_size);
    if (bytes_read == 0) {
      free(buf);
      return (SOX_EOF);
    }
    header_size -= bytes_read;
  }
  free(buf);

  if (ft->seekable) {
    /* Check first four bytes of data to see if it's shorten compressed. */
    char           shorten_check[4];

    if (lsx_readchars(ft, shorten_check, sizeof(shorten_check)))
      return SOX_EOF;
    lsx_seeki(ft, -(off_t)sizeof(shorten_check), SEEK_CUR);

    if (!memcmp(shorten_check, "ajkg", sizeof(shorten_check))) {
      lsx_fail_errno(ft, SOX_EFMT,
                     "File uses shorten compression, cannot handle this.");
      return (SOX_EOF);
    }
  }

  num_samples = num_samples_ul;
  return lsx_check_read_params(ft, channels, (sox_rate_t)rate, encoding,
      bytes_per_sample << 3, (uint64_t)num_samples * channels, sox_true);
}