예제 #1
0
sox_bool sox_format_supports_encoding(
    char               const * path,
    char               const * filetype,
    sox_encodinginfo_t const * encoding)
{
  #define enc_arg(T) (T)handler->write_formats[i++]
  sox_bool is_file_extension = filetype == NULL;
  sox_format_handler_t const * handler;
  unsigned i = 0, s;
  sox_encoding_t e;

  assert(path);
  assert(encoding);
  if (!filetype)
    filetype = lsx_find_file_extension(path);

  if (!filetype || !(handler = sox_find_format(filetype, is_file_extension)) ||
      !handler->write_formats)
    return sox_false;
  while ((e = enc_arg(sox_encoding_t))) {
    if (e == encoding->encoding) {
      sox_bool has_bits;
      for (has_bits = sox_false; (s = enc_arg(unsigned)); has_bits = sox_true)
        if (s == encoding->bits_per_sample)
          return sox_true;
      if (!has_bits && !encoding->bits_per_sample)
        return sox_true;
      break;
    }
    while (enc_arg(unsigned));
  }
예제 #2
0
bob::io::audio::Writer::Writer(const char* filename, double rate,
    sox_encoding_t encoding, size_t bits_per_sample):
  m_filename(filename),
  m_opened(false)
{

  sox_signalinfo_t siginfo;
  siginfo.rate = rate;
  siginfo.precision = bits_per_sample;
  siginfo.channels = SOX_UNSPEC;
#ifdef SOX_UNKNOWN_LEN
  siginfo.length = SOX_UNKNOWN_LEN;
#else
  siginfo.length = -1;
#endif

  const char* extension = lsx_find_file_extension(filename);

  if (bob::io::audio::SUPPORTED_FORMATS.find(extension-1) ==
      bob::io::audio::SUPPORTED_FORMATS.end()) { //unsupported file format
    boost::format m("file `%s' cannot be written by SoX (file format `%d' is unsupported -- use `sox --help-format all' for a list of all supported formats");
    m % filename % extension;
    throw std::runtime_error(m.str());
  }

  sox_format_t* f = 0;
  if (encoding == SOX_ENCODING_UNKNOWN) {
    f = sox_open_write(filename, &siginfo, 0, extension, 0, 0);
  }
  else {
    sox_encodinginfo_t encoding_info;
    encoding_info.encoding = encoding;
    encoding_info.bits_per_sample = bits_per_sample;
    encoding_info.compression = HUGE_VAL;
    f = sox_open_write(filename, &siginfo, &encoding_info, 0, 0, 0);
  }

  if (!f) {
    boost::format m("file `%s' is not writeable by SoX (internal call to `sox_open_write()' failed) -- we suggest you check writing permissions and existence of leading paths");
    m % filename;
    throw std::runtime_error(m.str());
  }

  m_file = boost::shared_ptr<sox_format_t>(f, std::ptr_fun(bob::io::audio::close_sox_file));

  m_typeinfo.dtype = bob::io::base::array::t_float64;
  m_typeinfo.nd = 2;
  m_typeinfo.shape[0] = 0;
  m_typeinfo.shape[1] = 0;
  m_typeinfo.update_strides();

  m_buffer = boost::shared_array<sox_sample_t>(new sox_sample_t[m_typeinfo.shape[0]]);

  m_opened = true; ///< file is now considered opened for business
}
예제 #3
0
sox_format_t * sox_open_read(
    char               const * path,
    sox_signalinfo_t   const * signal,
    sox_encodinginfo_t const * encoding,
    char               const * filetype)
{
  sox_format_t * ft = lsx_calloc(1, sizeof(*ft));
  sox_format_handler_t const * handler;
  char const * const io_types[] = {"file", "pipe", "file URL"};
  char const * type = "";
  size_t   input_bufsiz = sox_globals.input_bufsiz?
      sox_globals.input_bufsiz : sox_globals.bufsiz;

  if (filetype) {
    if (!(handler = sox_find_format(filetype, sox_false))) {
      lsx_fail("no handler for given file type `%s'", filetype);
      goto error;
    }
    ft->handler = *handler;
  }

  if (!(ft->handler.flags & SOX_FILE_NOSTDIO)) {
    if (!strcmp(path, "-")) { /* Use stdin if the filename is "-" */
      if (sox_globals.stdin_in_use_by) {
        lsx_fail("`-' (stdin) already in use by `%s'", sox_globals.stdin_in_use_by);
        goto error;
      }
      sox_globals.stdin_in_use_by = "audio input";
      SET_BINARY_MODE(stdin);
      ft->fp = stdin;
    }
    else {
      ft->fp = xfopen(path, "rb", &ft->io_type);
      type = io_types[ft->io_type];
      if (ft->fp == NULL) {
        lsx_fail("can't open input %s `%s': %s", type, path, strerror(errno));
        goto error;
      }
    }
    if (setvbuf (ft->fp, NULL, _IOFBF, sizeof(char) * input_bufsiz)) {
      lsx_fail("Can't set read buffer");
      goto error;
    }
    ft->seekable = is_seekable(ft);
  }

  if (!filetype) {
    if (ft->seekable) {
      filetype = auto_detect_format(ft, lsx_find_file_extension(path));
      lsx_rewind(ft);
    }
#ifndef NO_REWIND_PIPE
    else if (!(ft->handler.flags & SOX_FILE_NOSTDIO) &&
        input_bufsiz >= AUTO_DETECT_SIZE) {
      filetype = auto_detect_format(ft, lsx_find_file_extension(path));
      rewind_pipe(ft->fp);
      ft->tell_off = 0;
    }
#endif

    if (filetype) {
      lsx_report("detected file format type `%s'", filetype);
      if (!(handler = sox_find_format(filetype, sox_false))) {
        lsx_fail("no handler for detected file type `%s'", filetype);
        goto error;
      }
    }
    else {
      if (ft->io_type == lsx_io_pipe) {
        filetype = "sox"; /* With successful pipe rewind, this isn't useful */
        lsx_report("assuming input pipe `%s' has file-type `sox'", path);
      }
      else if (!(filetype = lsx_find_file_extension(path))) {
        lsx_fail("can't determine type of %s `%s'", type, path);
        goto error;
      }
      if (!(handler = sox_find_format(filetype, sox_true))) {
        lsx_fail("no handler for file extension `%s'", filetype);
        goto error;
      }
    }
    ft->handler = *handler;
    if (ft->handler.flags & SOX_FILE_NOSTDIO) {
      xfclose(ft->fp, ft->io_type);
      ft->fp = NULL;
    }
  }
  if (!ft->handler.startread && !ft->handler.read) {
    lsx_fail("file type `%s' isn't readable", filetype);
    goto error;
  }

  ft->mode = 'r';
  ft->filetype = lsx_strdup(filetype);
  ft->filename = lsx_strdup(path);
  if (signal)
    ft->signal = *signal;

  if (encoding)
    ft->encoding = *encoding;
  else sox_init_encodinginfo(&ft->encoding);
  set_endiannesses(ft);

  if ((ft->handler.flags & SOX_FILE_DEVICE) && !(ft->handler.flags & SOX_FILE_PHONY))
    lsx_set_signal_defaults(ft);

  ft->priv = lsx_calloc(1, ft->handler.priv_size);
  /* Read and write starters can change their formats. */
  if (ft->handler.startread && (*ft->handler.startread)(ft) != SOX_SUCCESS) {
    lsx_fail("can't open input %s `%s': %s", type, ft->filename, ft->sox_errstr);
    goto error;
  }

  /* Fill in some defaults: */
  if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
    ft->signal.precision = sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample);
  if (!(ft->handler.flags & SOX_FILE_PHONY) && !ft->signal.channels)
    ft->signal.channels = 1;

  if (sox_checkformat(ft) != SOX_SUCCESS) {
    lsx_fail("bad input format for %s `%s': %s", type, ft->filename, ft->sox_errstr);
    goto error;
  }

  if (signal) {
    if (signal->rate && signal->rate != ft->signal.rate)
      lsx_warn("can't set sample rate %g; using %g", signal->rate, ft->signal.rate);
    if (signal->channels && signal->channels != ft->signal.channels)
      lsx_warn("can't set %u channels; using %u", signal->channels, ft->signal.channels);
  }
  return ft;

error:
  if (ft->fp && ft->fp != stdin)
    xfclose(ft->fp, ft->io_type);
  free(ft->priv);
  free(ft->filename);
  free(ft->filetype);
  free(ft);
  return NULL;
}