コード例 #1
0
ファイル: avr.c プロジェクト: Emisense/eTracks
static int stopwrite(sox_format_t * ft)
{
    priv_t * avr = (priv_t *)ft->priv;

    unsigned size = avr->size / ft->signal.channels;

    /* Fix size */
    lsx_seeki(ft, (off_t)26, SEEK_SET);
    lsx_writedw (ft, size);

    /* Fix lend */
    lsx_seeki(ft, (off_t)34, SEEK_SET);
    lsx_writedw (ft, size);

    return(SOX_SUCCESS);
}
コード例 #2
0
ファイル: opus.c プロジェクト: CaptainHayashi/sox
static int callback_seek(void* ft_data, opus_int64 off, int whence)
{
  sox_format_t* ft = (sox_format_t*)ft_data;
  int ret = ft->seekable ? lsx_seeki(ft, (off_t)off, whence) : -1;

  if (ret == EBADF)
    ret = -1;
  return ret;
}
コード例 #3
0
ファイル: flac.c プロジェクト: Emisense/eTracks
static FLAC__StreamEncoderSeekStatus flac_stream_encoder_seek_callback(FLAC__StreamEncoder const * encoder, FLAC__uint64 absolute_byte_offset, void * client_data)
{
  sox_format_t * const ft = (sox_format_t *) client_data;
  (void) encoder;
  if (!ft->seekable)
    return FLAC__STREAM_ENCODER_SEEK_STATUS_UNSUPPORTED;
  else if (lsx_seeki(ft, (off_t)absolute_byte_offset, SEEK_SET) != SOX_SUCCESS)
    return FLAC__STREAM_ENCODER_SEEK_STATUS_ERROR;
  else
    return FLAC__STREAM_ENCODER_SEEK_STATUS_OK;
}
コード例 #4
0
ファイル: sox-fmt.c プロジェクト: Amalerd/SoxPlayer
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);
}
コード例 #5
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);
}
コード例 #6
0
ファイル: cvsd.c プロジェクト: 5in4/libsox.dll
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;
}
コード例 #7
0
ファイル: mp3.c プロジェクト: IntelligentVoice/sox
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;
}
コード例 #8
0
ファイル: sphere.c プロジェクト: CaptainHayashi/sox
static int start_read(sox_format_t * ft)
{
  unsigned long header_size_ul = 0, num_samples_ul = 0;
  sox_encoding_t encoding = SOX_ENCODING_SIGN2;
  size_t     header_size, bytes_read;
  size_t     num_samples = 0;
  unsigned       bytes_per_sample = 0;
  unsigned       channels = 1;
  unsigned       rate = 16000;
  char           fldname[64], fldtype[16], fldsval[128];
  char           * buf;

  /* Magic header */
  if (lsx_reads(ft, fldname, (size_t)8) || strncmp(fldname, "NIST_1A", (size_t)7) != 0) {
    lsx_fail_errno(ft, SOX_EHDR, "Sphere header does not begin with magic word `NIST_1A'");
    return (SOX_EOF);
  }

  if (lsx_reads(ft, fldsval, (size_t)8)) {
    lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header");
    return (SOX_EOF);
  }

  /* Determine header size, and allocate a buffer large enough to hold it. */
  sscanf(fldsval, "%lu", &header_size_ul);
  buf = lsx_malloc(header_size = header_size_ul);

  /* Skip what we have read so far */
  header_size -= 16;

  if (lsx_reads(ft, buf, header_size) == SOX_EOF) {
    lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header");
    free(buf);
    return (SOX_EOF);
  }

  header_size -= (strlen(buf) + 1);

  while (strncmp(buf, "end_head", (size_t)8) != 0) {
    if (strncmp(buf, "sample_n_bytes", (size_t)14) == 0)
      sscanf(buf, "%63s %15s %u", fldname, fldtype, &bytes_per_sample);
    else if (strncmp(buf, "channel_count", (size_t)13) == 0)
      sscanf(buf, "%63s %15s %u", fldname, fldtype, &channels);
    else if (strncmp(buf, "sample_count ", (size_t)13) == 0)
      sscanf(buf, "%53s %15s %lu", fldname, fldtype, &num_samples_ul);
    else if (strncmp(buf, "sample_rate ", (size_t)12) == 0)
      sscanf(buf, "%53s %15s %u", fldname, fldtype, &rate);
    else if (strncmp(buf, "sample_coding", (size_t)13) == 0) {
      sscanf(buf, "%63s %15s %127s", fldname, fldtype, fldsval);
      if (!strcasecmp(fldsval, "ulaw") || !strcasecmp(fldsval, "mu-law"))
        encoding = SOX_ENCODING_ULAW;
      else if (!strcasecmp(fldsval, "pcm"))
        encoding = SOX_ENCODING_SIGN2;
      else {
        lsx_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval);
        free(buf);
        return SOX_EOF;
      }
    }
    else if (strncmp(buf, "sample_byte_format", (size_t)18) == 0) {
      sscanf(buf, "%53s %15s %127s", fldname, fldtype, fldsval);
      if (strcmp(fldsval, "01") == 0)         /* Data is little endian. */
        ft->encoding.reverse_bytes = MACHINE_IS_BIGENDIAN;
      else if (strcmp(fldsval, "10") == 0)    /* Data is big endian. */
        ft->encoding.reverse_bytes = MACHINE_IS_LITTLEENDIAN;
      else if (strcmp(fldsval, "1")) {
        lsx_fail_errno(ft, SOX_EFMT, "sph: unsupported coding `%s'", fldsval);
        free(buf);
        return SOX_EOF;
      }
    }

    if (lsx_reads(ft, buf, header_size) == SOX_EOF) {
      lsx_fail_errno(ft, SOX_EHDR, "Error reading Sphere header");
      free(buf);
      return (SOX_EOF);
    }

    header_size -= (strlen(buf) + 1);
  }

  if (!bytes_per_sample)
    bytes_per_sample = encoding == SOX_ENCODING_ULAW? 1 : 2;

  while (header_size) {
    bytes_read = lsx_readbuf(ft, buf, header_size);
    if (bytes_read == 0) {
      free(buf);
      return (SOX_EOF);
    }
    header_size -= bytes_read;
  }
  free(buf);

  if (ft->seekable) {
    /* Check first four bytes of data to see if it's shorten compressed. */
    char           shorten_check[4];

    if (lsx_readchars(ft, shorten_check, sizeof(shorten_check)))
      return SOX_EOF;
    lsx_seeki(ft, -(off_t)sizeof(shorten_check), SEEK_CUR);

    if (!memcmp(shorten_check, "ajkg", sizeof(shorten_check))) {
      lsx_fail_errno(ft, SOX_EFMT,
                     "File uses shorten compression, cannot handle this.");
      return (SOX_EOF);
    }
  }

  num_samples = num_samples_ul;
  return lsx_check_read_params(ft, channels, (sox_rate_t)rate, encoding,
      bytes_per_sample << 3, (uint64_t)num_samples * channels, sox_true);
}