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; }
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; }