Ogg-Vorbis-Decoder

 view release on metacpan or  search on metacpan

Decoder.xs  view on Meta::CPAN

/* http://www.xiph.org/ogg/vorbis/doc/vorbisfile/ov_callbacks.html */
ov_callbacks vorbis_callbacks = {
	ovcb_read,
	ovcb_seek,
	ovcb_close,
	ovcb_tell
};

/* Allow multiple instances of the decoder object. Stuff each filehandle into (void*)stream */
typedef struct {
	int is_streaming;
	int bytes_streamed;
	int last_bitstream;
	PerlIO *stream;

} ocvb_datasource;

/* useful items from XMMS */
static size_t ovcb_read(void *ptr, size_t size, size_t nmemb, void *vdatasource) {

	size_t read_bytes = 0;

Decoder.xs  view on Meta::CPAN


	datasource->bytes_streamed += read_bytes;

	return read_bytes;
}

static int ovcb_seek(void *vdatasource, ogg_int64_t offset, int whence) {

	ocvb_datasource *datasource = vdatasource;

	if (datasource->is_streaming) {
		return -1;
	}

	/* For some reason PerlIO_seek fails miserably here. < 5.8.1 works */
	/* return PerlIO_seek(datasource->stream, offset, whence); */

	return fseek(PerlIO_findFILE(datasource->stream), offset, whence);
}

static int ovcb_close(void *vdatasource) {

	ocvb_datasource *datasource = vdatasource;

	return PerlIO_close(datasource->stream);
}

static long ovcb_tell(void *vdatasource) {

	ocvb_datasource *datasource = vdatasource;

	if (datasource->is_streaming) {
		return datasource->bytes_streamed;
	}

	return PerlIO_tell(datasource->stream);
}

/* Loads the commments from the stream and fills the object's hash */
void __read_comments(HV *self, OggVorbis_File *vf) {

	int i;

Decoder.xs  view on Meta::CPAN

	/* check and see if a pathname was passed in, otherwise it might be a
	 * IO::Socket subclass, or even a *FH Glob */
	if (SvOK(path) && (SvTYPE(SvRV(path)) != SVt_PVGV)) {

		if ((datasource->stream = PerlIO_open((char*)SvPV_nolen(path), "r")) == NULL) {
			safefree(vf);
			printf("failed on open: [%d] - [%s]\n", errno, strerror(errno));
			XSRETURN_UNDEF;
		}

		datasource->is_streaming = 0;

	} else if (SvOK(path)) {

		/* Did we get a Glob, or a IO::Socket subclass?
		 *
		 * XXX This should really be a class method so the caller
		 * can tell us if it's streaming or not. But how to do this on
		 * a per object basis without changing open()s arugments. That
		 * may be the easiest/only way. XXX
		 *
		 */

		if (sv_isobject(path) && sv_derived_from(path, "IO::Socket")) {
			datasource->is_streaming = 1;
		} else {
			datasource->is_streaming = 0;
		}

		/* dereference and get the SV* that contains the Magic & FH,
		 * then pull the fd from the PerlIO object */
		datasource->stream = IoIFP(GvIOp(SvRV(path)));

	} else {

		XSRETURN_UNDEF;
	}

Decoder.xs  view on Meta::CPAN

	HV *self = (HV *) SvRV(obj);
	OggVorbis_File *vf = (OggVorbis_File *) SvIV(*(my_hv_fetch(self, "VFILE")));

	if (!vf) XSRETURN_UNDEF;

	if (ix) {
		/* empty */
	}

	/* See http://www.xiph.org/ogg/vorbis/doc/vorbisfile/ov_read.html for
	 * a description of the bitstream parameter. This allows streaming
	 * without a hack like icy-metaint */
	cur_bitstream = (int) SvIV(*(my_hv_fetch(self, "BSTREAM")));
	old_bitstream = cur_bitstream;

	/* When we get a new bitstream, re-read the comment fields */
	read_comments = (int)SvIV(*(my_hv_fetch(self, "READCOMMENTS")));

	/* The nbytes argument to ov_read is only a limit, not a request. So
	 * read until we hit the requested number of bytes */
	while (nbytes > 0) {



( run in 0.268 second using v1.01-cache-2.11-cpan-4d50c553e7e )