Ejemplo n.º 1
0
static DWORD WINAPI DecodeThread(void *unused)
{
	const unsigned channels = stream_data_.channels;
	const unsigned bits_per_sample = stream_data_.bits_per_sample;
	const unsigned target_bps = stream_data_.output_bits_per_sample;
	const unsigned sample_rate = stream_data_.sample_rate;
	const unsigned fact = channels * (target_bps/8);

	while (stream_data_.is_playing)
	{
		/* seek needed */
		if (stream_data_.seek_to != -1)
		{
			const int pos = FLAC_plugin__seek(decoder_, &stream_data_);
			if (pos != -1) mod_.outMod->Flush(pos);
		}
		/* stream ended */
		else if (stream_data_.eof)
		{
			if (!mod_.outMod->IsPlaying())
			{
				PostMessage(mod_.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
				return 0;
			}
			Sleep(10);
		}
		/* decode */
		else
		{
			/* decode samples */
			int bytes = FLAC_plugin__decode(decoder_, &stream_data_, sample_buffer_);
			const int n = bytes / fact;
			/* visualization */
			do_vis(sample_buffer_, channels, target_bps, mod_.outMod->GetWrittenTime(), n);
			/* dsp */
			if (mod_.dsp_isactive())
				bytes = mod_.dsp_dosamples((short*)sample_buffer_, n, target_bps, channels, sample_rate) * fact;
			/* output */
			while (mod_.outMod->CanWrite()<bytes && stream_data_.is_playing && stream_data_.seek_to==-1)
				Sleep(20);
			if (stream_data_.is_playing && stream_data_.seek_to==-1)
				mod_.outMod->Write(sample_buffer_, bytes);
			/* show bitrate */
			if (flac_cfg.display.show_bps)
			{
				const int rate = FLAC_plugin__get_rate(mod_.outMod->GetWrittenTime(), mod_.outMod->GetOutputTime(), &stream_data_);
				if (rate) mod_.SetInfo(rate/1000, stream_data_.sample_rate/1000, stream_data_.channels, 1);
			}
		}
	}

	return 0;
}
Ejemplo n.º 2
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;
}