示例#1
0
文件: formats.c 项目: dmkrepo/libsox
static void set_endiannesses(sox_format_t * ft)
{
  if (ft->encoding.opposite_endian)
    ft->encoding.reverse_bytes = (ft->handler.flags & SOX_FILE_ENDIAN)?
      !(ft->handler.flags & SOX_FILE_ENDBIG) != MACHINE_IS_BIGENDIAN : sox_true;
  else if (ft->encoding.reverse_bytes == sox_option_default)
    ft->encoding.reverse_bytes = (ft->handler.flags & SOX_FILE_ENDIAN)?
      !(ft->handler.flags & SOX_FILE_ENDBIG) == MACHINE_IS_BIGENDIAN : sox_false;

  /* FIXME: Change reports to suitable warnings if trying
   * to override something that can't be overridden. */

  if (ft->handler.flags & SOX_FILE_ENDIAN) {
    if (ft->encoding.reverse_bytes == (sox_option_t)
        (!(ft->handler.flags & SOX_FILE_ENDBIG) != MACHINE_IS_BIGENDIAN))
      lsx_report("`%s': overriding file-type byte-order", ft->filename);
  } else if (ft->encoding.reverse_bytes == sox_option_yes)
    lsx_report("`%s': overriding machine byte-order", ft->filename);

  if (ft->encoding.reverse_bits == sox_option_default)
    ft->encoding.reverse_bits = !!(ft->handler.flags & SOX_FILE_BIT_REV);
  else if (ft->encoding.reverse_bits == !(ft->handler.flags & SOX_FILE_BIT_REV))
      lsx_report("`%s': overriding file-type bit-order", ft->filename);

  if (ft->encoding.reverse_nibbles == sox_option_default)
    ft->encoding.reverse_nibbles = !!(ft->handler.flags & SOX_FILE_NIB_REV);
  else
    if (ft->encoding.reverse_nibbles == !(ft->handler.flags & SOX_FILE_NIB_REV))
      lsx_report("`%s': overriding file-type nibble-order", ft->filename);
}
示例#2
0
static int startread(sox_format_t * ft)
{
  if (!ft->signal.rate) {
    ft->signal.rate = SOX_DEFAULT_RATE;
    lsx_report("sample rate not specified; using %g", ft->signal.rate);
  }
  ft->signal.precision = ft->encoding.bits_per_sample?
      ft->encoding.bits_per_sample: SOX_SAMPLE_PRECISION;
  /* Default number of channels is application-dependent */
  return SOX_SUCCESS;
}
示例#3
0
文件: cvsd.c 项目: 5in4/libsox.dll
/*
 * note! file must be seekable
 */
static int dvms_write_header(sox_format_t * ft, struct dvms_header *hdr)
{
        unsigned char hdrbuf[DVMS_HEADER_LEN];
        unsigned char *pch = hdrbuf;
        unsigned char *pchs = hdrbuf;
        int i;
        unsigned sum;

        memcpy(pch, hdr->Filename, sizeof(hdr->Filename));
        pch += sizeof(hdr->Filename);
        put16_le(&pch, hdr->Id);
        put16_le(&pch, hdr->State);
        put32_le(&pch, (unsigned)hdr->Unixtime);
        put16_le(&pch, hdr->Usender);
        put16_le(&pch, hdr->Ureceiver);
        put32_le(&pch, (unsigned) hdr->Length);
        put16_le(&pch, hdr->Srate);
        put16_le(&pch, hdr->Days);
        put16_le(&pch, hdr->Custom1);
        put16_le(&pch, hdr->Custom2);
        memcpy(pch, hdr->Info, sizeof(hdr->Info));
        pch += sizeof(hdr->Info);
        memcpy(pch, hdr->extend, sizeof(hdr->extend));
        pch += sizeof(hdr->extend);
        for(i = sizeof(hdrbuf), sum = 0; i > /*2*/3; i--) /* Deti bug */
                sum += *pchs++;
        hdr->Crc = sum;
        put16_le(&pch, hdr->Crc);
        if (lsx_seeki(ft, (off_t)0, SEEK_SET) < 0)
        {
                lsx_report("seek failed\n: %s",strerror(errno));
                return (SOX_EOF);
        }
        if (lsx_writebuf(ft, hdrbuf, sizeof(hdrbuf)) != sizeof(hdrbuf))
        {
                lsx_report("%s",strerror(errno));
                return (SOX_EOF);
        }
        return (SOX_SUCCESS);
}
示例#4
0
文件: alsa.c 项目: Amalerd/SoxPlayer
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;
}
示例#5
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);
}
示例#6
0
文件: sf.c 项目: CaptainHayashi/sox
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);
}
示例#7
0
文件: sinc.c 项目: Amalerd/SoxPlayer
static double * lpf(double Fn, double Fc, double tbw, int * num_taps, double att, double * beta, sox_bool round)
{
  if ((Fc /= Fn) <= 0 || Fc >= 1) {
    *num_taps = 0;
    return NULL;
  }
  att = att? att : 120;
  *beta = *beta < 0? lsx_kaiser_beta(att) : *beta;
  if (!*num_taps) {
    int n = lsx_lpf_num_taps(att, (tbw? tbw / Fn : .05) * .5, 0);
    *num_taps = range_limit(n, 11, 32767);
    if (round)
      *num_taps = 1 + 2 * (int)((int)((*num_taps / 2) * Fc + .5) / Fc + .5);
    lsx_report("num taps = %i (from %i)", *num_taps, n);
  }
  return lsx_make_lpf(*num_taps |= 1, Fc, *beta, 1., sox_false);
}
示例#8
0
文件: cvsd.c 项目: 5in4/libsox.dll
static int dvms_read_header(sox_format_t * ft, struct dvms_header *hdr)
{
        unsigned char hdrbuf[DVMS_HEADER_LEN];
        unsigned char *pch = hdrbuf;
        int i;
        unsigned sum;

        if (lsx_readbuf(ft, hdrbuf, sizeof(hdrbuf)) != sizeof(hdrbuf))
        {
                return (SOX_EOF);
        }
        for(i = sizeof(hdrbuf), sum = 0; i > /*2*/3; i--) /* Deti bug */
                sum += *pch++;
        pch = hdrbuf;
        memcpy(hdr->Filename, pch, sizeof(hdr->Filename));
        pch += sizeof(hdr->Filename);
        hdr->Id = get16_le(&pch);
        hdr->State = get16_le(&pch);
        hdr->Unixtime = get32_le(&pch);
        hdr->Usender = get16_le(&pch);
        hdr->Ureceiver = get16_le(&pch);
        hdr->Length = get32_le(&pch);
        hdr->Srate = get16_le(&pch);
        hdr->Days = get16_le(&pch);
        hdr->Custom1 = get16_le(&pch);
        hdr->Custom2 = get16_le(&pch);
        memcpy(hdr->Info, pch, sizeof(hdr->Info));
        pch += sizeof(hdr->Info);
        memcpy(hdr->extend, pch, sizeof(hdr->extend));
        pch += sizeof(hdr->extend);
        hdr->Crc = get16_le(&pch);
        if (sum != hdr->Crc)
        {
                lsx_report("DVMS header checksum error, read %u, calculated %u",
                     hdr->Crc, sum);
                return (SOX_EOF);
        }
        return (SOX_SUCCESS);
}
示例#9
0
文件: cvsd.c 项目: 5in4/libsox.dll
static void cvsdstartcommon(sox_format_t * ft)
{
        priv_t *p = (priv_t *) ft->priv;

        p->cvsd_rate = (ft->signal.rate <= 24000) ? 16000 : 32000;
        ft->signal.rate = 8000;
        ft->signal.channels = 1;
        lsx_rawstart(ft, sox_true, sox_false, sox_true, SOX_ENCODING_CVSD, 1);
        /*
         * initialize the decoder
         */
        p->com.overload = 0x5;
        p->com.mla_int = 0;
        /*
         * timeconst = (1/e)^(200 / SR) = exp(-200/SR)
         * SR is the sampling rate
         */
        p->com.mla_tc0 = exp((-200.0)/((float)(p->cvsd_rate)));
        /*
         * phase_inc = 32000 / SR
         */
        p->com.phase_inc = 32000 / p->cvsd_rate;
        /*
         * initialize bit shift register
         */
        p->bit.shreg = p->bit.cnt = 0;
        p->bit.mask = 1;
        /*
         * count the bytes written
         */
        p->bytes_written = 0;
        p->com.v_min = 1;
        p->com.v_max = -1;
        lsx_report("cvsd: bit rate %dbit/s, bits from %s", p->cvsd_rate,
               ft->encoding.reverse_bits ? "msb to lsb" : "lsb to msb");
}
示例#10
0
/*
 * Read up to len samples from p->Synth
 * If needed, read some more MP3 data, decode them and synth them
 * Place in buf[].
 * Return number of samples read.
 */
static size_t sox_mp3read(sox_format_t * ft, sox_sample_t *buf, size_t len)
{
    priv_t *p = (priv_t *) ft->priv;
    size_t donow,i,done=0;
    mad_fixed_t sample;
    size_t chan;

    do {
        size_t x = (p->Synth.pcm.length - p->cursamp)*ft->signal.channels;
        donow=min(len, x);
        i=0;
        while(i<donow){
            for(chan=0;chan<ft->signal.channels;chan++){
                sample=p->Synth.pcm.samples[chan][p->cursamp];
                if (sample < -MAD_F_ONE)
                    sample=-MAD_F_ONE;
                else if (sample >= MAD_F_ONE)
                    sample=MAD_F_ONE-1;
                *buf++=(sox_sample_t)(sample<<(32-1-MAD_F_FRACBITS));
                i++;
            }
            p->cursamp++;
        };

        len-=donow;
        done+=donow;

        if (len==0) break;

        /* check whether input buffer needs a refill */
        if (p->Stream.error == MAD_ERROR_BUFLEN)
        {
            if (sox_mp3_input(ft) == SOX_EOF) {
                lsx_debug("sox_mp3_input EOF");
                break;
            }
        }

        if (p->mad_frame_decode(&p->Frame,&p->Stream))
        {
            if(MAD_RECOVERABLE(p->Stream.error))
            {
                sox_mp3_inputtag(ft);
                continue;
            }
            else
            {
                if (p->Stream.error == MAD_ERROR_BUFLEN)
                    continue;
                else
                {
                    lsx_report("unrecoverable frame level error (%s).",
                              p->mad_stream_errorstr(&p->Stream));
                    break;
                }
            }
        }
        p->FrameCount++;
        p->mad_timer_add(&p->Timer,p->Frame.header.duration);
        p->mad_synth_frame(&p->Synth,&p->Frame);
        p->cursamp=0;
    } while(1);

    return done;
}
示例#11
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;
}
示例#12
0
文件: flac.c 项目: Emisense/eTracks
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;
}
示例#13
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);
}
示例#14
0
/*
 * Process command-line options but don't do other
 * initialization now: effp->in_signal & effp->out_signal are not
 * yet filled in.
 */
static int getopts(sox_effect_t* effp, int argc, char** argv)
{
    priv_t* p = (priv_t*)effp->priv;
    const size_t agcDefault = 100;
    const size_t denoiseDefault = 15;
    const size_t fpsDefault = 50;

    for (argc--, argv++; argc; argc--, argv++)
    {
        if (!strcasecmp("-agc", argv[0]))
        {
            /* AGC level argument is optional. If not specified, it defaults to agcDefault.
               If specified, it must be from 0 to 100. */
            if (!get_param(&argc, &argv, &p->agc, agcDefault, 0, 100))
            {
                lsx_fail("Invalid argument \"%s\" to -agc parameter - expected number from 0 to 100.", argv[1]);
                return lsx_usage(effp);
            }
        }
        else if (!strcasecmp("-denoise", argv[0]))
        {
            /* Denoise level argument is optional. If not specified, it defaults to denoiseDefault.
               If specified, it must be from 0 to 100. */
            if (!get_param(&argc, &argv, &p->denoise, denoiseDefault, 0, 100))
            {
                lsx_fail("Invalid argument \"%s\" to -denoise parameter - expected number from 0 to 100.", argv[1]);
                return lsx_usage(effp);
            }
        }
        else if (!strcasecmp("-dereverb", argv[0]))
        {
            p->dereverb = 1;
        }
        else if (!strcasecmp("-spf", argv[0]))
        {
            /* If samples_per_frame option is given, argument is required and must be
               greater than 0. */
            if (!get_param(&argc, &argv, &p->samples_per_frame, 0, 1, 1000000000) || !p->samples_per_frame)
            {
                lsx_fail("Invalid argument \"%s\" to -spf parameter - expected positive number.", argv[1]);
                return lsx_usage(effp);
            }
        }
        else if (!strcasecmp("-fps", argv[0]))
        {
            /* If frames_per_second option is given, argument is required and must be
               from 1 to 100. This will be used later to compute samples_per_frame once
               we know the sample rate). */
            if (!get_param(&argc, &argv, &p->frames_per_second, 0, 1, 100) || !p->frames_per_second)
            {
                lsx_fail("Invalid argument \"%s\" to -fps parameter - expected number from 1 to 100.", argv[1]);
                return lsx_usage(effp);
            }
        }
        else
        {
            lsx_fail("Invalid parameter \"%s\".", argv[0]);
            return lsx_usage(effp);
        }
    }

    if (!p->frames_per_second)
        p->frames_per_second = fpsDefault;

    if (!p->agc && !p->denoise && !p->dereverb)
    {
        lsx_report("No features specified. Enabling default settings \"-agc %u -denoise %u\".", agcDefault, denoiseDefault);
        p->agc = agcDefault;
        p->denoise = denoiseDefault;
    }

    return SOX_SUCCESS;
}