Пример #1
0
static size_t write_samples(sox_format_t * const ft, sox_sample_t const * const sampleBuffer, size_t const len)
{
  priv_t * p = (priv_t *)ft->priv;
  unsigned i;

  for (i = 0; i < len; ++i) {
    SOX_SAMPLE_LOCALS;
    long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i], ft->clips);
    p->decoded_samples[i] = pcm >> (32 - p->bits_per_sample);
    switch (p->bits_per_sample) {
      case  8: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips);
        break;
      case 16: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips);
        break;
      case 24: p->decoded_samples[i] = /* sign extension: */
          SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips) << 8;
        p->decoded_samples[i] >>= 8;
        break;
      case 32: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips);
        break;
    }
  }
  FLAC__stream_encoder_process_interleaved(p->encoder, p->decoded_samples, (unsigned) len / ft->signal.channels);
  return FLAC__stream_encoder_get_state(p->encoder) == FLAC__STREAM_ENCODER_OK ? len : 0;
}
Пример #2
0
static size_t
mp3_write(sox_format_t * ft, const sox_sample_t *buf, size_t samp)
{
    int nsamples = samp/ft->signal.channels;
    int bufsize = nsamples * 4; /* backend accept "forced" stereo of 16bit */
    uint16_t *buffer = malloc(bufsize);
    int clips = 0;
    int idx = 0;
    int c = 0;
    int rc;
    SOX_SAMPLE_LOCALS;

    if(!buffer)
        return 0;

    if(ft->signal.channels == 1)
    {
        /* mono */
        for(c = 0; c < samp; c++)
        {
            /* left channel */
            buffer[idx++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[c], clips);

            /* right channel */
            buffer[idx++] = 0;
        }
    }
    else
    {
        /* stereo:  we can ignore special meaning of right channel */
        for(idx = 0; idx < samp; idx++)
        {
            buffer[idx] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[idx], clips);
        }
    }
    sox_fixedpoint_mp3_t *self = (sox_fixedpoint_mp3_t *) ft->priv;
    rc = fixedlame_encode(self->codec, (void *)buffer, samp);
    free(buffer);
    return rc;
}
Пример #3
0
/*
 * Process up to *isamp samples from ibuf and produce up to *osamp samples
 * in obuf.  Write back the actual numbers of samples to *isamp and *osamp.
 * Return SOX_SUCCESS or, if error occurs, SOX_EOF.
 */
static int flow(
    sox_effect_t* effp,
    const sox_sample_t* ibuf,
    sox_sample_t* obuf,
    size_t* isamp,
    size_t* osamp)
{
    priv_t* p = (priv_t*)effp->priv;
    size_t ibuf_pos = 0;
    size_t ibuf_end = *isamp;
    size_t obuf_pos = 0;
    size_t obuf_end = *osamp;
    size_t end_pos;
    SOX_SAMPLE_LOCALS;

    for (;;)
    {
        /* Write any processed data in working buffer to the output buffer. */
        end_pos = obuf_pos + min(p->buffer_end - p->buffer_opos, obuf_end - obuf_pos);
        for (; obuf_pos < end_pos; obuf_pos++, p->buffer_opos++)
            obuf[obuf_pos] = SOX_SIGNED_16BIT_TO_SAMPLE(p->buffer[p->buffer_opos], dummy);
        if (p->buffer_opos != p->buffer_end)
            break; /* Output buffer is full and we still have more processed data. */

        /* Fill working buffer from input buffer. */
        end_pos = ibuf_pos + min(p->buffer_end - p->buffer_ipos, ibuf_end - ibuf_pos);
        for (; ibuf_pos < end_pos; ibuf_pos++, p->buffer_ipos++)
            p->buffer[p->buffer_ipos] = SOX_SAMPLE_TO_SIGNED_16BIT(ibuf[ibuf_pos], effp->clips);
        if (p->buffer_ipos != p->buffer_end)
            break; /* Working buffer is not full and there is no more input data. */

        speex_preprocess_run(p->sps, p->buffer);
        p->buffer_ipos = 0;
        p->buffer_opos = 0;
    }

    *isamp = ibuf_pos;
    *osamp = obuf_pos;
    return SOX_SUCCESS;
}
Пример #4
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;
        }
Пример #5
0
static int start_write(sox_format_t * const ft)
{
  priv_t * p = (priv_t *)ft->priv;
  FLAC__StreamEncoderState status;
  unsigned compression_level = MAX_COMPRESSION; /* Default to "best" */

  if (ft->encoding.compression != HUGE_VAL) {
    compression_level = ft->encoding.compression;
    if (compression_level != ft->encoding.compression ||
        compression_level > MAX_COMPRESSION) {
      lsx_fail_errno(ft, SOX_EINVAL,
                 "FLAC compression level must be a whole number from 0 to %i",
                 MAX_COMPRESSION);
      return SOX_EOF;
    }
  }

  p->encoder = FLAC__stream_encoder_new();
  if (p->encoder == NULL) {
    lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the encoder instance");
    return SOX_EOF;
  }
  p->decoded_samples = lsx_malloc(sox_globals.bufsiz * sizeof(FLAC__int32));

  p->bits_per_sample = ft->encoding.bits_per_sample;

  lsx_report("encoding at %i bits per sample", p->bits_per_sample);

  FLAC__stream_encoder_set_channels(p->encoder, ft->signal.channels);
  FLAC__stream_encoder_set_bits_per_sample(p->encoder, p->bits_per_sample);
  FLAC__stream_encoder_set_sample_rate(p->encoder, (unsigned)(ft->signal.rate + .5));

  { /* Check if rate is streamable: */
    static const unsigned streamable_rates[] =
      {8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000};
    size_t i;
    sox_bool streamable = sox_false;
    for (i = 0; !streamable && i < array_length(streamable_rates); ++i)
       streamable = (streamable_rates[i] == ft->signal.rate);
    if (!streamable) {
      lsx_report("non-standard rate; output may not be streamable");
      FLAC__stream_encoder_set_streamable_subset(p->encoder, sox_false);
    }
  }

#if FLAC_API_VERSION_CURRENT >= 10
  FLAC__stream_encoder_set_compression_level(p->encoder, compression_level);
#else
  {
    static struct {
      unsigned blocksize;
      FLAC__bool do_exhaustive_model_search;
      FLAC__bool do_mid_side_stereo;
      FLAC__bool loose_mid_side_stereo;
      unsigned max_lpc_order;
      unsigned max_residual_partition_order;
      unsigned min_residual_partition_order;
    } const options[MAX_COMPRESSION + 1] = {
      {1152, sox_false, sox_false, sox_false, 0, 2, 2},
      {1152, sox_false, sox_true, sox_true, 0, 2, 2},
      {1152, sox_false, sox_true, sox_false, 0, 3, 0},
      {4608, sox_false, sox_false, sox_false, 6, 3, 3},
      {4608, sox_false, sox_true, sox_true, 8, 3, 3},
      {4608, sox_false, sox_true, sox_false, 8, 3, 3},
      {4608, sox_false, sox_true, sox_false, 8, 4, 0},
      {4608, sox_true, sox_true, sox_false, 8, 6, 0},
      {4608, sox_true, sox_true, sox_false, 12, 6, 0},
    };
#define SET_OPTION(x) do {\
  lsx_report(#x" = %i", options[compression_level].x); \
  FLAC__stream_encoder_set_##x(p->encoder, options[compression_level].x);\
} while (0)
    SET_OPTION(blocksize);
    SET_OPTION(do_exhaustive_model_search);
    SET_OPTION(max_lpc_order);
    SET_OPTION(max_residual_partition_order);
    SET_OPTION(min_residual_partition_order);
    if (ft->signal.channels == 2) {
      SET_OPTION(do_mid_side_stereo);
      SET_OPTION(loose_mid_side_stereo);
    }
#undef SET_OPTION
  }
#endif

  if (ft->signal.length != 0) {
    FLAC__stream_encoder_set_total_samples_estimate(p->encoder, (FLAC__uint64)(ft->signal.length / ft->signal.channels));

    p->metadata[p->num_metadata] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_SEEKTABLE);
    if (p->metadata[p->num_metadata] == NULL) {
      lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the encoder seek table template");
      return SOX_EOF;
    }
    {
#if FLAC_API_VERSION_CURRENT >= 8
      if (!FLAC__metadata_object_seektable_template_append_spaced_points_by_samples(p->metadata[p->num_metadata], (unsigned)(10 * ft->signal.rate + .5), (FLAC__uint64)(ft->signal.length/ft->signal.channels))) {
#else
      size_t samples = 10 * ft->signal.rate;
      size_t total_samples = ft->signal.length/ft->signal.channels;
      if (!FLAC__metadata_object_seektable_template_append_spaced_points(p->metadata[p->num_metadata], total_samples / samples + (total_samples % samples != 0), (FLAC__uint64)total_samples)) {
#endif
        lsx_fail_errno(ft, SOX_ENOMEM, "FLAC ERROR creating the encoder seek table points");
        return SOX_EOF;
      }
    }
    p->metadata[p->num_metadata]->is_last = sox_false; /* the encoder will set this for us */
    ++p->num_metadata;
  }

  if (ft->oob.comments) {     /* Make the comment structure */
    FLAC__StreamMetadata_VorbisComment_Entry entry;
    int i;

    p->metadata[p->num_metadata] = FLAC__metadata_object_new(FLAC__METADATA_TYPE_VORBIS_COMMENT);
    for (i = 0; ft->oob.comments[i]; ++i) {
      static const char prepend[] = "Comment=";
      char * text = lsx_calloc(strlen(prepend) + strlen(ft->oob.comments[i]) + 1, sizeof(*text));
      /* Prepend `Comment=' if no field-name already in the comment */
      if (!strchr(ft->oob.comments[i], '='))
        strcpy(text, prepend);
      entry.entry = (FLAC__byte *) strcat(text, ft->oob.comments[i]);
      entry.length = strlen(text);
      FLAC__metadata_object_vorbiscomment_append_comment(p->metadata[p->num_metadata], entry, /*copy= */ sox_true);
      free(text);
    }
    ++p->num_metadata;
  }

  if (p->num_metadata)
    FLAC__stream_encoder_set_metadata(p->encoder, p->metadata, p->num_metadata);

#if FLAC_API_VERSION_CURRENT <= 7
  FLAC__stream_encoder_set_write_callback(p->encoder, flac_stream_encoder_write_callback);
  FLAC__stream_encoder_set_metadata_callback(p->encoder, flac_stream_encoder_metadata_callback);
  FLAC__stream_encoder_set_client_data(p->encoder, ft);
  status = FLAC__stream_encoder_init(p->encoder);
#else
  status = FLAC__stream_encoder_init_stream(p->encoder, flac_stream_encoder_write_callback,
      flac_stream_encoder_seek_callback, flac_stream_encoder_tell_callback, flac_stream_encoder_metadata_callback, ft);
#endif

  if (status != FLAC__STREAM_ENCODER_OK) {
    lsx_fail_errno(ft, SOX_EINVAL, "%s", FLAC__StreamEncoderStateString[status]);
    return SOX_EOF;
  }
  return SOX_SUCCESS;
}



static size_t write_samples(sox_format_t * const ft, sox_sample_t const * const sampleBuffer, size_t const len)
{
  priv_t * p = (priv_t *)ft->priv;
  unsigned i;

  for (i = 0; i < len; ++i) {
    long pcm = SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i], ft->clips);
    p->decoded_samples[i] = pcm >> (32 - p->bits_per_sample);
    switch (p->bits_per_sample) {
      case  8: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_8BIT(sampleBuffer[i], ft->clips);
        break;
      case 16: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_16BIT(sampleBuffer[i], ft->clips);
        break;
      case 24: p->decoded_samples[i] = /* sign extension: */
          SOX_SAMPLE_TO_SIGNED_24BIT(sampleBuffer[i],ft->clips) << 8;
        p->decoded_samples[i] >>= 8;
        break;
      case 32: p->decoded_samples[i] =
          SOX_SAMPLE_TO_SIGNED_32BIT(sampleBuffer[i],ft->clips);
        break;
    }
  }
  FLAC__stream_encoder_process_interleaved(p->encoder, p->decoded_samples, (unsigned) len / ft->signal.channels);
  return FLAC__stream_encoder_get_state(p->encoder) == FLAC__STREAM_ENCODER_OK ? len : 0;
}