Audio-FLAC-Decoder

 view release on metacpan or  search on metacpan

Decoder.xs  view on Meta::CPAN

	union {
		double seconds;
		FLAC__int64 samples;
	} value;
} SkipUntilSpecification;

/* Allow multiple instances of the decoder object. Stuff each filehandle into (void*)stream */
typedef struct {
	int abort_flag;
	int bytes_streamed;
	int is_streaming;
	FLAC__uint64 stream_length;
	void *buffer;
	PerlIO *stream;
	decoder_t *decoder;
	FLAC__bool has_replaygain;

	/* (24/8) for max bytes per sample */
	FLAC__byte sample_buffer[SAMPLES_PER_WRITE * FLAC__MAX_SUPPORTED_CHANNELS * (24/8)];
	FLAC__int32 reservoir[FLAC__MAX_BLOCK_SIZE * 2 * FLAC__MAX_SUPPORTED_CHANNELS];
	FLAC__uint64 decode_position_last;

Decoder.xs  view on Meta::CPAN

	warn("FLAC decoder error_callback: %s\n", status);
}

static FLAC__StreamDecoderSeekStatus seek_callback(
	const decoder_t *decoder,
	FLAC__uint64 absolute_byte_offset, void *client_data) {

	flac_datasource *datasource = (flac_datasource *)client_data;

	/* can't seek on a socket */
	if (datasource->is_streaming) {
		return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
	}

	if (PerlIO_seek(datasource->stream, absolute_byte_offset, SEEK_SET) >= 0) {
		return FLAC__STREAM_DECODER_SEEK_STATUS_OK;
	}

	return FLAC__STREAM_DECODER_SEEK_STATUS_ERROR;
}

static FLAC__StreamDecoderTellStatus tell_callback(
	const decoder_t *decoder,
	FLAC__uint64 *absolute_byte_offset, void *client_data) {

	flac_datasource *datasource = (flac_datasource *)client_data;
	FLAC__uint64 pos = -1;
	
	/* can't tell on a socket */
	if (datasource->is_streaming) {
		return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
	}

	pos = PerlIO_tell(datasource->stream);

	if (pos < 0) {
		return FLAC__STREAM_DECODER_TELL_STATUS_ERROR;
	}

	*absolute_byte_offset = pos;
	return FLAC__STREAM_DECODER_TELL_STATUS_OK;
}

static FLAC__StreamDecoderLengthStatus length_callback(
	const decoder_t *decoder,
	FLAC__uint64 *stream_length, void *client_data) {

	flac_datasource *datasource = (flac_datasource *)client_data;

	/* can't find the total length of a socket */
	if (datasource->is_streaming) {
		return FLAC__STREAM_DECODER_LENGTH_STATUS_ERROR;
	}

	*stream_length = datasource->stream_length;
	return FLAC__STREAM_DECODER_LENGTH_STATUS_OK;
}

static FLAC__bool eof_callback(
	const decoder_t *decoder, void *client_data) {

	flac_datasource *datasource = (flac_datasource *)client_data;
	FLAC__uint64 pos = 0;

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

	pos = PerlIO_tell(datasource->stream);

	if (pos >= 0 && pos >= datasource->stream_length) {
		/* printf("stream length: %d pos: %d\n", datasource->stream_length, pos); */
		return true;
	}

Decoder.xs  view on Meta::CPAN


			FLACdecoder_finish(datasource->decoder);
			FLACdecoder_delete(datasource->decoder);

			safefree(datasource);

			warn("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;
	}

	if (!datasource->is_streaming) {

		pos = PerlIO_tell(datasource->stream);

		if (PerlIO_seek(datasource->stream, 0, SEEK_END) != -1) {
		
			datasource->stream_length = PerlIO_tell(datasource->stream);

			if (PerlIO_seek(datasource->stream, pos, SEEK_SET) == -1) {

				FLACdecoder_finish(datasource->decoder);

Decoder.xs  view on Meta::CPAN

	long pos;
	int whence;

	CODE:
	{

	HV *self = (HV *) SvRV(obj);
	flac_datasource *datasource = (flac_datasource *) SvIV(*(my_hv_fetch(self, "DATASOURCE")));

	/* can't seek on a socket. */
	if (datasource->is_streaming) {
		XSRETURN_UNDEF;
	}

	if (!FLAC__stream_decoder_reset(datasource->decoder)) {
		XSRETURN_UNDEF;
	}

	RETVAL = PerlIO_seek(datasource->stream, pos, whence);

	}



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