Beispiel #1
0
void play_file_from_filename(const std::string name) {
   currently_playing = std::string(name);
   if (audiobuf) linearFree(audiobuf);

   if (name.rfind(".flac") != std::string::npos) {
      if (!FLAC_decoder) {
         FLAC_decoder = FLAC__stream_decoder_new();
         FLAC__stream_decoder_set_md5_checking(FLAC_decoder, true);
      }
      audiobuf_index = 0;
      decode_mode = AUDIO_MODE_FLAC;
      FLAC__StreamDecoderInitStatus init_status = FLAC__stream_decoder_init_file(FLAC_decoder, name.c_str(), FLAC_write_callback, FLAC_metadata_callback, FLAC_error_callback, NULL);
      if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
         printf("ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
      }
      FLAC__stream_decoder_process_until_end_of_metadata(FLAC_decoder);
   } else {
      decode_mode = AUDIO_MODE_VORBIS;
      v = stb_vorbis_open_filename(name.c_str(), &error, NULL);
      info = stb_vorbis_get_info(v);
      Samples = info.sample_rate;
      audiobuf_size = Samples * sizeof(s16) * 2;
      audiobuf = (s16*)linearAlloc(audiobuf_size);
   }
   paused = false;
}
static status_t HandleFLAC(const char *filename, MediaScannerClient* client)
{
    status_t status = UNKNOWN_ERROR;
    FLAC__StreamDecoder *decoder;

    decoder = FLAC__stream_decoder_new();
    if (!decoder)
        return status;

    FLAC__stream_decoder_set_md5_checking(decoder, false);
    FLAC__stream_decoder_set_metadata_ignore_all(decoder);
    FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
    FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);

    FLAC__StreamDecoderInitStatus init_status;
    init_status = FLAC__stream_decoder_init_file(decoder, filename, flac_write, flac_metadata, flac_error, client);
    if (init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
        goto exit;

    if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
        goto exit;

    status = OK;

exit:
    FLAC__stream_decoder_finish(decoder);
    FLAC__stream_decoder_delete(decoder);

    return status;
}
Beispiel #3
0
FLAC__bool safe_decoder_init_(const char *filename, FLAC__StreamDecoder *decoder)
{
	if(decoder == 0)
		return false;

	safe_decoder_finish_(decoder);

	FLAC__stream_decoder_set_md5_checking(decoder, false);
	FLAC__stream_decoder_set_metadata_ignore_all(decoder);
	FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
	FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);
	if(stream_data_.is_http_source) {
		flac_http_open(filename, 0);
		if(FLAC__stream_decoder_init_stream(decoder, http_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return false;
	}
	else {
		if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, /*client_data=*/&stream_data_) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return false;
	}

	if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
		return false;

	return true;
}
Beispiel #4
0
int read_flac_file (apr_pool_t* pool,void** file_struct, const char* file_path, encoding_options_t* enc_opt){
	FLAC__StreamDecoderInitStatus status;
	FLAC__bool status2;
	flac_file_t* flac_file = *file_struct = (flac_file_t*) apr_pcalloc(pool, sizeof(flac_file_t));

	flac_file->stream_decoder = FLAC__stream_decoder_new();
	flac_file->channels = 0;
	flac_file->samples = 0;
	flac_file->total_samples = 0;
	flac_file->rate = 0;
	flac_file->buf = NULL;

	status = FLAC__stream_decoder_init_file(flac_file->stream_decoder, file_path, flac_write, flac_metadata, flac_errors, flac_file);
	if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK){
		return -1;
	}

	status2 = FLAC__stream_decoder_process_until_end_of_metadata(flac_file->stream_decoder);
	if (status2 != true){
		return -2;
	}
	FLAC__stream_decoder_process_single(flac_file->stream_decoder);
	if (status2 != true){
			return -2;
	}
	enc_opt->channels = flac_file->channels;
	enc_opt->rate = flac_file->rate;
	enc_opt->total_samples_per_channel = flac_file->total_samples;
	enc_opt->samples_to_request = 1024;

	return 0;
}
Beispiel #5
0
bool do_test(const char* filename)
{
    drge_timer* pTimer = drge_create_timer();

    double decodeTimeReference = 1;
#ifndef DISABLE_REFERENCE_FLAC
    // Reference first.
    reference_data referenceData;
    referenceData.pDecodedData = NULL;
    referenceData.pDecodedDataWalker = NULL;
    referenceData.totalSampleCount = 0;
    referenceData.pDecoder = FLAC__stream_decoder_new();
    FLAC__stream_decoder_init_file(referenceData.pDecoder, filename, flac__write_callback, flac__metadata_callback, flac__error_callback, &referenceData);

    drge_tick_timer(pTimer);
    FLAC__stream_decoder_process_until_end_of_stream(referenceData.pDecoder);
    decodeTimeReference = drge_tick_timer(pTimer);
#endif

    // dr_flac second.
    drflac_data drflacData;
    drflacData.pDecodedData = NULL;
    drflacData.pFlac = drflac_open_file(filename);

    drflacData.pDecodedData = malloc((size_t)drflacData.pFlac->totalSampleCount * sizeof(int32_t));

    drge_tick_timer(pTimer);
    drflac_read_s32(drflacData.pFlac, (size_t)drflacData.pFlac->totalSampleCount, drflacData.pDecodedData);
    double decodeTime = drge_tick_timer(pTimer);


    (void)decodeTimeReference;
    (void)decodeTime;

    // Sample-by-Sample comparison.
    bool result = true;
#ifndef DISABLE_REFERENCE_FLAC
    if (drflacData.pFlac->totalSampleCount != referenceData.totalSampleCount) {
        result = false;
        printf("TEST FAILED: %s: Total sample count differs. %lld != %lld\n", filename, drflacData.pFlac->totalSampleCount, referenceData.totalSampleCount);
        goto finish_test;
    }

    for (uint64_t i = 0; i < drflacData.pFlac->totalSampleCount; ++i) {
        if (drflacData.pDecodedData[i] != referenceData.pDecodedData[i]) {
            result = false;
            printf("TEST FAILED: %s: Sample at %lld differs. %d != %d\n", filename, i, drflacData.pDecodedData[i], referenceData.pDecodedData[i]);
            goto finish_test;
        }
    }

    printf("Reference Time: %f : dr_flac Time: %f - %d%%\n", decodeTimeReference, decodeTime, (int)(decodeTime/decodeTimeReference*100));

finish_test:
    free(referenceData.pDecodedData);
    free(drflacData.pDecodedData);
#endif
    return result;
}
FLAC__bool populate_seekpoint_values(const char *filename, FLAC__StreamMetadata *block, FLAC__bool *needs_write)
{
	FLAC__StreamDecoder *decoder;
	ClientData client_data;
	FLAC__bool ok = true;

	FLAC__ASSERT(0 != block);
	FLAC__ASSERT(block->type == FLAC__METADATA_TYPE_SEEKTABLE);

	client_data.seektable_template = &block->data.seek_table;
	client_data.samples_written = 0;
	/* client_data.audio_offset must be determined later */
	client_data.first_seekpoint_to_check = 0;
	client_data.error_occurred = false;

	decoder = FLAC__stream_decoder_new();

	if(0 == decoder) {
		fprintf(stderr, "%s: ERROR (--add-seekpoint) creating the decoder instance\n", filename);
		return false;
	}

	FLAC__stream_decoder_set_md5_checking(decoder, false);
	FLAC__stream_decoder_set_metadata_ignore_all(decoder);

	if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, /*metadata_callback=*/0, error_callback_, &client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
		fprintf(stderr, "%s: ERROR (--add-seekpoint) initializing the decoder instance (%s)\n", filename, FLAC__stream_decoder_get_resolved_state_string(decoder));
		ok = false;
	}

	if(ok && !FLAC__stream_decoder_process_until_end_of_metadata(decoder)) {
		fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file (%s)\n", filename, FLAC__stream_decoder_get_resolved_state_string(decoder));
		ok = false;
	}

	if(ok && !FLAC__stream_decoder_get_decode_position(decoder, &client_data.audio_offset)) {
		fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file\n", filename);
		ok = false;
	}
	client_data.last_offset = client_data.audio_offset;

	if(ok && !FLAC__stream_decoder_process_until_end_of_stream(decoder)) {
		fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file (%s)\n", filename, FLAC__stream_decoder_get_resolved_state_string(decoder));
		ok = false;
	}

	if(ok && client_data.error_occurred) {
		fprintf(stderr, "%s: ERROR (--add-seekpoint) decoding file (%u:%s)\n", filename, (unsigned)client_data.error_status, FLAC__StreamDecoderErrorStatusString[client_data.error_status]);
		ok = false;
	}

	*needs_write = true;
	FLAC__stream_decoder_delete(decoder);
	return ok;
}
FLAC__bool FLAC_plugin__decoder_init(FLAC__StreamDecoder *decoder, const char *filename, FLAC__int64 filesize, stream_data_struct *stream_data, output_config_t *config)
{
	FLAC__StreamDecoderInitStatus init_status;

	FLAC__ASSERT(decoder);
	FLAC_plugin__decoder_finish(decoder);
	/* init decoder */
	FLAC__stream_decoder_set_md5_checking(decoder, false);
	FLAC__stream_decoder_set_metadata_ignore_all(decoder);
	FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_STREAMINFO);
	FLAC__stream_decoder_set_metadata_respond(decoder, FLAC__METADATA_TYPE_VORBIS_COMMENT);

	if ((init_status = FLAC__stream_decoder_init_file(decoder, filename, write_callback, metadata_callback, error_callback, /*client_data=*/stream_data)) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
	{
		FLAC_plugin__show_error("Error while initializing decoder (%s [%s]).", FLAC__StreamDecoderInitStatusString[init_status], FLAC__stream_decoder_get_resolved_state_string(decoder));
		return false;
	}
	/* process */
	cfg = *config;
	wide_samples_in_reservoir_ = 0;
	stream_data->is_playing = false;
	stream_data->abort_flag = false;
	stream_data->has_replaygain = false;

	if (!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
	{
		FLAC_plugin__show_error("Error while processing metadata (%s).", FLAC__stream_decoder_get_resolved_state_string(decoder));
		return false;
	}
	/* check results */
	if (stream_data->abort_flag) return false;                /* metadata callback already popped up the error dialog */
	/* init replaygain */
	stream_data->output_bits_per_sample = stream_data->has_replaygain && cfg.replaygain.enable ?
		cfg.resolution.replaygain.bps_out :
		cfg.resolution.normal.dither_24_to_16 ? min(stream_data->bits_per_sample, 16) : stream_data->bits_per_sample;

	if (stream_data->has_replaygain && cfg.replaygain.enable && cfg.resolution.replaygain.dither)
		FLAC__replaygain_synthesis__init_dither_context(&stream_data->dither_context, stream_data->bits_per_sample, cfg.resolution.replaygain.noise_shaping);
	/* more inits */
	stream_data->eof = false;
	stream_data->seek_to = -1;
	stream_data->is_playing = true;
	stream_data->average_bps = (unsigned)(filesize / (125.*(double)(FLAC__int64)stream_data->total_samples/(double)stream_data->sample_rate));
	
	bh_index_last_w = 0;
	bh_index_last_o = BITRATE_HIST_SIZE;
	decode_position = 0;
	decode_position_last = 0;
	written_time_last = 0;

	return true;
}
Beispiel #8
0
int __stdcall
Flac2Wav(const char *fromFlacPath, const char *toWavPath)
{
    int result = F2WRT_Success;
    FLAC__bool ok = true;
    FLAC__StreamDecoder *decoder = NULL;
    FLAC__StreamDecoderInitStatus init_status;
    FlacDecodeArgs args;

    memset(&args, 0, sizeof args);
    args.errorCode = F2WRT_OtherError;

    args.fout = fopen(toWavPath, "wb");
    if (args.fout == NULL) {
        result = F2WRT_WriteOpenFailed;
        goto end;
    }

    decoder = FLAC__stream_decoder_new();
    if(decoder == NULL) {
        result = F2WRT_FlacStreamDecoderNewFailed;
        goto end;
    }

    FLAC__stream_decoder_set_md5_checking(decoder, true);

    init_status = FLAC__stream_decoder_init_file(
        decoder, fromFlacPath, WriteCallback, MetadataCallback, ErrorCallback, &args);
    if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
        result = F2WRT_FlacStreamDecoderInitFailed;
        goto end;
    }

    ok = FLAC__stream_decoder_process_until_end_of_stream(decoder);
    if (!ok) {
        result = args.errorCode;
        goto end;
    }

    result = F2WRT_Success;
end:
    if (NULL != decoder) {
        FLAC__stream_decoder_delete(decoder);
        decoder = NULL;
    }
    if (NULL != args.fout) {
        fclose(args.fout);
        args.fout = NULL;
    }

    return result;
}
Beispiel #9
0
static void flacdecode_init(struct xlplayer *xlplayer)
    {
    struct flacdecode_vars *self = xlplayer->dec_data;
    int src_error;
    
    if (!(self->decoder = FLAC__stream_decoder_new()))
        {
        fprintf(stderr, "flacdecode_init: %s could not initialise flac decoder\n", xlplayer->playername);
        goto cleanup;
        }
    if (FLAC__stream_decoder_init_file(self->decoder, xlplayer->pathname, flac_writer_callback, NULL, flac_error_callback, xlplayer) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
        {
        fprintf(stderr, "flacdecode_init: %s error during flac player initialisation\n", xlplayer->playername);
        FLAC__stream_decoder_delete(self->decoder);
        goto cleanup;
        }
    if (xlplayer->seek_s)
        {
        self->suppress_audio_output = TRUE;               /* prevent seek noise */
        FLAC__stream_decoder_seek_absolute(self->decoder, ((FLAC__uint64)xlplayer->seek_s) * ((FLAC__uint64)self->metainfo.data.stream_info.sample_rate));
        self->suppress_audio_output = FALSE;
        }
    if ((self->resample_f = (self->metainfo.data.stream_info.sample_rate != xlplayer->samplerate)))
        {
        fprintf(stderr, "flacdecode_init: %s configuring resampler\n", xlplayer->playername);
        xlplayer->src_state = src_new(xlplayer->rsqual, self->metainfo.data.stream_info.channels, &src_error);
        if (src_error)
            {
            fprintf(stderr, "flacdecode_init: %s src_new reports - %s\n", xlplayer->playername, src_strerror(src_error));
            FLAC__stream_decoder_delete(self->decoder);
            goto cleanup;
            }
        xlplayer->src_data.output_frames = 0;
        xlplayer->src_data.data_in = xlplayer->src_data.data_out = NULL;
        xlplayer->src_data.src_ratio = (double)xlplayer->samplerate / (double)self->metainfo.data.stream_info.sample_rate;
        xlplayer->src_data.end_of_input = 0;
        self->totalsamples = self->metainfo.data.stream_info.total_samples; 
        }
    else
        xlplayer->src_state = NULL;
    self->suppress_audio_output = FALSE;
    self->flbuf = NULL;
    return;
cleanup:
    free(self);
    xlplayer->playmode = PM_STOPPED;
    xlplayer->command = CMD_COMPLETE;
    }
Beispiel #10
0
int main(int argc, char *argv[])
{
	FLAC__bool ok = true;
	FLAC__StreamDecoder *decoder = 0;
	FLAC__StreamDecoderInitStatus init_status;
	FILE *fout;

	if(argc != 3) {
		fprintf(stderr, "usage: %s infile.flac outfile.wav\n", argv[0]);
		return 1;
	}

	if((fout = fopen(argv[2], "wb")) == NULL) {
		fprintf(stderr, "ERROR: opening %s for output\n", argv[2]);
		return 1;
	}

	if((decoder = FLAC__stream_decoder_new()) == NULL) {
		fprintf(stderr, "ERROR: allocating decoder\n");
		fclose(fout);
		return 1;
	}

	(void)FLAC__stream_decoder_set_md5_checking(decoder, true);

	init_status = FLAC__stream_decoder_init_file(decoder, argv[1], write_callback, metadata_callback, error_callback, /*client_data=*/fout);
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK) {
		fprintf(stderr, "ERROR: initializing decoder: %s\n", FLAC__StreamDecoderInitStatusString[init_status]);
		ok = false;
	}

	if(ok) {
		ok = FLAC__stream_decoder_process_until_end_of_stream(decoder);
		fprintf(stderr, "decoding: %s\n", ok? "succeeded" : "FAILED");
		fprintf(stderr, "   state: %s\n", FLAC__StreamDecoderStateString[FLAC__stream_decoder_get_state(decoder)]);
	}

	FLAC__stream_decoder_delete(decoder);
	fclose(fout);

	return 0;
}
Beispiel #11
0
/* read mode:
 * 0 - no read after seek
 * 1 - read 2 frames
 * 2 - read until end
 */
static FLAC__bool seek_barrage(FLAC__bool is_ogg, const char *filename, off_t filesize, unsigned count, FLAC__int64 total_samples, unsigned read_mode)
{
	FLAC__StreamDecoder *decoder;
	DecoderClientData decoder_client_data;
	unsigned i;
	long int n;

	decoder_client_data.got_data = false;
	decoder_client_data.total_samples = 0;
	decoder_client_data.quiet = false;
	decoder_client_data.ignore_errors = false;
	decoder_client_data.error_occurred = false;

	printf("\n+++ seek test: FLAC__StreamDecoder (%s FLAC, read_mode=%u)\n\n", is_ogg? "Ogg":"native", read_mode);

	decoder = FLAC__stream_decoder_new();
	if(0 == decoder)
		return die_("FLAC__stream_decoder_new() FAILED, returned NULL\n");

	if(is_ogg) {
		if(FLAC__stream_decoder_init_ogg_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder);
	}
	else {
		if(FLAC__stream_decoder_init_file(decoder, filename, write_callback_, metadata_callback_, error_callback_, &decoder_client_data) != FLAC__STREAM_DECODER_INIT_STATUS_OK)
			return die_s_("FLAC__stream_decoder_init_file() FAILED", decoder);
	}

	if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
		return die_s_("FLAC__stream_decoder_process_until_end_of_metadata() FAILED", decoder);

	if(!is_ogg) { /* not necessary to do this for Ogg because of its seeking method */
	/* process until end of stream to make sure we can still seek in that state */
		decoder_client_data.quiet = true;
		if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
			return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder);
		decoder_client_data.quiet = false;

		printf("stream decoder state is %s\n", FLAC__stream_decoder_get_resolved_state_string(decoder));
		if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_END_OF_STREAM)
			return die_s_("expected FLAC__STREAM_DECODER_END_OF_STREAM", decoder);
	}

#ifdef _MSC_VER
	printf("file's total_samples is %I64u\n", decoder_client_data.total_samples);
#else
	printf("file's total_samples is %llu\n", (unsigned long long)decoder_client_data.total_samples);
#endif
#if !defined _MSC_VER && !defined __MINGW32__ && !defined __EMX__
	if (decoder_client_data.total_samples > (FLAC__uint64)RAND_MAX) {
		printf("ERROR: must be total_samples < %u\n", (unsigned)RAND_MAX);
		return false;
	}
#endif
	n = (long int)decoder_client_data.total_samples;

	if(n == 0 && total_samples >= 0)
		n = (long int)total_samples;

	/* if we don't have a total samples count, just guess based on the file size */
	/* @@@ for is_ogg we should get it from last page's granulepos */
	if(n == 0) {
		/* 8 would imply no compression, 9 guarantees that we will get some samples off the end of the stream to test that case */
		n = 9 * filesize / (decoder_client_data.channels * decoder_client_data.bits_per_sample);
#if !defined _MSC_VER && !defined __MINGW32__
		if(n > RAND_MAX)
			n = RAND_MAX;
#endif
	}

	printf("Begin seek barrage, count=%u\n", count);

	for (i = 0; !stop_signal_ && (count == 0 || i < count); i++) {
		FLAC__uint64 pos;

		/* for the first 10, seek to the first 10 samples */
		if (n >= 10 && i < 10) {
			pos = i;
		}
		/* for the second 10, seek to the last 10 samples */
		else if (n >= 10 && i < 20) {
			pos = n - 1 - (i-10);
		}
		/* for the third 10, seek past the end and make sure we fail properly as expected */
		else if (i < 30) {
			pos = n + (i-20);
		}
		else {
#if !defined _MSC_VER && !defined __MINGW32__
			pos = (FLAC__uint64)(random() % n);
#else
			/* RAND_MAX is only 32767 in my MSVC */
			pos = (FLAC__uint64)((rand()<<15|rand()) % n);
#endif
		}

#ifdef _MSC_VER
		printf("seek(%I64u)... ", pos);
#else
		printf("seek(%llu)... ", (unsigned long long)pos);
#endif
		fflush(stdout);
		if(!FLAC__stream_decoder_seek_absolute(decoder, pos)) {
			if(pos >= (FLAC__uint64)n)
				printf("seek past end failed as expected... ");
			else if(decoder_client_data.total_samples == 0 && total_samples <= 0)
				printf("seek failed, assuming it was past EOF... ");
			else
				return die_s_("FLAC__stream_decoder_seek_absolute() FAILED", decoder);
			if(!FLAC__stream_decoder_flush(decoder))
				return die_s_("FLAC__stream_decoder_flush() FAILED", decoder);
		}
		else if(read_mode == 1) {
			printf("decode_frame... ");
			fflush(stdout);
			if(!FLAC__stream_decoder_process_single(decoder))
				return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder);

			printf("decode_frame... ");
			fflush(stdout);
			if(!FLAC__stream_decoder_process_single(decoder))
				return die_s_("FLAC__stream_decoder_process_single() FAILED", decoder);
		}
		else if(read_mode == 2) {
			printf("decode_all... ");
			fflush(stdout);
			decoder_client_data.quiet = true;
			if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
				return die_s_("FLAC__stream_decoder_process_until_end_of_stream() FAILED", decoder);
			decoder_client_data.quiet = false;
		}

		printf("OK\n");
		fflush(stdout);
	}

	if(FLAC__stream_decoder_get_state(decoder) != FLAC__STREAM_DECODER_UNINITIALIZED) {
		if(!FLAC__stream_decoder_finish(decoder))
			return die_s_("FLAC__stream_decoder_finish() FAILED", decoder);
	}

	FLAC__stream_decoder_delete(decoder);
	printf("\nPASSED!\n");

	return true;
}
Beispiel #12
0
static FLAC__bool test_stream_decoder(Layer layer, FLAC__bool is_ogg)
{
	FLAC__StreamDecoder *decoder;
	FLAC__StreamDecoderInitStatus init_status;
	FLAC__StreamDecoderState state;
	StreamDecoderClientData decoder_client_data;
	FLAC__bool expect;

	decoder_client_data.layer = layer;

	printf("\n+++ libFLAC unit test: FLAC__StreamDecoder (layer: %s, format: %s)\n\n", LayerString[layer], is_ogg? "Ogg FLAC" : "FLAC");

	printf("testing FLAC__stream_decoder_new()... ");
	decoder = FLAC__stream_decoder_new();
	if(0 == decoder) {
		printf("FAILED, returned NULL\n");
		return false;
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_delete()... ");
	FLAC__stream_decoder_delete(decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_new()... ");
	decoder = FLAC__stream_decoder_new();
	if(0 == decoder) {
		printf("FAILED, returned NULL\n");
		return false;
	}
	printf("OK\n");

	switch(layer) {
		case LAYER_STREAM:
		case LAYER_SEEKABLE_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0) :
				FLAC__stream_decoder_init_stream(decoder, 0, 0, 0, 0, 0, 0, 0, 0, 0);
			break;
		case LAYER_FILE:
			printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_FILE(decoder, stdin, 0, 0, 0, 0) :
				FLAC__stream_decoder_init_FILE(decoder, stdin, 0, 0, 0, 0);
			break;
		case LAYER_FILENAME:
			printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0) :
				FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), 0, 0, 0, 0);
			break;
		default:
			die_("internal error 003");
			return false;
	}
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_INVALID_CALLBACKS)
		return die_s_(0, decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_delete()... ");
	FLAC__stream_decoder_delete(decoder);
	printf("OK\n");

	num_expected_ = 0;
	expected_metadata_sequence_[num_expected_++] = &streaminfo_;

	printf("testing FLAC__stream_decoder_new()... ");
	decoder = FLAC__stream_decoder_new();
	if(0 == decoder) {
		printf("FAILED, returned NULL\n");
		return false;
	}
	printf("OK\n");

	if(is_ogg) {
		printf("testing FLAC__stream_decoder_set_ogg_serial_number()... ");
		if(!FLAC__stream_decoder_set_ogg_serial_number(decoder, file_utils__ogg_serial_number))
			return die_s_("returned false", decoder);
		printf("OK\n");
	}

	printf("testing FLAC__stream_decoder_set_md5_checking()... ");
	if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
		return die_s_("returned false", decoder);
	printf("OK\n");

	if(layer < LAYER_FILENAME) {
		printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
		decoder_client_data.file = fopen(flacfilename(is_ogg), "rb");
		if(0 == decoder_client_data.file) {
			printf("ERROR (%s)\n", strerror(errno));
			return false;
		}
		printf("OK\n");
	}

	switch(layer) {
		case LAYER_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		case LAYER_SEEKABLE_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		case LAYER_FILE:
			printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_FILE(decoder, decoder_client_data.file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		case LAYER_FILENAME:
			printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data) :
				FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, &decoder_client_data);
			break;
		default:
			die_("internal error 009");
			return false;
	}
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
		return die_s_(0, decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_state()... ");
	state = FLAC__stream_decoder_get_state(decoder);
	printf("returned state = %u (%s)... OK\n", state, FLAC__StreamDecoderStateString[state]);

	decoder_client_data.current_metadata_number = 0;
	decoder_client_data.ignore_errors = false;
	decoder_client_data.error_occurred = false;

	printf("testing FLAC__stream_decoder_get_md5_checking()... ");
	if(!FLAC__stream_decoder_get_md5_checking(decoder)) {
		printf("FAILED, returned false, expected true\n");
		return false;
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_process_until_end_of_metadata()... ");
	if(!FLAC__stream_decoder_process_until_end_of_metadata(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_process_single()... ");
	if(!FLAC__stream_decoder_process_single(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_skip_single_frame()... ");
	if(!FLAC__stream_decoder_skip_single_frame(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	if(layer < LAYER_FILE) {
		printf("testing FLAC__stream_decoder_flush()... ");
		if(!FLAC__stream_decoder_flush(decoder))
			return die_s_("returned false", decoder);
		printf("OK\n");

		decoder_client_data.ignore_errors = true;
		printf("testing FLAC__stream_decoder_process_single()... ");
		if(!FLAC__stream_decoder_process_single(decoder))
			return die_s_("returned false", decoder);
		printf("OK\n");
		decoder_client_data.ignore_errors = false;
	}

	expect = (layer != LAYER_STREAM);
	printf("testing FLAC__stream_decoder_seek_absolute()... ");
	if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
		return die_s_(expect? "returned false" : "returned true", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
	if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	expect = (layer != LAYER_STREAM);
	printf("testing FLAC__stream_decoder_seek_absolute()... ");
	if(FLAC__stream_decoder_seek_absolute(decoder, 0) != expect)
		return die_s_(expect? "returned false" : "returned true", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_channels()... ");
	{
		unsigned channels = FLAC__stream_decoder_get_channels(decoder);
		if(channels != streaminfo_.data.stream_info.channels) {
			printf("FAILED, returned %u, expected %u\n", channels, streaminfo_.data.stream_info.channels);
			return false;
		}
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_bits_per_sample()... ");
	{
		unsigned bits_per_sample = FLAC__stream_decoder_get_bits_per_sample(decoder);
		if(bits_per_sample != streaminfo_.data.stream_info.bits_per_sample) {
			printf("FAILED, returned %u, expected %u\n", bits_per_sample, streaminfo_.data.stream_info.bits_per_sample);
			return false;
		}
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_sample_rate()... ");
	{
		unsigned sample_rate = FLAC__stream_decoder_get_sample_rate(decoder);
		if(sample_rate != streaminfo_.data.stream_info.sample_rate) {
			printf("FAILED, returned %u, expected %u\n", sample_rate, streaminfo_.data.stream_info.sample_rate);
			return false;
		}
	}
	printf("OK\n");

	printf("testing FLAC__stream_decoder_get_blocksize()... ");
	{
		unsigned blocksize = FLAC__stream_decoder_get_blocksize(decoder);
		/* value could be anything since we're at the last block, so accept any reasonable answer */
		printf("returned %u... %s\n", blocksize, blocksize>0? "OK" : "FAILED");
		if(blocksize == 0)
			return false;
	}

	printf("testing FLAC__stream_decoder_get_channel_assignment()... ");
	{
		FLAC__ChannelAssignment ca = FLAC__stream_decoder_get_channel_assignment(decoder);
		printf("returned %u (%s)... OK\n", (unsigned)ca, FLAC__ChannelAssignmentString[ca]);
	}

	if(layer < LAYER_FILE) {
		printf("testing FLAC__stream_decoder_reset()... ");
		if(!FLAC__stream_decoder_reset(decoder)) {
			state = FLAC__stream_decoder_get_state(decoder);
			printf("FAILED, returned false, state = %u (%s)\n", state, FLAC__StreamDecoderStateString[state]);
			return false;
		}
		printf("OK\n");

		if(layer == LAYER_STREAM) {
			/* after a reset() we have to rewind the input ourselves */
			printf("rewinding input... ");
			if(fseeko(decoder_client_data.file, 0, SEEK_SET) < 0) {
				printf("FAILED, errno = %d\n", errno);
				return false;
			}
			printf("OK\n");
		}

		decoder_client_data.current_metadata_number = 0;

		printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
		if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
			return die_s_("returned false", decoder);
		printf("OK\n");
	}

	printf("testing FLAC__stream_decoder_finish()... ");
	if(!FLAC__stream_decoder_finish(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	/*
	 * respond all
	 */

	printf("testing FLAC__stream_decoder_set_metadata_respond_all()... ");
	if(!FLAC__stream_decoder_set_metadata_respond_all(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	num_expected_ = 0;
	if(is_ogg) { /* encoder moves vorbis comment after streaminfo according to ogg mapping */
		expected_metadata_sequence_[num_expected_++] = &streaminfo_;
		expected_metadata_sequence_[num_expected_++] = &vorbiscomment_;
		expected_metadata_sequence_[num_expected_++] = &padding_;
		expected_metadata_sequence_[num_expected_++] = &seektable_;
		expected_metadata_sequence_[num_expected
Beispiel #13
0
static FLAC__bool stream_decoder_test_respond_(FLAC__StreamDecoder *decoder, StreamDecoderClientData *dcd, FLAC__bool is_ogg)
{
	FLAC__StreamDecoderInitStatus init_status;

	if(!FLAC__stream_decoder_set_md5_checking(decoder, true))
		return die_s_("at FLAC__stream_decoder_set_md5_checking(), returned false", decoder);

	/* for FLAC__stream_encoder_init_FILE(), the FLAC__stream_encoder_finish() closes the file so we have to keep re-opening: */
	if(dcd->layer == LAYER_FILE) {
		printf("opening %sFLAC file... ", is_ogg? "Ogg ":"");
		dcd->file = fopen(flacfilename(is_ogg), "rb");
		if(0 == dcd->file) {
			printf("ERROR (%s)\n", strerror(errno));
			return false;
		}
		printf("OK\n");
	}

	switch(dcd->layer) {
		case LAYER_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, /*seek_callback=*/0, /*tell_callback=*/0, /*length_callback=*/0, /*eof_callback=*/0, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd)
			;
			break;
		case LAYER_SEEKABLE_STREAM:
			printf("testing FLAC__stream_decoder_init_%sstream()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_stream(decoder, stream_decoder_read_callback_, stream_decoder_seek_callback_, stream_decoder_tell_callback_, stream_decoder_length_callback_, stream_decoder_eof_callback_, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
			break;
		case LAYER_FILE:
			printf("testing FLAC__stream_decoder_init_%sFILE()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_FILE(decoder, dcd->file, stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
			break;
		case LAYER_FILENAME:
			printf("testing FLAC__stream_decoder_init_%sfile()... ", is_ogg? "ogg_":"");
			init_status = is_ogg?
				FLAC__stream_decoder_init_ogg_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd) :
				FLAC__stream_decoder_init_file(decoder, flacfilename(is_ogg), stream_decoder_write_callback_, stream_decoder_metadata_callback_, stream_decoder_error_callback_, dcd);
			break;
		default:
			die_("internal error 000");
			return false;
	}
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
		return die_s_(0, decoder);
	printf("OK\n");

	dcd->current_metadata_number = 0;

	if(dcd->layer < LAYER_FILE && fseeko(dcd->file, 0, SEEK_SET) < 0) {
		printf("FAILED rewinding input, errno = %d\n", errno);
		return false;
	}

	printf("testing FLAC__stream_decoder_process_until_end_of_stream()... ");
	if(!FLAC__stream_decoder_process_until_end_of_stream(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	printf("testing FLAC__stream_decoder_finish()... ");
	if(!FLAC__stream_decoder_finish(decoder))
		return die_s_("returned false", decoder);
	printf("OK\n");

	return true;
}
/* 
	Populate the imFileInfoRec8 structure describing this file instance
	to Premiere.  Check file validity, allocate any private instance data 
	to share between different calls.
*/
prMALError 
SDKGetInfo8(
	imStdParms			*stdParms, 
	imFileAccessRec8	*fileAccessInfo, 
	imFileInfoRec8		*fileInfo)
{
	prMALError					result				= malNoError;
	PrivateDataH pdH = reinterpret_cast<PrivateDataH>(fileInfo->privatedata); 

	stdParms->piSuites->memFuncs->lockHandle(reinterpret_cast<char**>(pdH)); //Lock private data

	(*pdH)->flacErrorCode = 0;
	(*pdH)->flacDecoder = 0;

	char filepathASCII[255];
	int stringLength = (int)wcslen(reinterpret_cast<const wchar_t*>(fileAccessInfo->filepath));
	wcstombs_s(	NULL, reinterpret_cast<char*>(filepathASCII), sizeof (filepathASCII), fileAccessInfo->filepath, stringLength);

	FLAC__bool ok = true;
    FLAC__StreamDecoderInitStatus init_status;
	if(((*pdH)->flacDecoder = FLAC__stream_decoder_new()) == NULL)
	{
		(*pdH)->flacErrorCode = 1;
	}

	FLAC__stream_decoder_set_md5_checking((*pdH)->flacDecoder, true);

	init_status = FLAC__stream_decoder_init_file((*pdH)->flacDecoder, filepathASCII, write_callback, NULL, error_callback, pdH);
	if(init_status != FLAC__STREAM_DECODER_INIT_STATUS_OK )
	{
		return imBadFile; //Error, bail out
	}
	FLAC__stream_decoder_process_until_end_of_metadata((*pdH)->flacDecoder);
	FLAC__stream_decoder_process_single((*pdH)->flacDecoder);

	(*pdH)->audioChannels = FLAC__stream_decoder_get_channels((*pdH)->flacDecoder);
	(*pdH)->audioNumberOfSamples = FLAC__stream_decoder_get_total_samples((*pdH)->flacDecoder);
	(*pdH)->audioNumberOfSamplesPerSecond = FLAC__stream_decoder_get_sample_rate((*pdH)->flacDecoder);
	(*pdH)->audioBytesPerSample = FLAC__stream_decoder_get_bits_per_sample((*pdH)->flacDecoder) / 8;
	(*pdH)->audioPosition = 0;

	//Fill out the general file info
	fileInfo->accessModes						= kSeparateSequentialAudio;
	fileInfo->hasDataRate						= kPrFalse;	
	fileInfo->hasVideo							= kPrFalse;
	fileInfo->hasAudio							= kPrTrue;
	fileInfo->alwaysUnquiet						= 0;
	fileInfo->highMemUsage						= 0;
	fileInfo->audInfo.numChannels				= (*pdH)->audioChannels;
	fileInfo->audInfo.sampleRate				= (float)(*pdH)->audioNumberOfSamplesPerSecond;
	fileInfo->audDuration						= (*pdH)->audioNumberOfSamples;

	if((*pdH)->audioBytesPerSample == 1)
	{
		fileInfo->audInfo.sampleType = kPrAudioSampleType_8BitInt;
	}
	else if((*pdH)->audioBytesPerSample == 2)
	{
		fileInfo->audInfo.sampleType = kPrAudioSampleType_16BitInt;
	}
	else if((*pdH)->audioBytesPerSample == 3)
	{
		fileInfo->audInfo.sampleType = kPrAudioSampleType_24BitInt;
	}
	else if((*pdH)->audioBytesPerSample == 4)
	{
		fileInfo->audInfo.sampleType = kPrAudioSampleType_32BitInt;
	}
	else
	{
		fileInfo->audInfo.sampleType = kPrAudioSampleType_Other;
	}

	(*pdH)->suiteBasic = stdParms->piSuites->utilFuncs->getSPBasicSuite(); //Allocate an audio suite
	if ((*pdH)->suiteBasic)
	{
		(*pdH)->suiteBasic->AcquireSuite (kPrSDKAudioSuite, kPrSDKAudioSuiteVersion, (const void**)&(*pdH)->suiteAudio);
	}

	stdParms->piSuites->memFuncs->unlockHandle(reinterpret_cast<char**>(pdH)); //Unlock private data

	return result;
}
Beispiel #15
0
static int private_load_flac (
	LISndSample* self,
	const char*  file)
{
	void* buffer;
	ALenum format;
	FLAC__uint32 bps;
	FLAC__uint32 channels;
	FLAC__uint32 length;
	FLAC__uint32 rate;
	FLAC__StreamDecoder* decoder;
	FLAC__StreamDecoderInitStatus status;
	LIArcWriter* writer;

	/* Create decoder. */
	decoder = FLAC__stream_decoder_new ();
	if (decoder == NULL)
	{
		lisys_error_set (ENOMEM, NULL);
		return 0;
	}

	/* Allocate temporary storage. */
	writer = liarc_writer_new ();
	if (writer == NULL)
	{
		FLAC__stream_decoder_delete (decoder);
		return 0;
	}

	/* Decode file. */
	status = FLAC__stream_decoder_init_file (decoder, file,
		private_flac_stream_callback, NULL, private_flac_error_callback, writer);
	if (status != FLAC__STREAM_DECODER_INIT_STATUS_OK)
	{
		lisys_error_set (EINVAL, "FLAC decoder cannot open file `%s'", file);
		liarc_writer_free (writer);
		FLAC__stream_decoder_delete (decoder);
		return 0;
	}
	if (!FLAC__stream_decoder_process_until_end_of_stream (decoder))
	{
		lisys_error_set (EINVAL, "FLAC decoder failed to process file `%s'", file);
		liarc_writer_free (writer);
		FLAC__stream_decoder_finish (decoder);
		FLAC__stream_decoder_delete (decoder);
		return 0;
	}

	/* Stream format. */
	bps = FLAC__stream_decoder_get_bits_per_sample (decoder);
	channels = FLAC__stream_decoder_get_channels (decoder);
	length = liarc_writer_get_length (writer);
	rate = FLAC__stream_decoder_get_sample_rate (decoder);

	/* Upload format. */
	if (channels == 1 && bps == 8)
		format = AL_FORMAT_MONO8;
	else if (channels == 1 && bps == 16)
		format = AL_FORMAT_MONO16;
	else if (channels == 2 && bps == 8)
		format = AL_FORMAT_STEREO8;
	else if (channels == 2 && bps == 16)
		format = AL_FORMAT_STEREO16;
	else
	{
		lisys_error_set (EINVAL, "FLAC stream format unsupported in file `%s'", file);
		liarc_writer_free (writer);
		FLAC__stream_decoder_finish (decoder);
		FLAC__stream_decoder_delete (decoder);
		return 0;
	}

	/* Upload to OpenAL. */
	buffer = lisys_calloc (length, sizeof (uint8_t));
	if (buffer != NULL)
	{
		memcpy (buffer, liarc_writer_get_buffer (writer), length);
		private_load_raw (self, format, buffer, length, rate);
		lisys_free (buffer);
	}

	/* Finish reading. */
	liarc_writer_free (writer);
	FLAC__stream_decoder_finish (decoder);
	FLAC__stream_decoder_delete (decoder);

	return 1;
}