Audio-FLAC-Decoder
view release on metacpan or search on metacpan
#define FLACdecoder_delete(x) FLAC__stream_decoder_delete(x)
#define FLACdecoder_set_read_callback(x, y) FLAC__stream_decoder_set_read_callback(x, y)
#define FLACdecoder_set_write_callback(x, y) FLAC__stream_decoder_set_write_callback(x, y)
#define FLACdecoder_set_metadata_callback(x, y) FLAC__stream_decoder_set_metadata_callback(x, y)
#define FLACdecoder_set_error_callback(x, y) FLAC__stream_decoder_set_error_callback(x, y)
#define FLACdecoder_set_client_data(x, y) FLAC__stream_decoder_set_client_data(x, y)
#define FLACdecoder_set_seek_callback(x, y) FLAC__stream_decoder_set_seek_callback(x, y)
#define FLACdecoder_set_tell_callback(x, y) FLAC__stream_decoder_set_tell_callback(x, y)
#define FLACdecoder_set_length_callback(x, y) FLAC__stream_decoder_set_length_callback(x, y)
#define FLACdecoder_set_eof_callback(x, y) FLAC__stream_decoder_set_eof_callback(x, y)
#define FLACdecoder_seek_absolute(x, y) FLAC__stream_decoder_seek_absolute(x, y)
#define FLACdecoder_get_state(x) FLAC__stream_decoder_get_state(x)
#define FLACdecoder_get_channels(x) FLAC__stream_decoder_get_channels(x)
#define FLACdecoder_get_blocksize(x) FLAC__stream_decoder_get_blocksize(x)
#define FLACdecoder_get_sample_rate(x) FLAC__stream_decoder_get_sample_rate(x)
#define FLACdecoder_get_bits_per_sample(x) FLAC__stream_decoder_get_bits_per_sample(x)
#define FLACdecoder_get_decode_position(x, y) FLAC__stream_decoder_get_decode_position(x, y)
#define SAMPLES_PER_WRITE 512
typedef struct {
/* i.e. specification string started with + or - */
FLAC__bool is_relative;
FLAC__bool value_is_samples;
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;
FLAC__uint64 decode_position_frame_last;
FLAC__uint64 decode_position_frame;
unsigned buffer_size;
FLAC__int64 total_samples;
unsigned bps;
unsigned channels;
FLAC__int64 sample_rate;
FLAC__int64 length_in_msec;
unsigned wide_samples_in_reservoir;
SkipUntilSpecification skip_specification;
SkipUntilSpecification until_specification;
} flac_datasource;
/* start all the callbacks here. */
static void meta_callback(
const decoder_t *decoder,
const FLAC__StreamMetadata *metadata, void *client_data) {
flac_datasource *datasource = (flac_datasource *)client_data;
if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
FLAC__uint64 skip, until;
/* flac__utils_canonicalize_skip_until_specification(decoder_session->skip_specification, decoder_session->sample_rate);
FLAC__ASSERT(datasource->skip_specification->value.samples >= 0); */
skip = (FLAC__uint64)datasource->skip_specification.value.samples;
/* remember, metadata->data.stream_info.total_samples can be 0, meaning 'unknown' */
if (metadata->data.stream_info.total_samples > 0 && skip >= metadata->data.stream_info.total_samples) {
warn("ERROR trying to skip more samples than in stream\n");
datasource->abort_flag = true;
return;
} else if (metadata->data.stream_info.total_samples == 0 && skip > 0) {
warn("ERROR, can't skip when FLAC metadata has total sample count of 0\n");
datasource->abort_flag = true;
return;
}
datasource->bps = metadata->data.stream_info.bits_per_sample;
datasource->channels = metadata->data.stream_info.channels;
datasource->sample_rate = metadata->data.stream_info.sample_rate;
datasource->total_samples = metadata->data.stream_info.total_samples - skip;
datasource->length_in_msec = datasource->total_samples * 10 / (datasource->sample_rate / 100);
/* if (!canonicalize_until_specification(
datasource->until_specification, datasource->inbasefilename,
datasource>n->sample_rate, skip, metadata->data.stream_info.total_samples)) {
datasource->abort_flag = true;
return;
} */
FLAC__ASSERT(datasource->until_specification.value.samples >= 0);
until = (FLAC__uint64)datasource->until_specification.value.samples;
if (until > 0) {
datasource->total_samples -= (metadata->data.stream_info.total_samples - until);
}
if (datasource->bps != 8 && datasource->bps != 16 && datasource->bps != 24) {
warn("ERROR: bits per sample is not 8/16/24\n");
datasource->abort_flag = true;
return;
}
}
}
static void error_callback(
const decoder_t *decoder,
FLAC__StreamDecoderErrorStatus status, void *client_data) {
/* flac_datasource *datasource = (flac_datasource *)client_data; */
( run in 0.519 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )