Пример #1
0
void writeSound(void)
{
	int ret = soundBufferLen;
	//int i;
	
	while (mod.outMod->CanWrite() < ((ret*sndNumChannels*(sndBitsPerSample/8))<<(mod.dsp_isactive()?1:0)))
		Sleep(50);


	mod.SAAddPCMData((char *)soundFinalWave,sndNumChannels,sndBitsPerSample,decode_pos_ms);
	mod.VSAAddPCMData((char *)soundFinalWave,sndNumChannels,sndBitsPerSample,decode_pos_ms);
	decode_pos_ms += (ret/(2*sndNumChannels) * 1000) / (float)sndSamplesPerSec;

	if (mod.dsp_isactive())
		ret=mod.dsp_dosamples((short *)soundFinalWave,ret/sndNumChannels/(sndBitsPerSample/8),sndBitsPerSample,sndNumChannels,sndSamplesPerSec)*(sndNumChannels*(sndBitsPerSample/8));
	


	//if(soundFinalWave[0]==0&&soundFinalWave[1]==0&&soundFinalWave[2]==0&&soundFinalWave[3]==0)
	//  DisplayError("%.2X%.2X%.2X%.2X - %d", soundFinalWave[0],soundFinalWave[1],soundFinalWave[2],soundFinalWave[3],ret);
	mod.outMod->Write((char *)&soundFinalWave,ret);
	

	if (seek_needed != -1)		//if a seek is initiated
	{
		mod.outMod->Flush((long)decode_pos_ms);
		
		if (seek_needed < decode_pos_ms)	//if we are asked to seek backwards.  we have to start from the beginning
		{
			GSFClose();
			GSFRun(lastfn);
			decode_pos_ms = 0;
		}
	}
}
Пример #2
0
static int play(char *fn)
{
	int song;
	int maxlatency;
	DWORD threadId;
	strcpy(current_filename_with_song, fn);
	song = extractSongNumber(fn, current_filename);
	if (!loadModule(current_filename, module, &module_len))
		return -1;
	if (!ASAP_Load(&asap, current_filename, module, module_len))
		return 1;
	if (song < 0)
		song = asap.module_info.default_song;
	duration = playSong(song);
	maxlatency = mod.outMod->Open(ASAP_SAMPLE_RATE, channels, BITS_PER_SAMPLE, -1, -1);
	if (maxlatency < 0)
		return 1;
	mod.SetInfo(BITS_PER_SAMPLE, ASAP_SAMPLE_RATE / 1000, channels, 1);
	mod.SAVSAInit(maxlatency, ASAP_SAMPLE_RATE);
	// the order of VSASetInfo's arguments in in2.h is wrong!
	// http://forums.winamp.com/showthread.php?postid=1841035
	mod.VSASetInfo(ASAP_SAMPLE_RATE, channels);
	mod.outMod->SetVolume(-666);
	seek_needed = -1;
	thread_run = TRUE;
	thread_handle = CreateThread(NULL, 0, playThread, NULL, 0, &threadId);
	if (playing_info)
		updateInfoDialog(current_filename, song);
	return thread_handle != NULL ? 0 : 1;
}
Пример #3
0
static void do_vis(char *data, int nch, int resolution, int position, unsigned samples)
{
	static char vis_buffer[SAMPLES_PER_WRITE * FLAC_PLUGIN__MAX_SUPPORTED_CHANNELS];
	char *ptr;
	int size, count;

	/*
	 * Winamp visuals may have problems accepting sample sizes larger than
	 * 16 bits, so we reduce the sample size here if necessary.
	 */

	switch(resolution) {
		case 32:
		case 24:
			size  = resolution / 8;
			count = samples * nch;
			data += size - 1;

			ptr = vis_buffer;
			while(count--) {
				*ptr++ = data[0] ^ 0x80;
				data += size;
			}

			data = vis_buffer;
			resolution = 8;
			/* fall through */
		case 16:
		case 8:
			mod_.SAAddPCMData(data, nch, resolution, position);
			mod_.VSAAddPCMData(data, nch, resolution, position);
	}
}
Пример #4
0
static int play(char *fn)
{
	char filename[MAX_PATH];
	int song;
	const ASAPInfo *info;
	int channels;
	int maxlatency;
	DWORD threadId;
	strcpy(playing_filename_with_song, fn);
	song = extractSongNumber(fn, filename);
	if (!loadModule(filename, module, &module_len))
		return -1;
	if (!ASAP_Load(asap, filename, module, module_len))
		return 1;
	info = ASAP_GetInfo(asap);
	if (song < 0)
		song = ASAPInfo_GetDefaultSong(info);
	duration = playSong(song);
	channels = ASAPInfo_GetChannels(info);
	maxlatency = mod.outMod->Open(ASAP_SAMPLE_RATE, channels, BITS_PER_SAMPLE, -1, -1);
	if (maxlatency < 0)
		return 1;
	mod.SetInfo(BITS_PER_SAMPLE, ASAP_SAMPLE_RATE / 1000, channels, 1);
	mod.SAVSAInit(maxlatency, ASAP_SAMPLE_RATE);
	// the order of VSASetInfo's arguments in in2.h is wrong!
	// http://forums.winamp.com/showthread.php?postid=1841035
	mod.VSASetInfo(ASAP_SAMPLE_RATE, channels);
	mod.outMod->SetVolume(-666);
	seek_needed = -1;
	thread_run = TRUE;
	thread_handle = CreateThread(NULL, 0, playThread, NULL, 0, &threadId);
	setPlayingSong(filename, song);
	return thread_handle != NULL ? 0 : 1;
}
Пример #5
0
static int play(char *fn)
{
	LONGLONG filesize;
	DWORD thread_id;
	int   maxlatency;
	/* checks */
	if (decoder_ == 0) return 1;
	if (!(filesize = FileSize(fn))) return -1;
	/* init decoder */
	if (!FLAC_plugin__decoder_init(decoder_, fn, filesize, &stream_data_, &flac_cfg.output))
		return 1;
	strcpy(lastfn_, fn);
	/* open output */
	maxlatency = mod_.outMod->Open(stream_data_.sample_rate, stream_data_.channels, stream_data_.output_bits_per_sample, -1, -1);
	if (maxlatency < 0)
	{
		FLAC_plugin__decoder_finish(decoder_);
		return 1;
	}
	/* set defaults */
	mod_.outMod->SetVolume(-666);
	mod_.outMod->SetPan(0);
	/* initialize vis stuff */
	mod_.SAVSAInit(maxlatency, stream_data_.sample_rate);
	mod_.VSASetInfo(stream_data_.sample_rate, stream_data_.channels);
	/* set info */
	mod_.SetInfo(stream_data_.average_bps, stream_data_.sample_rate/1000, stream_data_.channels, 1);
	/* start playing thread */
	paused = 0;
	thread_handle = CreateThread(NULL, 0, DecodeThread, NULL, 0, &thread_id);
	if (!thread_handle)	return 1;

	return 0;
}
Пример #6
0
int play(char *fn) 
{ 
	int maxlatency;
	int thread_id;
	
	if (InitADPFILE(fn, &cubefile) && InitADXFILE(fn, &cubefile) && InitDSPFILE(fn, &cubefile)) return 1;

	lstrcpy(lastfn,fn);
	paused=0;
	decode_pos_ms=0;
	seek_needed=-1;

	maxlatency = mod.outMod->Open(cubefile.ch[0].sample_rate,cubefile.NCH,BPS, -1,-1);
	if (maxlatency < 0) // error opening device
	{
		MessageBox(NULL, "error opening device", AppName, MB_OK);
		return 1;
	}
	// dividing by 1000 for the first parameter of setinfo makes it
	// display 'H'... for hundred.. i.e. 14H Kbps.
	mod.SetInfo((cubefile.ch[0].sample_rate*BPS*cubefile.NCH)/1000,cubefile.ch[0].sample_rate/1000,cubefile.NCH,1);

	// initialize vis stuff
	mod.SAVSAInit(maxlatency,cubefile.ch[0].sample_rate);
	mod.VSASetInfo(cubefile.NCH,cubefile.ch[0].sample_rate);

	mod.outMod->SetVolume(-666); // set the output plug-ins default volume

	killDecodeThread=0;
	thread_handle = (HANDLE) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) DecodeThread,(void *) &killDecodeThread,0,&thread_id);
	SetThreadPriority(thread_handle,priarray[CPUPriority]);
	
	return 0; 
}
Пример #7
0
int play(char *fn) 
{ 
	int maxlatency;
	int thread_id;

	input_file = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
		OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if (input_file == INVALID_HANDLE_VALUE) // error opening file
	{
		return 1;
	}
	file_length=GetFileSize(input_file,NULL);

    if(IsCurrentFile)
	{
		if(!strcmp(fn,lastfn))
		{
			IsCurrentFile = TRUE;
		    SongChanged=FALSE;
		}
		else
		{
			IsCurrentFile = FALSE;
			SongChanged=TRUE;
		}

	}

	strcpy(lastfn,fn);
	paused=0;
	decode_pos_ms=0;
	seek_needed=-1;

	GSFRun(fn);

	maxlatency = mod.outMod->Open(sndSamplesPerSec,sndNumChannels,sndBitsPerSample, -1,-1);
	if (maxlatency < 0) // error opening device
	{
		CloseHandle(input_file);
		input_file=INVALID_HANDLE_VALUE;
		return 1;
	}
	// dividing by 1000 for the first parameter of setinfo makes it
	// display 'H'... for hundred.. i.e. 14H Kbps.
	mod.SetInfo((sndSamplesPerSec*sndBitsPerSample*sndNumChannels)/1000,sndSamplesPerSec/1000,sndNumChannels,1);

	// initialize vis stuff
	mod.SAVSAInit(maxlatency,sndSamplesPerSec);
	mod.VSASetInfo(sndSamplesPerSec,sndNumChannels);

	mod.outMod->SetVolume(-666); // set the output plug-ins default volume

	killDecodeThread=0;
	thread_handle = (HANDLE) CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) DecodeThread,(void *) &killDecodeThread,0,&thread_id);
	
	return 0; 
}
Пример #8
0
DWORD WINAPI __stdcall DecodeThread(void *b)
{
	int done=0;
	while (! *((int *)b) ) 
	{
		if (seek_needed != -1)
		{
			//DisplayError("seek to %d",seek_needed);

			if (decode_pos_ms>seek_needed) {

					if (!InitADPFILE(NULL, &cubefile) || !InitADXFILE(NULL, &cubefile) || !InitDSPFILE(NULL, &cubefile));
	
					decode_pos_ms=-1; // -1 ms, force it to work even if we want to seek to 0
			}
	
			while (decode_pos_ms<seek_needed && ! *((int *)b)) {
				get_576_samples((short*)sample_buffer);
				mod.outMod->Flush((int)decode_pos_ms);
				decode_pos_ms+=(576.0*1000.0)/(double)cubefile.ch[0].sample_rate;
			}
			seek_needed=-1;
		}
		if (done)
		{
			mod.outMod->CanWrite();
			if (!mod.outMod->IsPlaying())
			{
				PostMessage(mod.hMainWindow,WM_WA_MPEG_EOF,0,0);
				return 0;
			}
			Sleep(10);
		}
		else if (mod.outMod->CanWrite() >= ((576*cubefile.NCH*(BPS/8))<<(mod.dsp_isactive()?1:0)))
		{	
			int l=576*cubefile.NCH*(BPS/8);
			l=get_576_samples((short*)sample_buffer);
			if (!l) 
			{
				done=1;
			}
			else
			{
				if (l==576*cubefile.NCH*(BPS/8)) {
					mod.SAAddPCMData((char *)sample_buffer,cubefile.NCH,BPS,mod.outMod->GetWrittenTime());
					mod.VSAAddPCMData((char *)sample_buffer,cubefile.NCH,BPS,mod.outMod->GetWrittenTime());
				}
				decode_pos_ms+=(576.0*1000.0)/(double)cubefile.ch[0].sample_rate;
				if (mod.dsp_isactive()) l=mod.dsp_dosamples((short *)sample_buffer,l/cubefile.NCH/(BPS/8),BPS,cubefile.NCH,cubefile.ch[0].sample_rate)*(cubefile.NCH*(BPS/8));
				mod.outMod->Write(sample_buffer,l);
			}
		}
		else Sleep(20);
	}
	return 0;
}
Пример #9
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;
}
Пример #10
0
int play(char *fn)
{
	int maxlatency;
	int thread_id;
	HANDLE input_file = INVALID_HANDLE_VALUE;
	unsigned output_bits_per_sample;

	if(0 == decoder_) {
		return 1;
	}

	input_file = CreateFile(fn, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if(input_file == INVALID_HANDLE_VALUE) {
		return -1;
	}
	CloseHandle(input_file);

	if(!safe_decoder_init_(fn, decoder_)) {
		return 1;
	}

#ifdef FLAC__DO_DITHER
	output_bits_per_sample = min(file_info_.bits_per_sample, 16);
#else
	output_bits_per_sample = file_info_.bits_per_sample;
#endif

	strcpy(lastfn_, fn);
	paused_ = 0;
	decode_pos_ms_ = 0;
	seek_needed_ = -1;
	wide_samples_in_reservoir_ = 0;

	maxlatency = mod_.outMod->Open(file_info_.sample_rate, file_info_.channels, output_bits_per_sample, -1, -1);
	if(maxlatency < 0) { /* error opening device */
		return 1;
	}

	/* dividing by 1000 for the first parameter of setinfo makes it */
	/* display 'H'... for hundred.. i.e. 14H Kbps. */
	mod_.SetInfo((file_info_.sample_rate*file_info_.bits_per_sample*file_info_.channels)/1000, file_info_.sample_rate/1000, file_info_.channels, 1);

	/* initialize vis stuff */
	mod_.SAVSAInit(maxlatency, file_info_.sample_rate);
	mod_.VSASetInfo(file_info_.sample_rate, file_info_.channels);

	mod_.outMod->SetVolume(-666); /* set the output plug-ins default volume */

	killDecodeThread = 0;
	thread_handle = (HANDLE) CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) DecodeThread, (void *) &killDecodeThread, 0, &thread_id);

	return 0;
}
Пример #11
0
static DWORD WINAPI playThread(LPVOID dummy)
{
	while (thread_run) {
		static
#if BITS_PER_SAMPLE == 8
			byte
#else
			short
#endif
			buffer[BUFFERED_BLOCKS * 2
#if SUPPORT_EQUALIZER
			* 2
#endif
			];
		int buffered_bytes = BUFFERED_BLOCKS * channels * (BITS_PER_SAMPLE / 8);
		if (seek_needed >= 0) {
			mod.outMod->Flush(seek_needed);
			ASAP_Seek(&asap, seek_needed);
			seek_needed = -1;
		}
		if (mod.outMod->CanWrite() >= buffered_bytes
#if SUPPORT_EQUALIZER
			<< mod.dsp_isactive()
#endif
		) {
			int t;
			buffered_bytes = ASAP_Generate(&asap, buffer, buffered_bytes, BITS_PER_SAMPLE);
			if (buffered_bytes <= 0) {
				mod.outMod->CanWrite();
				if (!mod.outMod->IsPlaying()) {
					PostMessage(mod.hMainWindow, WM_WA_MPEG_EOF, 0, 0);
					return 0;
				}
				Sleep(10);
				continue;
			}
			t = mod.outMod->GetWrittenTime();
			mod.SAAddPCMData(buffer, channels, BITS_PER_SAMPLE, t);
			mod.VSAAddPCMData(buffer, channels, BITS_PER_SAMPLE, t);
#if SUPPORT_EQUALIZER
			t = buffered_bytes / (channels * (BITS_PER_SAMPLE / 8));
			t = mod.dsp_dosamples((short *) buffer, t, BITS_PER_SAMPLE, channels, ASAP_SAMPLE_RATE);
			t *= channels * (BITS_PER_SAMPLE / 8);
			mod.outMod->Write((char *) buffer, t);
#else
			mod.outMod->Write((char *) buffer, buffered_bytes);
#endif
		}
		else
			Sleep(20);
	}
	return 0;
}
Пример #12
0
void stop()
{
    killPlayThread=1;

    if (play_thread_handle != INVALID_HANDLE_VALUE)
    {
        if (WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)
            TerminateThread(play_thread_handle,0);
        CloseHandle(play_thread_handle);
        play_thread_handle = INVALID_HANDLE_VALUE;
    }

    faacDecClose(hDecoder);
    close_filestream(infile);
    mod.outMod->Close();
    mod.SAVSADeInit();

    if (memmap_buffer) LocalFree(memmap_buffer);
	if(seek_table)
	{
		free(seek_table);
		seek_table = NULL;
		seek_table_length = 0;
	}
}
Пример #13
0
void stop() { 
	if (thread_handle != INVALID_HANDLE_VALUE)
	{
		if (paused)
			unpause();
		killDecodeThread=1;
		if (WaitForSingleObject(thread_handle,5000) == WAIT_TIMEOUT)
		{
			MessageBox(mod.hMainWindow,"error asking thread to die!\n","error killing decode thread",0);
			TerminateThread(thread_handle,0);
		}
		CloseHandle(thread_handle);
		thread_handle = INVALID_HANDLE_VALUE;
	}
	if (input_file != INVALID_HANDLE_VALUE)
	{
		CloseHandle(input_file);
		input_file=INVALID_HANDLE_VALUE;
	}
	GSFClose();

	mod.outMod->Close();

	mod.SAVSADeInit();
}
Пример #14
0
// stop playing.
void stop() { 
	if (thread_handle != INVALID_HANDLE_VALUE)
	{
		killDecodeThread=1;
		if (WaitForSingleObject(thread_handle,10000) == WAIT_TIMEOUT)
		{
			MessageBox(mod.hMainWindow,"error asking thread to die!\n",
				"error killing decode thread",0);
			TerminateThread(thread_handle,0);
		}
		CloseHandle(thread_handle);
		thread_handle = INVALID_HANDLE_VALUE;
	}

	// close output system
	mod.outMod->Close();

	// deinitialize visualization
	mod.SAVSADeInit();
	

	// CHANGEME! Write your own file closing code here
	if (input_file != INVALID_HANDLE_VALUE)
	{
		CloseHandle(input_file);
		input_file=INVALID_HANDLE_VALUE;
	}

}
Пример #15
0
static void stop() {
	PostThreadMessage( self->PlayThreadID, WM_QUIT, 0, 0 );
	WaitForSingleObject( self->PlayThread, INFINITE );
	CloseHandle( self->PlayThread );
	self->PlayThread = 0;
	self->PlayThreadID = 0;
	delete self->mod;
	self->mod = 0;
	inmod.outMod->Close();
	inmod.SAVSADeInit();
}
Пример #16
0
static void stop(void)
{
	if (thread_handle != NULL) {
		thread_run = FALSE;
		// wait max 10 seconds
		if (WaitForSingleObject(thread_handle, 10 * 1000) == WAIT_TIMEOUT)
			TerminateThread(thread_handle, 0);
		CloseHandle(thread_handle);
		thread_handle = NULL;
	}
	mod.outMod->Close();
	mod.SAVSADeInit();
}
Пример #17
0
static int play( const in_char * fn ) {
	if ( !fn ) {
		return -1;
	}
	try {
		std::ifstream s( fn, std::ios::binary );
		std::map< std::string, std::string > ctls;
		ctls["seek.sync_samples"] = "1";
		self->mod = new openmpt::module( s, std::clog, ctls );
		self->cached_filename = fn;
		self->cached_title = StringDecode( self->mod->get_metadata( "title" ), CP_UTF8 );
		self->cached_length = static_cast<int>( self->mod->get_duration_seconds() * 1000.0 );
		self->cached_infotext = generate_infotext( self->cached_filename, *self->mod );
		apply_options();
		self->samplerate = self->settings.samplerate;
		self->channels = self->settings.channels;
		int maxlatency = inmod.outMod->Open( self->samplerate, self->channels, BPS, -1, -1 );
		std::ostringstream str;
		str << maxlatency;
		inmod.SetInfo( self->mod->get_num_channels(), self->samplerate/1000, self->channels, 1 );
		inmod.SAVSAInit( maxlatency, self->samplerate );
		inmod.VSASetInfo( self->channels, self->samplerate );
		inmod.outMod->SetVolume( -666 );
		inmod.outMod->SetPan( 0 );
		self->paused = false;
		self->decode_position_frames = 0;
		self->PlayThread = CreateThread( NULL, 0, DecodeThread, NULL, 0, &self->PlayThreadID );
		return 0;
	} catch ( ... ) {
		if ( self->mod ) {
			delete self->mod;
			self->mod = 0;
		}
		return -1;
	}
}
Пример #18
0
void stop()
{
	if(thread_handle != INVALID_HANDLE_VALUE) {
		killDecodeThread = 1;
		if(WaitForSingleObject(thread_handle, INFINITE) == WAIT_TIMEOUT) {
			MessageBox(mod_.hMainWindow, "error asking thread to die!\n", "error killing decode thread", 0);
			TerminateThread(thread_handle, 0);
		}
		CloseHandle(thread_handle);
		thread_handle = INVALID_HANDLE_VALUE;
	}
	safe_decoder_finish_(decoder_);

	mod_.outMod->Close();

	mod_.SAVSADeInit();
}
Пример #19
0
static void stop()
{
	if (thread_handle)
	{
		stream_data_.is_playing = false;
		if (WaitForSingleObject(thread_handle, 2000) == WAIT_TIMEOUT)
		{
			FLAC_plugin__show_error("Error while stopping decoding thread.");
			TerminateThread(thread_handle, 0);
		}
		CloseHandle(thread_handle);
		thread_handle = NULL;
	}

	FLAC_plugin__decoder_finish(decoder_);
	mod_.outMod->Close();
	mod_.SAVSADeInit();
}
Пример #20
0
static DWORD WINAPI DecodeThread( LPVOID ) {
	MSG msg;
	PeekMessage( &msg, NULL, 0, 0, PM_NOREMOVE );
	bool eof = false;
	while ( true ) {
		bool quit = false;
		while ( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
			if ( msg.message == WM_QUIT ) {
				quit = true;
			} else if ( msg.message == WM_OPENMPT_SEEK ) {
				double pos_seconds = self->mod->set_position_seconds( msg.lParam * 0.001 );
				self->decode_position_frames = (std::int64_t)( pos_seconds * (double)self->samplerate);
				eof = false;
				inmod.outMod->Flush( (int)( pos_seconds * 1000.0 ) );
			}
		}
		if ( quit ) {
			break;
		}
		if ( eof ) {
			inmod.outMod->CanWrite(); // update output plugin state
			if ( !inmod.outMod->IsPlaying() ) {
				PostMessage( inmod.hMainWindow, WM_WA_MPEG_EOF, 0, 0 );
				return 0;
			}
			Sleep( 10 );
		} else {
			bool dsp_active = inmod.dsp_isactive() ? true : false;
			if ( inmod.outMod->CanWrite() >= (int)( WINAMP_BUFFER_SIZE_FRAMES * self->channels * sizeof( signed short ) ) * ( dsp_active ? WINAMP_DSP_HEADROOM_FACTOR : 1 ) ) {
				int frames = 0;
				switch ( self->channels ) {
				case 1:
					frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES );
					for ( int frame = 0; frame < frames; frame++ ) {
						self->interleaved_buffer[frame*1+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
					}
					break;
				case 2:
					frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+1*WINAMP_BUFFER_SIZE_FRAMES );
					for ( int frame = 0; frame < frames; frame++ ) {
						self->interleaved_buffer[frame*2+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
						self->interleaved_buffer[frame*2+1] = self->buffer[1*WINAMP_BUFFER_SIZE_FRAMES+frame];
					}
					break;
				case 4:
					frames = self->mod->read( self->samplerate, WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+0*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+1*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+2*WINAMP_BUFFER_SIZE_FRAMES, (&(self->buffer[0]))+3*WINAMP_BUFFER_SIZE_FRAMES );
					for ( int frame = 0; frame < frames; frame++ ) {
						self->interleaved_buffer[frame*4+0] = self->buffer[0*WINAMP_BUFFER_SIZE_FRAMES+frame];
						self->interleaved_buffer[frame*4+1] = self->buffer[1*WINAMP_BUFFER_SIZE_FRAMES+frame];
						self->interleaved_buffer[frame*4+2] = self->buffer[2*WINAMP_BUFFER_SIZE_FRAMES+frame];
						self->interleaved_buffer[frame*4+3] = self->buffer[3*WINAMP_BUFFER_SIZE_FRAMES+frame];
					}
					break;
				}
				if ( frames == 0 ) {
					eof = true;
				} else {
					self->decode_position_frames += frames;
					std::int64_t decode_pos_ms = (self->decode_position_frames * 1000 / self->samplerate );
					inmod.SAAddPCMData( &( self->interleaved_buffer[0] ), self->channels, BPS, (int)decode_pos_ms );
					inmod.VSAAddPCMData( &( self->interleaved_buffer[0] ), self->channels, BPS, (int)decode_pos_ms );
					if ( dsp_active ) {
						frames = inmod.dsp_dosamples( &( self->interleaved_buffer[0] ), frames, BPS, self->channels, self->samplerate );
					}
					int bytes = frames * self->channels * sizeof( signed short );
					inmod.outMod->Write( (char*)&( self->interleaved_buffer[0] ), bytes );
				}
			} else {
				Sleep( 10 );
			}
		}
	}
	return 0;
}
Пример #21
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;
}
Пример #22
0
int play(char *fn)
{
    int maxlatency;
    int thread_id;

    current_file_mode = m_memmap_file;

    if (current_file_mode) {
        if (play_memmap(fn))
            return -1;
    } else {
        if (play_file(fn))
            return -1;
    }

	if(seek_table)
	{
		free(seek_table);
		seek_table = NULL;
		seek_table_length = 0;
	}

	get_AAC_format(fn, &file_info, &seek_table, &seek_table_length, 0);

	if(infile->http)
	{
		/* No seeking in http streams */
		mod.is_seekable = 0;
	}
	else
	{
		if (file_info.headertype == 2) /* ADTS header - seekable */
			mod.is_seekable = 1;
		else
			mod.is_seekable = 0; /* ADIF or Headerless - not seekable */
	}

    strcpy(lastfn,fn);
    paused=0;
    decode_pos_ms=0;
    seek_needed=-1;

    /*
      To RageAmp: This is really needed, because aacinfo isn't very accurate on ADIF files yet.
                  Can be fixed though :-)
    */
    file_info.sampling_rate = samplerate;
    file_info.channels = frameInfo.channels;

    maxlatency = mod.outMod->Open(file_info.sampling_rate, file_info.channels, 16, -1,-1);

    if (maxlatency < 0) // error opening device
    {
        return -1;
    }

    // initialize vis stuff
    mod.SAVSAInit(maxlatency, file_info.sampling_rate);
    mod.VSASetInfo(file_info.sampling_rate, file_info.channels);

    mod.SetInfo(file_info.bitrate/1000, file_info.sampling_rate/1000, file_info.channels,1);

    mod.outMod->SetVolume(-666); // set the output plug-ins default volume

    killPlayThread = 0;

    if((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PlayThread, (void *) &killPlayThread, 0, &thread_id)) == NULL)
    {
        MessageBox(mod.hMainWindow, "Fatal error: Cannot create playback thread\n", "FAAD Error", MB_OK);
        return -1;
    }

    // Note: This line seriously slows down start up time
	if(m_priority != 3) // if the priority in config window is set to normal, there is nothing to reset!
	    SetThreadPriority(play_thread_handle, priority_table[m_priority]);

    return 0;
}
Пример #23
0
DWORD WINAPI DecodeThread(LPVOID b)
{
	int done=0; // set to TRUE if decoding has finished
	while (!killDecodeThread) 
	{
		if (seek_needed != -1) // seek is needed.
		{
			int offs;
			decode_pos_ms = seek_needed;
			seek_needed=-1;
			done=0;
			mod.outMod->Flush(decode_pos_ms); // flush output device and set 
											  // output position to the seek position
			offs = MulDiv(decode_pos_ms,SAMPLERATE,1000); // decode_pos_ms*SAMPLERATE/1000
			SetFilePointer(input_file,offs*NCH*(BPS/8),NULL,FILE_BEGIN); // seek!
		}

		if (done) // done was set to TRUE during decoding, signaling eof
		{
			mod.outMod->CanWrite();		// some output drivers need CanWrite
									    // to be called on a regular basis.

			if (!mod.outMod->IsPlaying()) 
			{
				// we're done playing, so tell Winamp and quit the thread.
				PostMessage(mod.hMainWindow,WM_WA_MPEG_EOF,0,0);
				return 0;	// quit thread
			}
			Sleep(10);		// give a little CPU time back to the system.
		}
		else if (mod.outMod->CanWrite() >= ((576*NCH*(BPS/8))*(mod.dsp_isactive()?2:1)))
			// CanWrite() returns the number of bytes you can write, so we check that
			// to the block size. the reason we multiply the block size by two if 
			// mod.dsp_isactive() is that DSP plug-ins can change it by up to a 
			// factor of two (for tempo adjustment).
		{	
			int l=576*NCH*(BPS/8);			       // block length in bytes
			static char sample_buffer[576*NCH*(BPS/8)*2]; 
												   // sample buffer. twice as 
												   // big as the blocksize

			l=get_576_samples(sample_buffer);	   // retrieve samples
			if (!l)			// no samples means we're at eof
			{
				done=1;
			}
			else	// we got samples!
			{
				// give the samples to the vis subsystems
				mod.SAAddPCMData((char *)sample_buffer,NCH,BPS,decode_pos_ms);	
				mod.VSAAddPCMData((char *)sample_buffer,NCH,BPS,decode_pos_ms);
				// adjust decode position variable
				decode_pos_ms+=(576*1000)/SAMPLERATE;	

				// if we have a DSP plug-in, then call it on our samples
				if (mod.dsp_isactive()) 
					l=mod.dsp_dosamples(
						(short *)sample_buffer,l/NCH/(BPS/8),BPS,NCH,SAMPLERATE
					  ) // dsp_dosamples
					  *(NCH*(BPS/8));

				// write the pcm data to the output system
				mod.outMod->Write(sample_buffer,l);
			}
		}
		else Sleep(20); 
		// if we can't write data, wait a little bit. Otherwise, continue 
		// through the loop writing more data (without sleeping)
	}
	return 0;
}
Пример #24
0
DWORD WINAPI PlayThread(void *b)
{
    int done=0;
    int l;
	int decoded_frames=0;
	int br_calc_frames=0;
	int br_bytes_consumed=0;
    unsigned long bytesconsumed;

	PlayThreadAlive = 1;
    last_frame = 0;

    while (! *((int *)b) )
    {
        if (seek_needed != -1)
        {
            int seconds;

            // Round off to a second
            seconds = seek_needed - (seek_needed%1000);
            mod.outMod->Flush(decode_pos_ms);
            aac_seek(seconds, seek_table);
            decode_pos_ms = seconds;
			seek_needed = -1;
			decoded_frames = 0;
			br_calc_frames = 0;
			br_bytes_consumed = 0;
        }

        if (done)
        {
            mod.outMod->CanWrite();

            if (!mod.outMod->IsPlaying())
            {
                PostMessage(mod.hMainWindow,WM_WA_AAC_EOF,0,0);
                PlayThreadAlive = 0;
                return 0;
            }

            Sleep(10);
        }
        //assume that max channels is 2.
        else if (mod.outMod->CanWrite() >= ((1024*file_info.channels*sizeof(short))<<(mod.dsp_isactive()?1:0)))
        {
            if(last_frame)
            {
                done=1;
            }
            else
            {
                if (current_file_mode)
                    bytesconsumed = PlayThread_memmap();
                else
                    bytesconsumed = PlayThread_file();

				decoded_frames++;
				br_calc_frames++;
				br_bytes_consumed += bytesconsumed;

				/* Update the variable bitrate about every second */
				if(m_variable_bitrate_display && br_calc_frames == 43)
				{
					int br;

					br = (int)((br_bytes_consumed * 8) / (decoded_frames / 43.07));

					mod.SetInfo(br/1000, file_info.sampling_rate/1000, file_info.channels, 1);
					br_calc_frames = 0;
				}

                if (!killPlayThread && (frameInfo.samples > 0))
                {
                    mod.SAAddPCMData(sample_buffer,file_info.channels, 16, decode_pos_ms);
                    mod.VSAAddPCMData(sample_buffer,file_info.channels, 16, decode_pos_ms);
                    decode_pos_ms+=(1024*1000)/file_info.sampling_rate;

                    if (mod.dsp_isactive())
                        l=mod.dsp_dosamples((short *)sample_buffer,frameInfo.samples*sizeof(short)/file_info.channels/(16/8),16,file_info.channels,file_info.sampling_rate)*(file_info.channels*(16/8));
                    else
                        l = frameInfo.samples*sizeof(short);

                    mod.outMod->Write(sample_buffer, l);
                }
            }
        }
        else
        {
            Sleep(10);
        }
    }

	if(seek_table)
	{
		free(seek_table);
		seek_table = NULL;
		seek_table_length = 0;
	}
    
	PlayThreadAlive = 0;
	
    return 0;
}
Пример #25
0
// called when winamp wants to play a file
int play(const char *fn) 
{ 
	int maxlatency;
	int thread_id;

	paused=0;
	decode_pos_ms=0;
	seek_needed=-1;

	
	
	// CHANGEME! Write your own file opening code here
	input_file = CreateFile(fn,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,
		OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if (input_file == INVALID_HANDLE_VALUE) // error opening file
	{
		// we return error. 1 means to keep going in the playlist, -1
		// means to stop the playlist.
		return 1;
	}

	file_length=GetFileSize(input_file,NULL);


	
	strcpy(lastfn,fn);

	// -1 and -1 are to specify buffer and prebuffer lengths.
	// -1 means to use the default, which all input plug-ins should
	// really do.
	maxlatency = mod.outMod->Open(SAMPLERATE,NCH,BPS, -1,-1); 

	// maxlatency is the maxium latency between a outMod->Write() call and
	// when you hear those samples. In ms. Used primarily by the visualization
	// system.

	if (maxlatency < 0) // error opening device
	{
		CloseHandle(input_file);
		input_file=INVALID_HANDLE_VALUE;
		return 1;
	}
	// dividing by 1000 for the first parameter of setinfo makes it
	// display 'H'... for hundred.. i.e. 14H Kbps.
	mod.SetInfo((SAMPLERATE*BPS*NCH)/1000,SAMPLERATE/1000,NCH,1);

	// initialize visualization stuff
	mod.SAVSAInit(maxlatency,SAMPLERATE);
	mod.VSASetInfo(SAMPLERATE,NCH);

	// set the output plug-ins default volume.
	// volume is 0-255, -666 is a token for
	// current volume.
	mod.outMod->SetVolume(-666); 

	// launch decode thread
	killDecodeThread=0;
	thread_handle = (HANDLE) 
		CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) DecodeThread,NULL,0,&thread_id);
	
	return 0; 
}