Пример #1
0
int FLAC_plugin__seek(FLAC__FileDecoder *decoder, file_info_struct *file_info)
{
	int pos;
	const FLAC__uint64 target_sample =
		(FLAC__uint64)file_info->total_samples*file_info->seek_to / file_info->length_in_msec;

	if (!FLAC__file_decoder_seek_absolute(decoder, target_sample))
		return -1;

	file_info->seek_to = -1;
	file_info->eof = false;
	wide_samples_in_reservoir_ = 0;
	pos = (int)(target_sample*1000 / file_info->sample_rate);

	bh_index_last_o = bh_index_last_w = (pos/BITRATE_HIST_SEGMENT_MSEC) % BITRATE_HIST_SIZE;
	if (!FLAC__file_decoder_get_decode_position(decoder, &decode_position))
		decode_position = 0;

	return pos;
}
Пример #2
0
static FLAC__bool seek_barrage_native_flac(const char *filename, off_t filesize, unsigned count)
{
	FLAC__FileDecoder *decoder;
	decoder_client_data_struct decoder_client_data;
	unsigned i;
	long int n;

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

	printf("\n+++ seek test: FLAC__FileDecoder\n\n");

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

	if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_))
		return die_f_("FLAC__file_decoder_set_write_callback() FAILED", decoder);

	if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_))
		return die_f_("FLAC__file_decoder_set_metadata_callback() FAILED", decoder);

	if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_))
		return die_f_("FLAC__file_decoder_set_error_callback() FAILED", decoder);

	if(!FLAC__file_decoder_set_client_data(decoder, &decoder_client_data))
		return die_f_("FLAC__file_decoder_set_client_data() FAILED", decoder);

	if(!FLAC__file_decoder_set_filename(decoder, filename))
		return die_f_("FLAC__file_decoder_set_filename() FAILED", decoder);

	if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
		return die_f_("FLAC__file_decoder_init() FAILED", decoder);

	if(!FLAC__file_decoder_process_until_end_of_metadata(decoder))
		return die_f_("FLAC__file_decoder_process_until_end_of_metadata() FAILED", decoder);

	printf("file's total_samples is %llu\n", decoder_client_data.total_samples);
#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 we don't have a total samples count, just guess based on the file size */
	/* @@@ 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
		}

		printf("seek(%llu)... ", pos);
		fflush(stdout);
		if(!FLAC__file_decoder_seek_absolute(decoder, pos)) {
			if(pos < (FLAC__uint64)n && decoder_client_data.total_samples != 0)
				return die_f_("FLAC__file_decoder_seek_absolute() FAILED", decoder);
			else if(decoder_client_data.total_samples == 0)
				printf("seek failed, assuming it was past EOF... ");
			else
				printf("seek past end failed as expected... ");

			/* hack to work around a deficiency in the seek API's behavior */
			/* seeking past EOF sets the file decoder state to non-OK and there's no ..._flush() or ..._reset() call to reset it */
			if(!FLAC__file_decoder_finish(decoder))
				return die_f_("FLAC__file_decoder_finish() FAILED", decoder);

			if(!FLAC__file_decoder_set_write_callback(decoder, file_decoder_write_callback_))
				return die_f_("FLAC__file_decoder_set_write_callback() FAILED", decoder);

			if(!FLAC__file_decoder_set_metadata_callback(decoder, file_decoder_metadata_callback_))
				return die_f_("FLAC__file_decoder_set_metadata_callback() FAILED", decoder);

			if(!FLAC__file_decoder_set_error_callback(decoder, file_decoder_error_callback_))
				return die_f_("FLAC__file_decoder_set_error_callback() FAILED", decoder);

			if(!FLAC__file_decoder_set_client_data(decoder, &decoder_client_data))
				return die_f_("FLAC__file_decoder_set_client_data() FAILED", decoder);

			if(!FLAC__file_decoder_set_filename(decoder, filename))
				return die_f_("FLAC__file_decoder_set_filename() FAILED", decoder);

			if(FLAC__file_decoder_init(decoder) != FLAC__FILE_DECODER_OK)
				return die_f_("FLAC__file_decoder_init() FAILED", decoder);

			if(!FLAC__file_decoder_process_until_end_of_metadata(decoder))
				return die_f_("FLAC__file_decoder_process_until_end_of_metadata() FAILED", decoder);
		}
		else {
			printf("decode_frame... ");
			fflush(stdout);
			if(!FLAC__file_decoder_process_single(decoder))
				return die_f_("FLAC__file_decoder_process_single() FAILED", decoder);

			printf("decode_frame... ");
			fflush(stdout);
			if(!FLAC__file_decoder_process_single(decoder))
				return die_f_("FLAC__file_decoder_process_single() FAILED", decoder);
		}

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

	if(FLAC__file_decoder_get_state(decoder) != FLAC__FILE_DECODER_UNINITIALIZED) {
		if(!FLAC__file_decoder_finish(decoder))
			return die_f_("FLAC__file_decoder_finish() FAILED", decoder);
	}

	printf("\nPASSED!\n");

	return true;
}
Пример #3
0
DWORD WINAPI __stdcall DecodeThread(void *b)
{
	int done = 0;

	while(! *((int *)b) ) {
		const unsigned channels = file_info_.channels;
		const unsigned bits_per_sample = file_info_.bits_per_sample;
#ifdef FLAC__DO_DITHER
		const unsigned target_bps = min(bits_per_sample, 16);
#else
		const unsigned target_bps = bits_per_sample;
#endif
		const unsigned sample_rate = file_info_.sample_rate;
		if(seek_needed_ != -1) {
			const double distance = (double)seek_needed_ / (double)getlength();
			const unsigned target_sample = (unsigned)(distance * (double)file_info_.total_samples);
			if(FLAC__file_decoder_seek_absolute(decoder_, (FLAC__uint64)target_sample)) {
				decode_pos_ms_ = (int)(distance * (double)getlength());
				seek_needed_ = -1;
				done = 0;
				mod_.outMod->Flush(decode_pos_ms_);
			}
		}
		if(done) {
			if(!mod_.outMod->IsPlaying()) {
				PostMessage(mod_.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
				return 0;
			}
			Sleep(10);
		}
		else if(mod_.outMod->CanWrite() >= ((int)(SAMPLES_PER_WRITE*channels*((target_bps+7)/8)) << (mod_.dsp_isactive()?1:0))) {
			while(wide_samples_in_reservoir_ < SAMPLES_PER_WRITE) {
				if(FLAC__file_decoder_get_state(decoder_) == FLAC__FILE_DECODER_END_OF_FILE) {
					done = 1;
					break;
				}
				else if(!FLAC__file_decoder_process_single(decoder_)) {
					MessageBox(mod_.hMainWindow, FLAC__FileDecoderStateString[FLAC__file_decoder_get_state(decoder_)], "READ ERROR processing frame", 0);
					done = 1;
					break;
				}
			}

			if(wide_samples_in_reservoir_ == 0) {
				done = 1;
			}
			else {
				const unsigned n = min(wide_samples_in_reservoir_, SAMPLES_PER_WRITE);
				const unsigned delta = n * channels;
				int bytes = (int)FLAC__plugin_common__pack_pcm_signed_little_endian(sample_buffer_, reservoir_, n, channels, bits_per_sample, target_bps);
				unsigned i;

				for(i = delta; i < wide_samples_in_reservoir_ * channels; i++)
					reservoir_[i-delta] = reservoir_[i];
				wide_samples_in_reservoir_ -= n;

				do_vis((char *)sample_buffer_, channels, target_bps, decode_pos_ms_, n);
				decode_pos_ms_ += (n*1000 + sample_rate/2)/sample_rate;
				if(mod_.dsp_isactive())
					bytes = mod_.dsp_dosamples((short *)sample_buffer_, n, target_bps, channels, sample_rate) * (channels*target_bps/8);
				mod_.outMod->Write(sample_buffer_, bytes);
			}
		}
		else Sleep(20);
	}
	return 0;
}