Audio-FLAC-Header

 view release on metacpan or  search on metacpan

Header.xs  view on Meta::CPAN

        PerlIO_close(fh);
        XSRETURN_UNDEF;
      }

      /* The size of the ID3 tag is a 'synchsafe' 4-byte uint */
      for (c = 0; c < 4; c++) {

        if (PerlIO_read(fh, &buf, 1) == -1 || buf[0] & 0x80) {
          warn("Couldn't read ID3 header length (syncsafe)!\n");
          PerlIO_close(fh);
          XSRETURN_UNDEF;
        }

        id3size <<= 7;
        id3size |= (buf[0] & 0x7f);
      }

      if (PerlIO_seek(fh, id3size, SEEK_CUR) < 0) {
        warn("Couldn't seek past ID3 header!\n");
        PerlIO_close(fh);
        XSRETURN_UNDEF;
      }

      if (PerlIO_read(fh, &buf, 4) == -1) {
        warn("Couldn't read magic fLaC header!\n");
        PerlIO_close(fh);
        XSRETURN_UNDEF;
      }
    }

    if (memcmp(buf, FLACHEADERFLAG, 4)) {
      warn("Couldn't read magic fLaC header - got gibberish instead!\n");
      PerlIO_close(fh);
      XSRETURN_UNDEF;
    }

    while (!is_last) {

      if (PerlIO_read(fh, &buf, 4) != 4) {
        warn("Couldn't read 4 bytes of the metadata block!\n");
        PerlIO_close(fh);
        XSRETURN_UNDEF;
      }

      is_last = (unsigned int)(buf[0] & 0x80);

      len = (long)((buf[1] << 16) | (buf[2] << 8) | (buf[3]));

      PerlIO_seek(fh, len, SEEK_CUR);
    }

    len = PerlIO_tell(fh);
    PerlIO_close(fh);

    my_hv_store(self, "startAudioData", newSVnv(len));

    /* Now calculate the bit rate and file size */
    totalSeconds = (float)SvIV(*(my_hv_fetch(self, "trackTotalLengthSeconds")));

    /* Find the file size */
    if (stat(path, &st) == 0) {
      my_hv_store(self, "fileSize", newSViv(st.st_size));
    } else {
      warn("Couldn't stat file: [%s], might be more problems ahead!", path);
    }

    my_hv_store(self, "bitRate", newSVnv(8.0 * (st.st_size - len) / totalSeconds));
  }

  my_hv_store(self, "filename", newSVpv(path, 0));

  /* Bless the hashref to create a class object */
  sv_bless(obj_ref, gv_stashpv(class, FALSE));

  RETVAL = obj_ref;

  OUTPUT:
  RETVAL

SV*
_write_XS(obj)
  SV* obj

  CODE:

  FLAC__bool ok = true;

  HE *he;
  HV *self = (HV *) SvRV(obj);
  HV *tags = (HV *) SvRV(*(my_hv_fetch(self, "tags")));

  char *path = (char *) SvPV_nolen(*(my_hv_fetch(self, "filename")));

  FLAC__Metadata_Chain *chain = FLAC__metadata_chain_new();

  if (chain == 0) {
    die("Out of memory allocating chain");
    XSRETURN_UNDEF;
  }

  if (!FLAC__metadata_chain_read(chain, path)) {
    print_error_with_chain_status(chain, "%s: ERROR: reading metadata", path);
    XSRETURN_UNDEF;
  }

  FLAC__Metadata_Iterator *iterator = FLAC__metadata_iterator_new();
  FLAC__StreamMetadata *block = 0;
  FLAC__bool found_vc_block = false;

  if (iterator == 0) {
    die("out of memory allocating iterator");
  }

  FLAC__metadata_iterator_init(iterator, chain);

  do {
    block = FLAC__metadata_iterator_get_block(iterator);

    if (block->type == FLAC__METADATA_TYPE_VORBIS_COMMENT) {
      found_vc_block = true;
    }



( run in 0.937 second using v1.01-cache-2.11-cpan-39bf76dae61 )