Example #1
0
static int check_read_params(sox_format_t * ft, unsigned channels,
    sox_rate_t rate, sox_encoding_t encoding, unsigned bits_per_sample, off_t length)
{
  ft->signal.length = length;

  if (channels && ft->signal.channels && ft->signal.channels != channels)
    lsx_warn("`%s': overriding number of channels", ft->filename);
  else ft->signal.channels = channels;

  if (rate && ft->signal.rate && ft->signal.rate != rate)
    lsx_warn("`%s': overriding sample rate", ft->filename);
  else ft->signal.rate = rate;

  if (encoding && ft->encoding.encoding && ft->encoding.encoding != encoding)
    lsx_warn("`%s': overriding encoding type", ft->filename);
  else ft->encoding.encoding = encoding;

  if (bits_per_sample && ft->encoding.bits_per_sample && ft->encoding.bits_per_sample != bits_per_sample)
    lsx_warn("`%s': overriding encoding size", ft->filename);
  ft->encoding.bits_per_sample = bits_per_sample;

  if (sox_precision(ft->encoding.encoding, ft->encoding.bits_per_sample))
    return SOX_SUCCESS;
  lsx_fail_errno(ft, EINVAL, "invalid format for this file type");
  return SOX_EOF;
}
Example #2
0
static int recover(sox_format_t * ft, snd_pcm_t * pcm, int err)
{
  if (err == -EPIPE)
    lsx_warn("%s-run", ft->mode == 'r'? "over" : "under");
  else if (err != -ESTRPIPE)
    lsx_warn("%s", snd_strerror(err));
  else while ((err = snd_pcm_resume(pcm)) == -EAGAIN) {
    lsx_report("suspended");
    sleep(1);                  /* Wait until the suspend flag is released */
  }
  if (err < 0 && (err = snd_pcm_prepare(pcm)) < 0)
    lsx_fail_errno(ft, SOX_EPERM, "%s", snd_strerror(err));
  return err;
}
Example #3
0
static void FLAC__decoder_metadata_callback(FLAC__StreamDecoder const * const flac, FLAC__StreamMetadata const * const metadata, void * const client_data)
{
  sox_format_t * ft = (sox_format_t *) client_data;
  priv_t * p = (priv_t *)ft->priv;

  (void) flac;

  if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
    p->bits_per_sample = metadata->data.stream_info.bits_per_sample;
    p->channels = metadata->data.stream_info.channels;
    p->sample_rate = metadata->data.stream_info.sample_rate;
    p->total_samples = metadata->data.stream_info.total_samples;
  }
  else if (metadata->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
    size_t i;

    if (metadata->data.vorbis_comment.num_comments == 0)
      return;

    if (ft->oob.comments != NULL) {
      lsx_warn("multiple Vorbis comment block ignored");
      return;
    }

    for (i = 0; i < metadata->data.vorbis_comment.num_comments; ++i)
      sox_append_comment(&ft->oob.comments, (char const *) metadata->data.vorbis_comment.comments[i].entry);
  }
}
Example #4
0
static int stop(sox_effect_t * effp)
{
  priv_t * p = (priv_t *)effp->priv;
  if (p->pos[0].at || (p->pos[1].at && p->argc == 2))
    lsx_warn("input audio was too short to crop as requested");
  return SOX_SUCCESS;
}
Example #5
0
static int select_format(
    sox_encoding_t              * encoding_,
    unsigned                    * nbits_,
    snd_pcm_format_mask_t const * mask,
    int                         * format)
{
  unsigned can_do[NSIZES], i, j, index = (*nbits_ >> 3) - 1, nbits;
  sox_encoding_t encoding = *encoding_;

  for (i = 0; i < NSIZES; ++i) for (can_do[i] = 0, j = 0; j < 2; ++j)
    can_do[i] |= snd_pcm_format_mask_test(mask, formats[j][i]);

  if (index >= NSIZES ||
      (encoding != SOX_ENCODING_SIGN2 && encoding != SOX_ENCODING_UNSIGNED)){
    encoding = SOX_ENCODING_SIGN2;
    index = 2;
  }
  while (!can_do[index]) if (++index == NSIZES)           /* Search up */
    for (--index; !can_do[index];) if (--index >= NSIZES) /* then down */
      return -1;
  nbits = (index + 1) << 3;

  if (encoding == SOX_ENCODING_SIGN2 &&
      !snd_pcm_format_mask_test(mask, formats[0][index]))
    encoding = SOX_ENCODING_UNSIGNED;

  if (*nbits_ != nbits || *encoding_ != encoding) {
    lsx_warn("can't encode %u-bit %s", *nbits_,
        sox_encodings_info[*encoding_].desc);
    *nbits_ = nbits;
    *encoding_ = encoding;
  }
  *format = formats[encoding == SOX_ENCODING_UNSIGNED][index];
  return 0;
}
Example #6
0
File: pad.c Project: damien78/sox
static int stop(sox_effect_t * effp)
{
  priv_t * p = (priv_t *)effp->priv;
  if (p->pads_pos != p->npads)
    lsx_warn("Input audio too short; pads not applied: %u", p->npads-p->pads_pos);
  return SOX_SUCCESS;
}
Example #7
0
static int stop_read(sox_format_t * const ft)
{
  priv_t * p = (priv_t *)ft->priv;
  if (!FLAC__stream_decoder_finish(p->decoder) && p->eof)
    lsx_warn("decoder MD5 checksum mismatch.");
  FLAC__stream_decoder_delete(p->decoder);
  return SOX_SUCCESS;
}
Example #8
0
/*
 * Do anything required when you stop reading samples.
 * Don't close input file!
 */
static int sox_dcshift_stop(sox_effect_t * effp)
{
    priv_t * dcs = (priv_t *) effp->priv;

    if (dcs->limited)
    {
        lsx_warn("DCSHIFT limited %" PRIu64 " values (%d percent).",
             dcs->limited, (int) (dcs->limited * 100.0 / dcs->totalprocessed));
    }
    return SOX_SUCCESS;
}
Example #9
0
static int startwrite(sox_format_t * ft)
{
  priv_t * sf = (priv_t *)ft->priv;
  start(ft);
  /* If output format is invalid, try to find a sensible default */
  if (!sf_format_check(sf->sf_info)) {
    SF_FORMAT_INFO format_info;
    int i, count;

    sf_command(sf->sf_file, SFC_GET_SIMPLE_FORMAT_COUNT, &count, (int) sizeof(int));
    for (i = 0; i < count; i++) {
      format_info.format = i;
      sf_command(sf->sf_file, SFC_GET_SIMPLE_FORMAT, &format_info, (int) sizeof(format_info));
      if ((format_info.format & SF_FORMAT_TYPEMASK) == (sf->sf_info->format & SF_FORMAT_TYPEMASK)) {
        sf->sf_info->format = format_info.format;
        /* FIXME: Print out exactly what we chose, needs sndfile ->
           sox encoding conversion functions */
        break;
      }
    }

    if (!sf_format_check(sf->sf_info)) {
      lsx_fail("cannot find a usable output encoding");
      return SOX_EOF;
    }
    if ((sf->sf_info->format & SF_FORMAT_TYPEMASK) != SF_FORMAT_RAW)
      lsx_warn("cannot use desired output encoding, choosing default");
  }

  sf->sf_file = sf_open_fd(fileno(ft->fp), SFM_WRITE, sf->sf_info, 1);
  ft->fp = NULL; /* Transfer ownership of fp to LSF */
  drain_log_buffer(ft);

  if (sf->sf_file == NULL) {
    memset(ft->sox_errstr, 0, sizeof(ft->sox_errstr));
    strncpy(ft->sox_errstr, sf_strerror(sf->sf_file), sizeof(ft->sox_errstr)-1);
    free(sf->sf_file);
    return SOX_EOF;
  }

#ifdef HAVE_SFC_SET_SCALE_INT_FLOAT_WRITE
  if ((sf->sf_info->format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT)
    sf_command(sf->sf_file, SFC_SET_SCALE_INT_FLOAT_WRITE, NULL, SF_TRUE);
#endif
           
  return SOX_SUCCESS;
}
Example #10
0
/*
 * Open file in sndfile.
 */
static int startread(sox_format_t * ft)
{
  priv_t * sf = (priv_t *)ft->priv;
  unsigned bits_per_sample;
  sox_encoding_t encoding;
  sox_rate_t rate;

  start(ft);

  sf->sf_file = sf_open_fd(fileno(ft->fp), SFM_READ, sf->sf_info, 1);
  ft->fp = NULL; /* Transfer ownership of fp to LSF */
  drain_log_buffer(ft);

  if (sf->sf_file == NULL) {
    memset(ft->sox_errstr, 0, sizeof(ft->sox_errstr));
    strncpy(ft->sox_errstr, sf_strerror(sf->sf_file), sizeof(ft->sox_errstr)-1);
    free(sf->sf_file);
    return SOX_EOF;
  }

  if (!(encoding = sox_enc(sf->sf_info->format, &bits_per_sample))) {
    lsx_fail_errno(ft, SOX_EFMT, "unsupported sndfile encoding %#x", sf->sf_info->format);
    return SOX_EOF;
  }

  /* Don't believe LSF's rate for raw files */
  if ((sf->sf_info->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_RAW && !ft->signal.rate) {
    lsx_warn("`%s': sample rate not specified; trying 8kHz", ft->filename);
    rate = 8000;
  }
  else rate = sf->sf_info->samplerate;

#ifdef HAVE_SFC_SET_SCALE_FLOAT_INT_READ
  if ((sf->sf_info->format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT) {
    sf_command(sf->sf_file, SFC_SET_SCALE_FLOAT_INT_READ, NULL, SF_TRUE);
    sf_command(sf->sf_file, SFC_SET_CLIPPING, NULL, SF_TRUE);
  }
#endif

#if 0 /* FIXME */
    sox_append_comments(&ft->oob.comments, buf);
#endif

  return check_read_params(ft, (unsigned)sf->sf_info->channels, rate,
      encoding, bits_per_sample, (off_t)(sf->sf_info->frames * sf->sf_info->channels));
}
Example #11
0
int lsx_dvmsstartwrite(sox_format_t * ft)
{
        struct dvms_header hdr;
        int rc;

        rc = lsx_cvsdstartwrite(ft);
        if (rc)
            return rc;

        make_dvms_hdr(ft, &hdr);
        rc = dvms_write_header(ft, &hdr);
        if (rc){
                lsx_fail_errno(ft,rc,"cannot write DVMS header");
            return rc;
        }

        if (!ft->seekable)
               lsx_warn("Length in output .DVMS header will wrong since can't seek to fix it");

        return(SOX_SUCCESS);
}
Example #12
0
/*
 * Drain LSF's wonderful log buffer
 */
static void drain_log_buffer(sox_format_t * ft)
{
  priv_t * sf = (priv_t *)ft->priv;
  sf_command(sf->sf_file, SFC_GET_LOG_INFO, sf->log_buffer, LOG_MAX);
  while (*sf->log_buffer_ptr) {
    static char const warning_prefix[] = "*** Warning : ";
    char const * end = strchr(sf->log_buffer_ptr, '\n');
    if (!end)
      end = strchr(sf->log_buffer_ptr, '\0');
    if (!strncmp(sf->log_buffer_ptr, warning_prefix, strlen(warning_prefix))) {
      sf->log_buffer_ptr += strlen(warning_prefix);
      lsx_warn("`%s': %.*s",
          ft->filename, (int)(end - sf->log_buffer_ptr), sf->log_buffer_ptr);
    } else
      lsx_debug("`%s': %.*s",
          ft->filename, (int)(end - sf->log_buffer_ptr), sf->log_buffer_ptr);
    sf->log_buffer_ptr = end;
    if (*sf->log_buffer_ptr == '\n')
      ++sf->log_buffer_ptr;
  }
}
Example #13
0
/*
 * Start processing
 */
static int sox_trim_start(sox_effect_t * effp)
{
    priv_t * trim = (priv_t *) effp->priv;

    if (lsx_parsesamples(effp->in_signal.rate, trim->start_str,
                        &trim->start, 't') == NULL)
      return lsx_usage(effp);

    if (trim->end_str)
    {
        if (lsx_parsesamples(effp->in_signal.rate, trim->end_str,
                    &trim->length, 't') == NULL)
          return lsx_usage(effp);
        if (trim->end_is_absolute) {
            if (trim->length < trim->start) {
                lsx_warn("end earlier than start");
                trim->length = 0;
                  /* with trim->end_str != NULL, this really means zero */
            } else
                trim->length -= trim->start;
        }
    }
    else
        trim->length = 0;
          /* with trim->end_str == NULL, this means indefinite length */

    lsx_debug("start at %lus, length %lu", trim->start, trim->length);

    /* Account for # of channels */
    trim->start *= effp->in_signal.channels;
    trim->length *= effp->in_signal.channels;

    trim->index = 0;
    trim->trimmed = 0;

    effp->out_signal.length = trim->length;
    return (SOX_SUCCESS);
}
Example #14
0
/*
 * Drain out remaining samples if the effect generates any.
 */
static int sox_fade_drain(sox_effect_t * effp, sox_sample_t *obuf, size_t *osamp)
{
    priv_t * fade = (priv_t *) effp->priv;
    int len;
    size_t t_chan = 0;

    len = *osamp;
    len -= len % effp->in_signal.channels;
    *osamp = 0;

    if (fade->do_out && fade->samplesdone < fade->out_stop &&
        !(fade->endpadwarned))
    { /* Warning about padding silence into end of sample */
        lsx_warn("End time past end of audio. Padding with silence");
        fade->endpadwarned = 1;
    } /* endif endpadwarned */

    for (;len && (fade->do_out &&
                  fade->samplesdone < fade->out_stop); len--)
    {
        *obuf = 0;
        obuf++;
        *osamp += 1;

        t_chan++;
        if (t_chan >= effp->in_signal.channels)
        {
            fade->samplesdone += 1;
            t_chan = 0;
        } /* endif channels */
    } /* endfor */

    if (fade->do_out && fade->samplesdone >= fade->out_stop)
        return SOX_EOF;
    else
        return SOX_SUCCESS;
}
Example #15
0
int lsx_dvmsstopwrite(sox_format_t * ft)
{
        struct dvms_header hdr;
        int rc;

        lsx_cvsdstopwrite(ft);
        if (!ft->seekable)
        {
            lsx_warn("File not seekable");
            return (SOX_EOF);
        }
        if (lsx_seeki(ft, (off_t)0, 0) != 0)
        {
                lsx_fail_errno(ft,errno,"Can't rewind output file to rewrite DVMS header.");
                return(SOX_EOF);
        }
        make_dvms_hdr(ft, &hdr);
        rc = dvms_write_header(ft, &hdr);
        if(rc){
            lsx_fail_errno(ft,rc,"cannot write DVMS header");
            return rc;
        }
        return rc;
}
Example #16
0
static int sox_mp3seek(sox_format_t * ft, uint64_t offset)
{
  priv_t   * p = (priv_t *) ft->priv;
  size_t   initial_bitrate = p->Frame.header.bitrate;
  size_t   tagsize = 0, consumed = 0;
  sox_bool vbr = sox_false; /* Variable Bit Rate */
  sox_bool depadded = sox_false;
  uint64_t to_skip_samples = 0;

  /* Reset all */
  rewind((FILE*)ft->fp);
  mad_timer_reset(&p->Timer);
  p->FrameCount = 0;

  /* They where opened in startread */
  mad_synth_finish(&p->Synth);
  p->mad_frame_finish(&p->Frame);
  p->mad_stream_finish(&p->Stream);

  p->mad_stream_init(&p->Stream);
  p->mad_frame_init(&p->Frame);
  p->mad_synth_init(&p->Synth);

  offset /= ft->signal.channels;
  to_skip_samples = offset;

  while(sox_true) {  /* Read data from the MP3 file */
    int read, padding = 0;
    size_t leftover = p->Stream.bufend - p->Stream.next_frame;

    memcpy(p->mp3_buffer, p->Stream.this_frame, leftover);
    read = fread(p->mp3_buffer + leftover, (size_t) 1, p->mp3_buffer_size - leftover, (FILE*)ft->fp);
    if (read <= 0) {
      lsx_debug("seek failure. unexpected EOF (frames=%" PRIuPTR " leftover=%" PRIuPTR ")", p->FrameCount, leftover);
      break;
    }
    for (; !depadded && padding < read && !p->mp3_buffer[padding]; ++padding);
    depadded = sox_true;
    p->mad_stream_buffer(&p->Stream, p->mp3_buffer + padding, leftover + read - padding);

    while (sox_true) {  /* Decode frame headers */
      static unsigned short samples;
      p->Stream.error = MAD_ERROR_NONE;

      /* Not an audio frame */
      if (p->mad_header_decode(&p->Frame.header, &p->Stream) == -1) {
        if (p->Stream.error == MAD_ERROR_BUFLEN)
          break;  /* Normal behaviour; get some more data from the file */
        if (!MAD_RECOVERABLE(p->Stream.error)) {
          lsx_warn("unrecoverable MAD error");
          break;
        }
        if (p->Stream.error == MAD_ERROR_LOSTSYNC) {
          unsigned available = (p->Stream.bufend - p->Stream.this_frame);
          tagsize = tagtype(p->Stream.this_frame, (size_t) available);
          if (tagsize) {   /* It's some ID3 tags, so just skip */
            if (tagsize >= available) {
              fseeko((FILE*)ft->fp, (off_t)(tagsize - available), SEEK_CUR);
              depadded = sox_false;
            }
            p->mad_stream_skip(&p->Stream, min(tagsize, available));
          }
          else lsx_warn("MAD lost sync");
        }
        else lsx_warn("recoverable MAD error");
        continue;
      }

      consumed += p->Stream.next_frame - p->Stream.this_frame;
      vbr      |= (p->Frame.header.bitrate != initial_bitrate);

      samples = 32 * MAD_NSBSAMPLES(&p->Frame.header);

      p->FrameCount++;
      p->mad_timer_add(&p->Timer, p->Frame.header.duration);

      if(to_skip_samples <= samples)
      {
        p->mad_frame_decode(&p->Frame,&p->Stream);
        p->mad_synth_frame(&p->Synth, &p->Frame);
        p->cursamp = to_skip_samples;
        return SOX_SUCCESS;
      }
      else to_skip_samples -= samples;

      /* If not VBR, we can extrapolate frame size */
      if (p->FrameCount == 64 && !vbr) {
        p->FrameCount = offset / samples;
        to_skip_samples = offset % samples;

        if (SOX_SUCCESS != lsx_seeki(ft, (off_t)(p->FrameCount * consumed / 64 + tagsize), SEEK_SET))
          return SOX_EOF;

        /* Reset Stream for refilling buffer */
        p->mad_stream_finish(&p->Stream);
        p->mad_stream_init(&p->Stream);
        break;
      }
    }
  };

  return SOX_EOF;
}
Example #17
0
/* common r/w initialization code */
static int ossinit(sox_format_t * ft)
{
    int sampletype, samplesize, dsp_stereo;
    int tmp, rc;
    priv_t *file = (priv_t *)ft->priv;

    if (ft->encoding.bits_per_sample == 8) {
        sampletype = AFMT_U8;
        samplesize = 8;
        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
            ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
        if (ft->encoding.encoding != SOX_ENCODING_UNSIGNED) {
            lsx_report("OSS driver only supports unsigned with bytes");
            lsx_report("Forcing to unsigned");
            ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
        }
    }
    else if (ft->encoding.bits_per_sample == 16) {
        /* Attempt to use endian that user specified */
        if (ft->encoding.reverse_bytes)
            sampletype = (MACHINE_IS_BIGENDIAN) ? AFMT_S16_LE : AFMT_S16_BE;
        else
            sampletype = (MACHINE_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
        samplesize = 16;
        if (ft->encoding.encoding == SOX_ENCODING_UNKNOWN)
            ft->encoding.encoding = SOX_ENCODING_SIGN2;
        if (ft->encoding.encoding != SOX_ENCODING_SIGN2) {
            lsx_report("OSS driver only supports signed with words");
            lsx_report("Forcing to signed linear");
            ft->encoding.encoding = SOX_ENCODING_SIGN2;
        }
    }
    else {
        /* Attempt to use endian that user specified */
        if (ft->encoding.reverse_bytes)
            sampletype = (MACHINE_IS_BIGENDIAN) ? AFMT_S16_LE : AFMT_S16_BE;
        else
            sampletype = (MACHINE_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
        samplesize = 16;
        ft->encoding.bits_per_sample = 16;
        ft->encoding.encoding = SOX_ENCODING_SIGN2;
        lsx_report("OSS driver only supports bytes and words");
        lsx_report("Forcing to signed linear word");
    }

    if (ft->signal.channels > 2) ft->signal.channels = 2;

    if (ioctl(fileno(ft->fp), (size_t) SNDCTL_DSP_RESET, 0) < 0)
    {
        lsx_fail_errno(ft,SOX_EOF,"Unable to reset OSS driver.  Possibly accessing an invalid file/device");
        return(SOX_EOF);
    }

    /* Query the supported formats and find the best match
     */
    rc = ioctl(fileno(ft->fp), SNDCTL_DSP_GETFMTS, &tmp);
    if (rc == 0) {
        if ((tmp & sampletype) == 0)
        {
            /* is 16-bit supported? */
            if (samplesize == 16 && (tmp & (AFMT_S16_LE|AFMT_S16_BE)) == 0)
            {
                /* Must not like 16-bits, try 8-bits */
                ft->encoding.bits_per_sample = 8;
                ft->encoding.encoding = SOX_ENCODING_UNSIGNED;
                lsx_report("OSS driver doesn't like signed words");
                lsx_report("Forcing to unsigned bytes");
                tmp = sampletype = AFMT_U8;
                samplesize = 8;
            }
            /* is 8-bit supported */
            else if (samplesize == 8 && (tmp & AFMT_U8) == 0)
            {
                ft->encoding.bits_per_sample = 16;
                ft->encoding.encoding = SOX_ENCODING_SIGN2;
                lsx_report("OSS driver doesn't like unsigned bytes");
                lsx_report("Forcing to signed words");
                sampletype = (MACHINE_IS_BIGENDIAN) ? AFMT_S16_BE : AFMT_S16_LE;
                samplesize = 16;
            }
            /* determine which 16-bit format to use */
            if (samplesize == 16 && (tmp & sampletype) == 0)
            {
                /* Either user requested something not supported
                 * or hardware doesn't support machine endian.
                 * Force to opposite as the above test showed
                 * it supports at least one of the two endians.
                 */
                sampletype = (sampletype == AFMT_S16_BE) ? AFMT_S16_LE : AFMT_S16_BE;
                ft->encoding.reverse_bytes = !ft->encoding.reverse_bytes;
            }

        }
        tmp = sampletype;
        rc = ioctl(fileno(ft->fp), SNDCTL_DSP_SETFMT, &tmp);
    }
    /* Give up and exit */
    if (rc < 0 || tmp != sampletype)
    {
        lsx_fail_errno(ft,SOX_EOF,"Unable to set the sample size to %d", samplesize);
        return (SOX_EOF);
    }

    if (ft->signal.channels == 2) dsp_stereo = 1;
    else dsp_stereo = 0;

    tmp = dsp_stereo;
    if (ioctl(fileno(ft->fp), SNDCTL_DSP_STEREO, &tmp) < 0)
    {
        lsx_warn("Couldn't set to %s", dsp_stereo?  "stereo":"mono");
        dsp_stereo = 0;
    }

    if (tmp != dsp_stereo)
        ft->signal.channels = tmp + 1;

    tmp = ft->signal.rate;
    if (ioctl (fileno(ft->fp), SNDCTL_DSP_SPEED, &tmp) < 0 ||
        (int)ft->signal.rate != tmp) {
        /* If the rate the sound card is using is not within 1% of what
         * the user specified then override the user setting.
         * The only reason not to always override this is because of
         * clock-rounding problems. Sound cards will sometimes use
         * things like 44101 when you ask for 44100.  No need overriding
         * this and having strange output file rates for something that
         * we can't hear anyways.
         */
        if ((int)ft->signal.rate - tmp > (tmp * .01) ||
            tmp - (int)ft->signal.rate > (tmp * .01))
            ft->signal.rate = tmp;
    }

    /* Find out block size to use last because the driver could compute
     * its size based on specific rates/formats.
     */
    file->size = 0;
    ioctl (fileno(ft->fp), SNDCTL_DSP_GETBLKSIZE, &file->size);
    if (file->size < 4 || file->size > 65536) {
            lsx_fail_errno(ft,SOX_EOF,"Invalid audio buffer size %lu", (unsigned long)file->size);
            return (SOX_EOF);
    }
    file->count = 0;
    file->pos = 0;
    file->buf = lsx_malloc(file->size);

    if (ioctl(fileno(ft->fp), (size_t) SNDCTL_DSP_SYNC, NULL) < 0) {
        lsx_fail_errno(ft,SOX_EOF,"Unable to sync dsp");
        return (SOX_EOF);
    }

    /* Change to non-buffered I/O */
    setvbuf(ft->fp, NULL, _IONBF, sizeof(char) * file->size);
    return(SOX_SUCCESS);
}
Example #18
0
/*
 * Prepare for processing.
 */
static int sox_echo_start(sox_effect_t * effp)
{
        priv_t * echo = (priv_t *) effp->priv;
        int i;
        float sum_in_volume;
        long j;

        echo->maxsamples = 0;
        if ( echo->in_gain < 0.0 )
        {
                lsx_fail("echo: gain-in must be positive!");
                return (SOX_EOF);
        }
        if ( echo->in_gain > 1.0 )
        {
                lsx_fail("echo: gain-in must be less than 1.0!");
                return (SOX_EOF);
        }
        if ( echo->out_gain < 0.0 )
        {
                lsx_fail("echo: gain-in must be positive!");
                return (SOX_EOF);
        }
        for ( i = 0; i < echo->num_delays; i++ ) {
                echo->samples[i] = echo->delay[i] * effp->in_signal.rate / 1000.0;
                if ( echo->samples[i] < 1 )
                {
                    lsx_fail("echo: delay must be positive!");
                    return (SOX_EOF);
                }
                if ( echo->samples[i] > (ptrdiff_t)DELAY_BUFSIZ )
                {
                        lsx_fail("echo: delay must be less than %g seconds!",
                                DELAY_BUFSIZ / effp->in_signal.rate );
                        return (SOX_EOF);
                }
                if ( echo->decay[i] < 0.0 )
                {
                    lsx_fail("echo: decay must be positive!" );
                    return (SOX_EOF);
                }
                if ( echo->decay[i] > 1.0 )
                {
                    lsx_fail("echo: decay must be less than 1.0!" );
                    return (SOX_EOF);
                }
                if ( echo->samples[i] > echo->maxsamples )
                        echo->maxsamples = echo->samples[i];
        }
        echo->delay_buf = lsx_malloc(sizeof (double) * echo->maxsamples);
        for ( j = 0; j < echo->maxsamples; ++j )
                echo->delay_buf[j] = 0.0;
        /* Be nice and check the hint with warning, if... */
        sum_in_volume = 1.0;
        for ( i = 0; i < echo->num_delays; i++ )
                sum_in_volume += echo->decay[i];
        if ( sum_in_volume * echo->in_gain > 1.0 / echo->out_gain )
                lsx_warn("echo: warning >>> gain-out can cause saturation of output <<<");
        echo->counter = 0;
        echo->fade_out = echo->maxsamples;

  effp->out_signal.length = SOX_UNKNOWN_LEN; /* TODO: calculate actual length */

        return (SOX_SUCCESS);
}
Example #19
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;
}
Example #20
0
/*
 * Start processing
 */
static int sox_pan_start(sox_effect_t * effp)
{
    if (effp->out_signal.channels==1)
        lsx_warn("PAN onto a mono channel...");
    return SOX_SUCCESS;
}
Example #21
0
/*-----------------------------------------------------------------
 * read() -- read data from a VOC file
 * ANN:  Major changes here to support multi-part files and files
 *       that do not have audio in block 9's.
 *-----------------------------------------------------------------*/
static size_t read_samples(sox_format_t * ft, sox_sample_t * buf,
                               size_t len)
{
  priv_t * v = (priv_t *) ft->priv;
  size_t done = 0;
  int rc = 0;
  int16_t sw;
  unsigned char uc;

  if (v->block_remaining == 0) {        /* handle getting another cont. buffer */
    rc = getblock(ft);
    if (rc)
      return 0;
  }

  if (v->block_remaining == 0)  /* if no more data, return 0, i.e., done */
    return 0;

  if (v->silent) {
    for (; v->block_remaining && (done < len); v->block_remaining--, done++)
      *buf++ = 0;       /* Fill in silence */
  } else {      /* not silence; read len samples of audio from the file */
    size_t per = max(1, 9 / v->size);

    for (; (done + per <= len); done += per) {
      if (v->block_remaining == 0) {    /* IF no more in this block, get another */
        while (v->block_remaining == 0) {       /* until have either EOF or a block with data */
          rc = getblock(ft);
          if (rc)
            break;
        }
        if (rc) /* IF EOF, break out, no more data, next will return 0 */
          break;
      }

      /* Read the data in the file */
      if (v->size <= 4) {
        if (!v->adpcm.setup.sign) {
          SOX_SAMPLE_LOCALS;
          if (lsx_readb(ft, &uc) == SOX_EOF) {
            lsx_warn("VOC input: short file");
            v->block_remaining = 0;
            return done;
          }
          *buf = SOX_UNSIGNED_8BIT_TO_SAMPLE(uc,);
          lsx_adpcm_init(&v->adpcm, 6 - v->size, SOX_SAMPLE_TO_SIGNED_16BIT(*buf, ft->clips));
          ++buf;
          --v->block_remaining;
          ++done;
        }
        if (lsx_readb(ft, &uc) == SOX_EOF) {
          lsx_warn("VOC input: short file");
          v->block_remaining = 0;
          return done;
        }
        switch (v->size) {
          case 2:
            if (v->format == VOC_FMT_CRLADPCM2) {
              int u = uc;

              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u >> 6, &v->adpcm),);
              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u >> 4, &v->adpcm),);
              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u >> 2, &v->adpcm),);
              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u     , &v->adpcm),);
            }
            break;
          case 3:
            if (v->format == VOC_FMT_CRLADPCM3) {
              int u = uc;

              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u >> 5, &v->adpcm),);
              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u >> 2, &v->adpcm),);
              *buf++ =                              /* A bit from nowhere! */
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u << 1, &v->adpcm),);
            }
            break;
          case 4:
            if (v->format == VOC_FMT_CRLADPCM4) {
              int u = uc;

              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u >> 4, &v->adpcm),);
              *buf++ =
                  SOX_SIGNED_16BIT_TO_SAMPLE(lsx_adpcm_decode (u     , &v->adpcm),);
            }
            break;
        }
Example #22
0
static void
_fixedlame_logf(const char *msg)
{
    lsx_warn(msg);
}
Example #23
0
static int stop(sox_effect_t * effp)
{
  priv_t * p = (priv_t *)effp->priv;

  if (!effp->flow) {
    double min_runs = 0, max_count = 0, min = 2, max = -2, max_sigma_x = 0, sigma_x = 0, sigma_x2 = 0, min_sigma_x2 = 2, max_sigma_x2 = 0, avg_peak = 0;
    off_t num_samples = 0, min_count = 0, max_runs = 0;
    uint32_t mask = 0;
    unsigned b1, b2, i, n = effp->flows > 1 ? effp->flows : 0;

    for (i = 0; i < effp->flows; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      min = min(min, q->min);
      max = max(max, q->max);
      min_sigma_x2 = min(min_sigma_x2, q->min_sigma_x2);
      max_sigma_x2 = max(max_sigma_x2, q->max_sigma_x2);
      sigma_x += q->sigma_x;
      sigma_x2 += q->sigma_x2;
      num_samples += q->num_samples;
      mask |= q->mask;
      if (fabs(q->sigma_x) > fabs(max_sigma_x))
        max_sigma_x = q->sigma_x;
      min_count += q->min_count;
      min_runs += q->min_runs;
      max_count += q->max_count;
      max_runs += q->max_runs;
      avg_peak += max(-q->min, q->max);
    }
    avg_peak /= effp->flows;

    if (!num_samples) {
      lsx_warn("no audio");
      return SOX_SUCCESS;
    }

    if (n == 2)
      fprintf(stderr, "             Overall     Left      Right\n");
    else if (n) {
      fprintf(stderr, "             Overall");
      for (i = 0; i < n; ++i)
        fprintf(stderr, "     Ch%-3i", i + 1);
      fprintf(stderr, "\n");
    }

    fprintf(stderr, "DC offset ");
    output(p, max_sigma_x / p->num_samples);
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      output(p, q->sigma_x / q->num_samples);
    }

    fprintf(stderr, "\nMin level ");
    output(p, min);
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      output(p, q->min);
    }

    fprintf(stderr, "\nMax level ");
    output(p, max);
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      output(p, q->max);
    }

    fprintf(stderr, "\nPk lev dB %10.2f", linear_to_dB(max(-min, max)));
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      fprintf(stderr, "%10.2f", linear_to_dB(max(-q->min, q->max)));
    }

    fprintf(stderr, "\nRMS lev dB%10.2f", linear_to_dB(sqrt(sigma_x2 / num_samples)));
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      fprintf(stderr, "%10.2f", linear_to_dB(sqrt(q->sigma_x2 / q->num_samples)));
    }

    fprintf(stderr, "\nRMS Pk dB %10.2f", linear_to_dB(sqrt(max_sigma_x2)));
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      fprintf(stderr, "%10.2f", linear_to_dB(sqrt(q->max_sigma_x2)));
    }

    fprintf(stderr, "\nRMS Tr dB ");
    if (min_sigma_x2 != 1)
      fprintf(stderr, "%10.2f", linear_to_dB(sqrt(min_sigma_x2)));
    else fprintf(stderr, "         -");
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      if (q->min_sigma_x2 != 1)
        fprintf(stderr, "%10.2f", linear_to_dB(sqrt(q->min_sigma_x2)));
      else fprintf(stderr, "         -");
    }

    if (effp->flows > 1)
      fprintf(stderr, "\nCrest factor       -");
    else fprintf(stderr, "\nCrest factor %7.2f", sigma_x2 ? avg_peak / sqrt(sigma_x2 / num_samples) : 1);
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      fprintf(stderr, "%10.2f", q->sigma_x2? max(-q->min, q->max) / sqrt(q->sigma_x2 / q->num_samples) : 1);
    }

    fprintf(stderr, "\nFlat factor%9.2f", linear_to_dB((min_runs + max_runs) / (min_count + max_count)));
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      fprintf(stderr, " %9.2f", linear_to_dB((q->min_runs + q->max_runs) / (q->min_count + q->max_count)));
    }

    fprintf(stderr, "\nPk count   %9s", lsx_sigfigs3((min_count + max_count) / effp->flows));
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      fprintf(stderr, " %9s", lsx_sigfigs3((double)(q->min_count + q->max_count)));
    }

    b1 = bit_depth(mask, min, max, &b2);
    fprintf(stderr, "\nBit-depth      %2u/%-2u", b1, b2);
    for (i = 0; i < n; ++i) {
      priv_t * q = (priv_t *)(effp - effp->flow + i)->priv;
      b1 = bit_depth(q->mask, q->min, q->max, &b2);
      fprintf(stderr, "     %2u/%-2u", b1, b2);
    }

    fprintf(stderr, "\nNum samples%9s", lsx_sigfigs3((double)p->num_samples));
    fprintf(stderr, "\nLength s   %9.3f", p->num_samples / effp->in_signal.rate);
    fprintf(stderr, "\nScale max ");
    output(p, 1.);
    fprintf(stderr, "\nWindow s   %9.3f", p->time_constant);
    fprintf(stderr, "\n");
  }
  return SOX_SUCCESS;
}