Audio-Scan

 view release on metacpan or  search on metacpan

src/buffer.c  view on Meta::CPAN

// From libsndfile
float
get_f32(const void *vp)
{
  const u_char *p = (const u_char *)vp;
  float v;
  int exponent, mantissa, negative;

  negative = p[0] & 0x80;
  exponent = ((p[0] & 0x7F) << 1) | ((p[1] & 0x80) ? 1 : 0);
  mantissa = ((p[1] & 0x7F) << 16) | (p[2] << 8) | (p[3]);

  if ( !(exponent || mantissa) ) {
    return 0.0;
  }

  mantissa |= 0x800000;
  exponent = exponent ? exponent - 127 : 0;

  v = mantissa ? ((float)mantissa) / ((float)0x800000) : 0.0;

  if (negative) {
    v *= -1;
  }

  if (exponent > 0) {
    v *= pow(2.0, exponent);
  }
  else if (exponent < 0) {
    v /= pow(2.0, abs(exponent));
  }

  return (v);
}

// http://www.onicos.com/staff/iz/formats/aiff.html
// http://www.onicos.com/staff/iz/formats/ieee.c
double
buffer_get_ieee_float(Buffer *buffer)
{
  double f;
  int expon;
  unsigned long hiMant, loMant;

  unsigned char *bptr = buffer_ptr(buffer);

  expon  = ((bptr[0] & 0x7F) << 8) | (bptr[1] & 0xFF);
  hiMant = ((unsigned long)(bptr[2] & 0xFF) << 24)
      |    ((unsigned long)(bptr[3] & 0xFF) << 16)
      |    ((unsigned long)(bptr[4] & 0xFF) << 8)
      |    ((unsigned long)(bptr[5] & 0xFF));
  loMant = ((unsigned long)(bptr[6] & 0xFF) << 24)
      |    ((unsigned long)(bptr[7] & 0xFF) << 16)
      |    ((unsigned long)(bptr[8] & 0xFF) << 8)
      |    ((unsigned long)(bptr[9] & 0xFF));

  if (expon == 0 && hiMant == 0 && loMant == 0) {
    f = 0;
  }
  else {
    if (expon == 0x7FFF) {    /* Infinity or NaN */
      f = HUGE_VAL;
    }
    else {
      expon -= 16383;
      f  = ldexp(UnsignedToFloat(hiMant), expon-=31);
      f += ldexp(UnsignedToFloat(loMant), expon-=32);
    }
  }

  buffer_consume(buffer, 10);

  if (bptr[0] & 0x80)
    return -f;
  else
    return f;
}

void
put_u16(void *vp, uint16_t v)
{
  u_char *p = (u_char *)vp;

	p[0] = (u_char)(v >> 8) & 0xff;
	p[1] = (u_char)v & 0xff;
}

void
put_u32(void *vp, uint32_t v)
{
	u_char *p = (u_char *)vp;

	p[0] = (u_char)(v >> 24) & 0xff;
	p[1] = (u_char)(v >> 16) & 0xff;
	p[2] = (u_char)(v >> 8) & 0xff;
	p[3] = (u_char)v & 0xff;
}

void
buffer_put_int(Buffer *buffer, u_int value)
{
	char buf[4];

	put_u32(buf, value);
	buffer_append(buffer, buf, 4);
}

// Warnings:
// Do not request more than 32 bits at a time.
// Be careful if using other buffer functions without reading a multiple of 8 bits.
uint32_t
buffer_get_bits(Buffer *buffer, uint32_t bits)
{
  uint32_t mask = CacheMask[bits];

  //PerlIO_printf(PerlIO_stderr(), "get_bits(%d), in cache %d\n", bits, buffer->ncached);

  while (buffer->ncached < bits) {
    // Need to read more data

    //PerlIO_printf(PerlIO_stderr(), "reading: ");



( run in 2.015 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )