示例#1
0
文件: formats.c 项目: dmkrepo/libsox
void sox_append_comment(sox_comments_t * comments, char const * comment)
{
  size_t n = sox_num_comments(*comments);
  *comments = lsx_realloc(*comments, (n + 2) * sizeof(**comments));
  assert(comment);
  (*comments)[n++] = lsx_strdup(comment);
  (*comments)[n] = 0;
}
示例#2
0
文件: pad.c 项目: damien78/sox
static int parse(sox_effect_t * effp, char * * argv, sox_rate_t rate)
{
  priv_t * p = (priv_t *)effp->priv;
  char const * next;
  unsigned i;
  uint64_t last_seen = 0;
  const uint64_t in_length = argv ? 0 :
    (effp->in_signal.length != SOX_UNKNOWN_LEN ?
     effp->in_signal.length / effp->in_signal.channels : SOX_UNKNOWN_LEN);
  uint64_t pad_len = 0;
  uint64_t *arg;
  char *str;

  for (i = 0; i < p->npads; ++i) {
    if (argv) /* 1st parse only */
      p->pads[i].str = lsx_strdup(argv[i]);
    str = p->pads[i].str;
    if (*str == '%') {
      str++;
      arg = &p->pads[i].align;
    } else {
      arg = &p->pads[i].pad;
    }
    next = lsx_parsesamples(rate, str, arg, 't');
    if (next == NULL) break;
    if (*next == '\0')
      p->pads[i].start = i? in_length : 0;
    else {
      if (*next != '@') break;
      next = lsx_parseposition(rate, next+1, argv ? NULL : &p->pads[i].start,
               last_seen, in_length, '=');
      if (next == NULL || *next != '\0') break;
      last_seen = p->pads[i].start;
      if (p->pads[i].start == SOX_UNKNOWN_LEN)
        p->pads[i].start = UINT64_MAX; /* currently the same value, but ... */
    }
    if (!argv) {
      if (p->pads[i].align && p->pads[i].start != UINT64_MAX) {
        p->pads[i].pad =
          pad_align(p->pads[i].start + pad_len, p->pads[i].align);
        p->pads[i].align = 0;
      }

      pad_len += p->pads[i].pad;

      /* Do this check only during the second pass when the actual
         sample rate is known, otherwise it might fail on legal
         commands like
           pad [email protected] 1@30000s
         if the rate is, e.g., 48k. */
      if (i > 0 && p->pads[i].start <= p->pads[i-1].start) break;
    }
  }
  if (i < p->npads)
    return lsx_usage(effp);
  return SOX_SUCCESS;
}
示例#3
0
文件: bend.c 项目: CaptainHayashi/sox
static int parse(sox_effect_t * effp, char **argv, sox_rate_t rate)
{
  priv_t *p = (priv_t *) effp->priv;
  size_t i;
  char const *next;
  uint64_t last_seen = 0;
  const uint64_t in_length = argv ? 0 :
    (effp->in_signal.length != SOX_UNKNOWN_LEN ?
     effp->in_signal.length / effp->in_signal.channels : SOX_UNKNOWN_LEN);

  for (i = 0; i < p->nbends; ++i) {
    if (argv)   /* 1st parse only */
      p->bends[i].str = lsx_strdup(argv[i]);

    next = lsx_parseposition(rate, p->bends[i].str,
             argv ? NULL : &p->bends[i].start, last_seen, in_length, '+');
    last_seen = p->bends[i].start;
    if (next == NULL || *next != ',')
      break;

    p->bends[i].cents = strtod(next + 1, (char **)&next);
    if (p->bends[i].cents == 0 || *next != ',')
      break;

    next = lsx_parseposition(rate, next + 1,
             argv ? NULL : &p->bends[i].duration, last_seen, in_length, '+');
    last_seen = p->bends[i].duration;
    if (next == NULL || *next != '\0')
      break;

    /* sanity checks */
    if (!argv && p->bends[i].duration < p->bends[i].start) {
      lsx_fail("Bend %" PRIuPTR " has negative width", i+1);
      break;
    }
    if (!argv && i && p->bends[i].start < p->bends[i-1].start) {
      lsx_fail("Bend %" PRIuPTR " overlaps with previous one", i+1);
      break;
    }

    p->bends[i].duration -= p->bends[i].start;
  }
  if (i < p->nbends)
    return lsx_usage(effp);
  return SOX_SUCCESS;
}
示例#4
0
文件: crop.c 项目: Amalerd/SoxPlayer
static int parse(sox_effect_t * effp, char * * argv, sox_rate_t rate)
{
  priv_t * p = (priv_t *)effp->priv;
  char const * s, * q;
  int i;

  for (i = p->argc - 1; i == 0 || i == 1; --i) {
    if (argv) /* 1st parse only */
      p->pos[i].str = lsx_strdup(argv[i]);
    s = p->pos[i].str;
    if (strchr("+-" + 1 - i, *s))
      p->pos[i].flag = *s++;
    if (!(q = lsx_parsesamples(rate, s, &p->pos[i].at, 't')) || *q)
      break;
  }
  return i >= 0 ? lsx_usage(effp) : SOX_SUCCESS;
}
示例#5
0
static int create(sox_effect_t * effp, int argc, char * * argv)
{
  priv_t * p = (priv_t *)effp->priv;
  size_t delay, max_samples = 0;
  unsigned i;

  --argc, ++argv;
  p->argv = lsx_calloc(p->argc = argc, sizeof(*p->argv));
  for (i = 0; i < p->argc; ++i) {
    char const * next = lsx_parsesamples(1e5, p->argv[i] = lsx_strdup(argv[i]), &delay, 't');
    if (!next || *next) {
      kill(effp);
      return lsx_usage(effp);
    }
    if (delay > max_samples) {
      max_samples = delay;
      p->max_arg = p->argv[i];
    }
  }
  return SOX_SUCCESS;
}
示例#6
0
static int parse(sox_effect_t * effp, char * * argv, sox_rate_t rate)
{
    priv_t * p = (priv_t *)effp->priv;
    char const * next;
    unsigned i;

    for (i = 0; i < p->npads; ++i) {
        if (argv) /* 1st parse only */
            p->pads[i].str = lsx_strdup(argv[i]);
        next = lsx_parsesamples(rate, p->pads[i].str, &p->pads[i].pad, 't');
        if (next == NULL) break;
        if (*next == '\0')
            p->pads[i].start = i? SOX_SIZE_MAX : 0;
        else {
            if (*next != '@') break;
            next = lsx_parsesamples(rate, next+1, &p->pads[i].start, 't');
            if (next == NULL || *next != '\0') break;
        }
        if (i > 0 && p->pads[i].start <= p->pads[i-1].start) break;
    }
    if (i < p->npads)
        return lsx_usage(effp);
    return SOX_SUCCESS;
}
示例#7
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;
}
示例#8
0
文件: fade.c 项目: CaptainHayashi/sox
static int sox_fade_getopts(sox_effect_t * effp, int argc, char **argv)
{

    priv_t * fade = (priv_t *) effp->priv;
    char t_char[2];
    int t_argno;
    uint64_t samples;
    const char *n;
  --argc, ++argv;

    if (argc < 1 || argc > 4)
         return lsx_usage(effp);

    /* because sample rate is unavailable at this point we store the
     * string off for later computations.
     */

    if (sscanf(argv[0], "%1[qhltp]", t_char))
    {
        fade->in_fadetype = *t_char;
        fade->out_fadetype = *t_char;

        argv++;
        argc--;
    }
    else
    {
        /* No type given. */
        fade->in_fadetype = 'l';
        fade->out_fadetype = 'l';
    }

    fade->in_stop_str = lsx_strdup(argv[0]);
    /* Do a dummy parse to see if it will fail */
    n = lsx_parsesamples(0., fade->in_stop_str, &samples, 't');
    if (!n || *n)
      return lsx_usage(effp);

    fade->in_stop = samples;
    fade->out_start_str = fade->out_stop_str = 0;

    for (t_argno = 1; t_argno < argc && t_argno < 3; t_argno++)
    {
        /* See if there is fade-in/fade-out times/curves specified. */
        if(t_argno == 1)
        {
            fade->out_stop_str = lsx_strdup(argv[t_argno]);

            /* Do a dummy parse to see if it will fail */
            n = lsx_parseposition(0., fade->out_stop_str, NULL, (uint64_t)0, (uint64_t)0, '=');
            if (!n || *n)
              return lsx_usage(effp);
            fade->out_stop = samples;
        }
        else
        {
            fade->out_start_str = lsx_strdup(argv[t_argno]);

            /* Do a dummy parse to see if it will fail */
            n = lsx_parsesamples(0., fade->out_start_str, &samples, 't');
            if (!n || *n)
              return lsx_usage(effp);
            fade->out_start = samples;
        }
    } /* End for(t_argno) */

    return(SOX_SUCCESS);
}
示例#9
0
static int sox_silence_getopts(sox_effect_t * effp, int argc, char **argv)
{
    priv_t *   silence = (priv_t *) effp->priv;
    int parse_count;
    uint64_t temp;
    const char *n;
  --argc, ++argv;

    /* check for option switches */
    silence->leave_silence = sox_false;
    if (argc > 0)
    {
        if (!strcmp("-l", *argv)) {
            argc--; argv++;
            silence->leave_silence = sox_true;
        }
    }

    if (argc < 1)
      return lsx_usage(effp);

    /* Parse data related to trimming front side */
    silence->start = sox_false;
    if (sscanf(argv[0], "%d", &silence->start_periods) != 1)
      return lsx_usage(effp);
    if (silence->start_periods < 0)
    {
        lsx_fail("Periods must not be negative");
        return(SOX_EOF);
    }
    argv++;
    argc--;

    if (silence->start_periods > 0)
    {
        silence->start = sox_true;
        if (argc < 2)
          return lsx_usage(effp);

        /* We do not know the sample rate so we can not fully
         * parse the duration info yet.  So save argument off
         * for future processing.
         */
        silence->start_duration_str = lsx_strdup(argv[0]);
        /* Perform a fake parse to do error checking */
        n = lsx_parsesamples(0.,silence->start_duration_str,&temp,'s');
        if (!n || *n)
          return lsx_usage(effp);
        silence->start_duration = temp;

        parse_count = sscanf(argv[1], "%lf%c", &silence->start_threshold,
                &silence->start_unit);
        if (parse_count < 1)
          return lsx_usage(effp);
        else if (parse_count < 2)
            silence->start_unit = '%';

        argv++; argv++;
        argc--; argc--;
    }

    silence->stop = sox_false;
    /* Parse data needed for trimming of backside */
    if (argc > 0)
    {
        if (argc < 3)
          return lsx_usage(effp);
        if (sscanf(argv[0], "%d", &silence->stop_periods) != 1)
          return lsx_usage(effp);
        if (silence->stop_periods < 0)
        {
            silence->stop_periods = -silence->stop_periods;
            silence->restart = 1;
        }
        else
            silence->restart = 0;
        silence->stop = sox_true;
        argv++;
        argc--;

        /* We do not know the sample rate so we can not fully
         * parse the duration info yet.  So save argument off
         * for future processing.
         */
        silence->stop_duration_str = lsx_strdup(argv[0]);
        /* Perform a fake parse to do error checking */
        n = lsx_parsesamples(0.,silence->stop_duration_str,&temp,'s');
        if (!n || *n)
          return lsx_usage(effp);
        silence->stop_duration = temp;

        parse_count = sscanf(argv[1], "%lf%c", &silence->stop_threshold,
                             &silence->stop_unit);
        if (parse_count < 1)
          return lsx_usage(effp);
        else if (parse_count < 2)
            silence->stop_unit = '%';

        argv++; argv++;
        argc--; argc--;
    }

    /* Error checking */
    if (silence->start)
    {
        if ((silence->start_unit != '%') && (silence->start_unit != 'd'))
        {
            lsx_fail("Invalid unit specified");
            return lsx_usage(effp);
        }
        if ((silence->start_unit == '%') && ((silence->start_threshold < 0.0)
            || (silence->start_threshold > 100.0)))
        {
            lsx_fail("silence threshold should be between 0.0 and 100.0 %%");
            return (SOX_EOF);
        }
        if ((silence->start_unit == 'd') && (silence->start_threshold >= 0.0))
        {
            lsx_fail("silence threshold should be less than 0.0 dB");
            return(SOX_EOF);
        }
    }

    if (silence->stop)
    {
        if ((silence->stop_unit != '%') && (silence->stop_unit != 'd'))
        {
            lsx_fail("Invalid unit specified");
            return(SOX_EOF);
        }
        if ((silence->stop_unit == '%') && ((silence->stop_threshold < 0.0) ||
                    (silence->stop_threshold > 100.0)))
        {
            lsx_fail("silence threshold should be between 0.0 and 100.0 %%");
            return (SOX_EOF);
        }
        if ((silence->stop_unit == 'd') && (silence->stop_threshold >= 0.0))
        {
            lsx_fail("silence threshold should be less than 0.0 dB");
            return(SOX_EOF);
        }
    }
    return(SOX_SUCCESS);
}