Index: /winamp-musepack/trunk/in2.h
===================================================================
--- /winamp-musepack/trunk/in2.h	(revision 248)
+++ /winamp-musepack/trunk/in2.h	(revision 248)
@@ -0,0 +1,103 @@
+#include "out.h"
+
+// note: exported symbol is now winampGetInModule2.
+
+#define IN_VER 0x100
+
+typedef struct 
+{
+	int version;				// module type (IN_VER)
+	char *description;			// description of module, with version string
+
+	HWND hMainWindow;			// winamp's main window (filled in by winamp)
+	HINSTANCE hDllInstance;		// DLL instance handle (Also filled in by winamp)
+
+	char *FileExtensions;		// "mp3\0Layer 3 MPEG\0mp2\0Layer 2 MPEG\0mpg\0Layer 1 MPEG\0"
+								// May be altered from Config, so the user can select what they want
+	
+	int is_seekable;			// is this stream seekable? 
+	int UsesOutputPlug;			// does this plug-in use the output plug-ins? (musn't ever change, ever :)
+
+	void (*Config)(HWND hwndParent); // configuration dialog
+	void (*About)(HWND hwndParent);  // about dialog
+
+	void (*Init)();				// called at program init
+	void (*Quit)();				// called at program quit
+
+	void (*GetFileInfo)(char *file, char *title, int *length_in_ms); // if file == NULL, current playing is used
+	int (*InfoBox)(char *file, HWND hwndParent);
+	
+	int (*IsOurFile)(char *fn);	// called before extension checks, to allow detection of mms://, etc
+	// playback stuff
+	int (*Play)(char *fn);		// return zero on success, -1 on file-not-found, some other value on other (stopping winamp) error
+	void (*Pause)();			// pause stream
+	void (*UnPause)();			// unpause stream
+	int (*IsPaused)();			// ispaused? return 1 if paused, 0 if not
+	void (*Stop)();				// stop (unload) stream
+
+	// time stuff
+	int (*GetLength)();			// get length in ms
+	int (*GetOutputTime)();		// returns current output time in ms. (usually returns outMod->GetOutputTime()
+	void (*SetOutputTime)(int time_in_ms);	// seeks to point in stream (in ms). Usually you signal yoru thread to seek, which seeks and calls outMod->Flush()..
+
+	// volume stuff
+	void (*SetVolume)(int volume);	// from 0 to 255.. usually just call outMod->SetVolume
+	void (*SetPan)(int pan);	// from -127 to 127.. usually just call outMod->SetPan
+	
+	// in-window builtin vis stuff
+
+	void (*SAVSAInit)(int maxlatency_in_ms, int srate);		// call once in Play(). maxlatency_in_ms should be the value returned from outMod->Open()
+	// call after opening audio device with max latency in ms and samplerate
+	void (*SAVSADeInit)();	// call in Stop()
+
+
+	// simple vis supplying mode
+	void (*SAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); 
+											// sets the spec data directly from PCM data
+											// quick and easy way to get vis working :)
+											// needs at least 576 samples :)
+
+	// advanced vis supplying mode, only use if you're cool. Use SAAddPCMData for most stuff.
+	int (*SAGetMode)();		// gets csa (the current type (4=ws,2=osc,1=spec))
+							// use when calling SAAdd()
+	void (*SAAdd)(void *data, int timestamp, int csa); // sets the spec data, filled in by winamp
+
+
+	// vis stuff (plug-in)
+	// simple vis supplying mode
+	void (*VSAAddPCMData)(void *PCMData, int nch, int bps, int timestamp); // sets the vis data directly from PCM data
+											// quick and easy way to get vis working :)
+											// needs at least 576 samples :)
+
+	// advanced vis supplying mode, only use if you're cool. Use VSAAddPCMData for most stuff.
+	int (*VSAGetMode)(int *specNch, int *waveNch); // use to figure out what to give to VSAAdd
+	void (*VSAAdd)(void *data, int timestamp); // filled in by winamp, called by plug-in
+
+
+	// call this in Play() to tell the vis plug-ins the current output params. 
+	void (*VSASetInfo)(int nch, int srate);
+
+
+	// dsp plug-in processing: 
+	// (filled in by winamp, called by input plug)
+
+	// returns 1 if active (which means that the number of samples returned by dsp_dosamples
+	// could be greater than went in.. Use it to estimate if you'll have enough room in the
+	// output buffer
+	int (*dsp_isactive)(); 
+
+	// returns number of samples to output. This can be as much as twice numsamples. 
+	// be sure to allocate enough buffer for samples, then.
+	int (*dsp_dosamples)(short int *samples, int numsamples, int bps, int nch, int srate);
+
+
+	// eq stuff
+	void (*EQSet)(int on, char data[10], int preamp); // 0-64 each, 31 is +0, 0 is +12, 63 is -12. Do nothing to ignore.
+
+	// info setting (filled in by winamp)
+	void (*SetInfo)(int bitrate, int srate, int stereo, int synched); // if -1, changes ignored? :)
+
+	Out_Module *outMod; // filled in by winamp, optionally used :)
+} In_Module;
+
+
Index: /winamp-musepack/trunk/in_mpc.cpp
===================================================================
--- /winamp-musepack/trunk/in_mpc.cpp	(revision 248)
+++ /winamp-musepack/trunk/in_mpc.cpp	(revision 248)
@@ -0,0 +1,227 @@
+/*
+	Copyright (C) 2006 Nicolas BOTTI <rududu at laposte.net>
+	This file is part of the Musepack Winamp plugin.
+
+	This library is free software; you can redistribute it and/or
+	modify it under the terms of the GNU Lesser General Public
+	License as published by the Free Software Foundation; either
+	version 2.1 of the License, or (at your option) any later version.
+
+	This library is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+	Lesser General Public License for more details.
+
+	You should have received a copy of the GNU Lesser General Public
+	License along with this library; if not, write to the Free Software
+	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <windows.h>
+
+#include "in2.h"
+#include "mpc_player.h"
+
+void config(HWND hwndParent);
+void about(HWND hwndParent);
+int infoDlg(char *fn, HWND hwnd);
+
+void init(void);
+void quit(void);
+int play(char *fn);
+void stop(void);
+
+void pause(void);
+void unpause(void);
+int ispaused(void);
+
+int isourfile(char *fn);
+int getlength(void);
+int getoutputtime(void);
+void getfileinfo(char *filename, char *title, int *length_in_ms);
+void setoutputtime(int time_in_ms);
+
+void setvolume(int volume);
+void setpan(int pan);
+
+void eq_set(int on, char data[10], int preamp);
+
+mpc_player * player;
+
+// module definition.
+In_Module mod = 
+{
+	IN_VER, // defined in IN2.H
+	"Musepack winamp plugin",
+	0, // hMainWindow (filled in by winamp)
+	0, // hDllInstance (filled in by winamp)
+	"mpc\0Musepack Audio File (*.mpc)\0mp+\0Musepack Audio File (*.mp+)\0"
+	,
+	1, // is_seekable
+	1, // uses output plug-in system
+	config,
+	about,
+	init,
+	quit,
+	getfileinfo,
+	infoDlg,
+	isourfile,
+	play,
+	pause,
+	unpause,
+	ispaused,
+	stop,
+	
+	getlength,
+	getoutputtime,
+	setoutputtime,
+
+	setvolume,
+	setpan,
+
+	0,0,0,0,0,0,0,0,0, // visualization calls filled in by winamp
+
+	0,0, // dsp calls filled in by winamp
+
+	eq_set,
+
+	0, // setinfo call filled in by winamp
+
+	0 // out_mod filled in by winamp
+};
+
+void config(HWND hwndParent)
+{
+	MessageBoxA(hwndParent, "No configuration yet", "Configuration", MB_OK);
+}
+void about(HWND hwndParent)
+{
+	MessageBoxA(hwndParent,"Musepack plugin for winamp\nAll bugs © Nicolas BOTTI", "Uh ?", MB_OK);
+}
+
+void init(void)
+{ 
+	player = new mpc_player(&mod);
+}
+
+void quit(void)
+{ 
+	delete player;
+}
+
+int isourfile(char *fn)
+{ 
+// used for detecting URL streams.. unused here. 
+// return !strncmp(fn,"http://",7); to detect HTTP streams, etc
+	return 0; 
+}
+
+// called when winamp wants to play a file
+int play(char *fn)
+{ 	
+	return player->play(fn);
+}
+
+void stop(void)
+{ 
+	player->stop();
+}
+
+void pause(void)
+{ 
+	player->paused = 1;
+	mod.outMod->Pause(1);
+}
+
+void unpause(void)
+{
+	player->paused = 0;
+	mod.outMod->Pause(0);
+}
+
+int ispaused(void)
+{ 
+	return player->paused;
+}
+
+void setvolume(int volume)
+{
+	mod.outMod->SetVolume(volume);
+}
+
+void setpan(int pan)
+{
+	mod.outMod->SetPan(pan);
+}
+
+int getlength(void)
+{ 
+	return player->getLength();
+}
+
+
+// returns current output position, in ms.
+// you could just use return mod.outMod->GetOutputTime(),
+// but the dsp plug-ins that do tempo changing tend to make
+// that wrong.
+int getoutputtime(void)
+{ 
+	return player->getOutputTime();
+}
+
+
+// called when the user releases the seek scroll bar.
+// usually we use it to set seek_needed to the seek
+// point (seek_needed is -1 when no seek is needed)
+// and the decode thread checks seek_needed.
+void setoutputtime(int time_in_ms)
+{
+	player->setOutputTime(time_in_ms);
+}
+
+// this gets called when the use hits Alt+3 to get the file info.
+// if you need more info, ask me :)
+
+int infoDlg(char *fn, HWND hwnd)
+{
+	mpc_player info_play(fn, &mod);
+	return info_play.infoDlg(hwnd);
+}
+
+
+// this is an odd function. it is used to get the title and/or
+// length of a track.
+// if filename is either NULL or of length 0, it means you should
+// return the info of lastfn. Otherwise, return the information
+// for the file in filename.
+// if title is NULL, no title is copied into it.
+// if length_in_ms is NULL, no length is copied into it.
+void getfileinfo(char *filename, char *title, int *length_in_ms)
+{
+	if (!filename || !*filename)
+		player->getFileInfo(title, length_in_ms);
+	else {
+		mpc_player info_play(filename, &mod);
+		info_play.getFileInfo(title, length_in_ms);
+	}
+}
+
+void eq_set(int on, char data[10], int preamp) 
+{ 
+	// most plug-ins can't even do an EQ anyhow.. I'm working on writing
+	// a generic PCM EQ, but it looks like it'll be a little too CPU 
+	// consuming to be useful :)
+	// if you _CAN_ do EQ with your format, each data byte is 0-63 (+20db <-> -20db)
+	// and preamp is the same. 
+}
+
+// exported symbol. Returns output module.
+
+extern "C" {
+
+__declspec( dllexport ) In_Module * winampGetInModule2()
+{
+	return &mod;
+}
+
+}
Index: /winamp-musepack/trunk/mpc_player.cpp
===================================================================
--- /winamp-musepack/trunk/mpc_player.cpp	(revision 248)
+++ /winamp-musepack/trunk/mpc_player.cpp	(revision 248)
@@ -0,0 +1,356 @@
+/*
+	Copyright (C) 2006 Nicolas BOTTI <rududu at laposte.net>
+	This file is part of the Musepack Winamp plugin.
+
+	This library is free software; you can redistribute it and/or
+	modify it under the terms of the GNU Lesser General Public
+	License as published by the Free Software Foundation; either
+	version 2.1 of the License, or (at your option) any later version.
+
+	This library is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+	Lesser General Public License for more details.
+
+	You should have received a copy of the GNU Lesser General Public
+	License along with this library; if not, write to the Free Software
+	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#include <windows.h>
+#include <math.h>
+
+#include "in2.h"
+#include "mpc_player.h"
+#include <mpc/minimax.h>
+#include "mpc_info.h"
+
+#include <tag.h>
+#include <vcclr.h>
+
+
+mpc_player::mpc_player(In_Module * in_mod)
+{
+	init(in_mod);
+}
+
+mpc_player::mpc_player(char * fn, In_Module * in_mod)
+{
+	init(in_mod);
+	openFile(fn);
+}
+
+mpc_player::~mpc_player(void)
+{
+	closeFile();
+}
+
+void mpc_player::init(In_Module * in_mod)
+{
+	thread_handle=INVALID_HANDLE_VALUE;
+	killDecodeThread=0;
+
+	demux = 0;
+	mod = in_mod;
+	wait_event = 0;
+	tag_file = 0;
+}
+
+int mpc_player::openFile(char * fn)
+{
+	closeFile();
+
+    mpc_status err = mpc_reader_init_stdio(&reader, fn);
+    if(err < 0) return 1;
+
+    demux = mpc_demux_init(&reader);
+	if(!demux) {
+		mpc_reader_exit_stdio(&reader);
+		return 1;
+	}
+
+    mpc_demux_get_info(demux,  &si);
+	strcpy(lastfn, fn);
+	return 0;
+}
+
+void mpc_player::closeFile(void)
+{
+	if (demux != 0) {
+		mpc_demux_exit(demux);
+		demux = 0;
+		mpc_reader_exit_stdio(&reader);
+	}
+	if (tag_file != 0) {
+		delete tag_file;
+		tag_file = 0;
+	}
+}
+
+void mpc_player::setOutputTime(int time_in_ms)
+{
+	seek_offset = time_in_ms;
+	if (wait_event) SetEvent(wait_event);
+}
+
+void mpc_player::scaleSamples(short * buffer, int len)
+{
+	for (int i = 0; i < len; i++){
+		int tmp = (int) (sample_buffer[i] * (1 << 15));
+		tmp = clip(tmp, -(1 << 15), ((1 << 15) - 1));
+		buffer[i] = (short) tmp;
+	}
+}
+
+// FIXME : use 576 samples if advice still valid
+
+// note that if you adjust the size of sample_buffer, for say, 1024
+// sample blocks, it will still work, but some of the visualization 
+// might not look as good as it could. Stick with 576 sample blocks
+// if you can, and have an additional auxiliary (overflow) buffer if 
+// necessary.. 
+
+
+DWORD WINAPI mpc_player::runThread(void * pThis)
+{
+	return ((mpc_player*)(pThis))->decodeFile();
+}
+
+int mpc_player::decodeFile(void)
+{
+	int done = 0;
+
+	wait_event = CreateEvent(0, FALSE, FALSE, 0);
+
+	while (!killDecodeThread) 
+	{
+		if (seek_offset != -1) {
+			mpc_demux_seek_second(demux, seek_offset / 1000.);
+			mod->outMod->Flush(seek_offset);
+			decode_pos_sample = (__int64)seek_offset * (__int64)si.sample_freq / 1000;
+			seek_offset = -1;
+			done = 0;
+		}
+
+		if (done) {
+			mod->outMod->CanWrite();	// some output drivers need CanWrite
+									    // to be called on a regular basis.
+
+			if (!mod->outMod->IsPlaying())  {
+				PostMessage(mod->hMainWindow,WM_WA_EOF, 0, 0);
+				break;
+			}
+			WaitForSingleObject(wait_event, 100);		// give a little CPU time back to the system.
+		} else if (mod->outMod->CanWrite() >= (MPC_FRAME_LENGTH * sizeof(short) * si.channels)*(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).
+
+			mpc_frame_info frame;
+
+			frame.buffer = sample_buffer;
+			mpc_demux_decode(demux, &frame);
+
+			if(frame.bits == -1) {
+				done = 1;
+			} else {
+				short output_buffer[MPC_FRAME_LENGTH * 2]; // default 2 channels
+				int decode_pos_ms = getOutputTime();
+				decode_pos_sample += frame.samples;
+
+				scaleSamples(output_buffer, frame.samples * si.channels);
+				
+				// give the samples to the vis subsystems
+				mod->SAAddPCMData((char *)output_buffer, si.channels, sizeof(short) * 8, decode_pos_ms);	
+				mod->VSAAddPCMData((char *)output_buffer, si.channels, sizeof(short) * 8, decode_pos_ms);
+
+				// if we have a DSP plug-in, then call it on our samples
+				if (mod->dsp_isactive()) 
+					frame.samples = mod->dsp_dosamples(output_buffer, frame.samples , sizeof(short) * 8, si.channels, si.sample_freq);
+
+				// write the pcm data to the output system
+				mod->outMod->Write((char*)output_buffer, frame.samples * sizeof(short) * si.channels);
+			}
+		} else WaitForSingleObject(wait_event, 1000);
+	}
+
+	CloseHandle(wait_event);
+	wait_event = 0;
+
+	return 0;
+}
+
+void mpc_player::getFileInfo(char *title, int *length_in_ms)
+{
+	if (length_in_ms) *length_in_ms = getLength();
+	if (title) {
+		if(tag_file == 0)
+			tag_file = new TagLib::FileRef(lastfn, false);
+
+		if (tag_file->isNull() || !tag_file->tag()) {
+			char *p = lastfn + strlen(lastfn);
+			while (*p != '\\' && p >= lastfn) p--;
+			strcpy(title,++p);
+		} else {
+			TagLib::Tag *tag = tag_file->tag();
+			sprintf(title, "%s - %s", tag->artist().toCString(), tag->title().toCString());
+			//tag->artist()
+			//tag->album()
+			//tag->year()
+			//tag->comment()
+			//tag->track()
+			//tag->genre()
+		}
+	}
+}
+
+// stop playing.
+void mpc_player::stop(void)
+{ 
+	if (thread_handle != INVALID_HANDLE_VALUE) {
+		killDecodeThread = 1;
+		if (wait_event) SetEvent(wait_event);
+		if (WaitForSingleObject(thread_handle,10000) == WAIT_TIMEOUT) {
+			MessageBoxA(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();
+	
+	closeFile();
+}
+
+int mpc_player::play(char *fn) 
+{ 
+	int maxlatency;
+
+	paused=0;
+	decode_pos_sample = 0;
+	seek_offset=-1;
+
+	if (openFile(fn) != 0) return 1;
+
+	// -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(si.sample_freq, si.channels, sizeof(short) * 8, -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
+		return 1;
+
+	// dividing by 1000 for the first parameter of setinfo makes it
+	// display 'H'... for hundred.. i.e. 14H Kbps.
+	mod->SetInfo(si.average_bitrate / 1000, si.sample_freq / 1000, si.channels, 1);
+
+	// initialize visualization stuff
+	mod->SAVSAInit(maxlatency, si.sample_freq);
+	mod->VSASetInfo(si.sample_freq, si.channels);
+
+	// 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 = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) runThread, this, 0, 0);
+	
+	return 0; 
+}
+
+void mpc_player::loadTags(mpc_info ^ infoBox)
+{
+	if(tag_file == 0)
+		tag_file = new TagLib::FileRef(lastfn, false);
+
+	if (!tag_file->isNull() && tag_file->tag()) {
+		TagLib::Tag *tag = tag_file->tag();
+		infoBox->txtTitle->Text = gcnew String(tag->title().toCString(true), 0, strlen(tag->title().toCString(true)), System::Text::Encoding::UTF8);
+		infoBox->txtArtist->Text = gcnew String(tag->artist().toCString(true), 0, strlen(tag->artist().toCString(true)), System::Text::Encoding::UTF8);
+		infoBox->txtAlbum->Text = gcnew String(tag->album().toCString(true), 0, strlen(tag->album().toCString(true)), System::Text::Encoding::UTF8);
+		infoBox->txtYear->Text = "";
+		infoBox->txtYear->Text += tag->year();
+		infoBox->txtTrack->Text = "";
+		infoBox->txtTrack->Text += tag->track();
+		infoBox->comboGenre->Text = gcnew String(tag->genre().toCString(true), 0, strlen(tag->genre().toCString(true)), System::Text::Encoding::UTF8);
+		infoBox->txtComment->Text = gcnew String(tag->comment().toCString(true), 0, strlen(tag->comment().toCString(true)), System::Text::Encoding::UTF8);
+	}
+}
+
+void mpc_player::writeTags(mpc_info ^ infoBox)
+{
+	if (!tag_file->isNull() && tag_file->tag()) {
+		TagLib::Tag *tag = tag_file->tag();
+
+		pin_ptr<const wchar_t> wch = PtrToStringChars(infoBox->txtTitle->Text);
+		tag->setTitle(wch);
+
+		wch = PtrToStringChars(infoBox->txtArtist->Text);
+		tag->setArtist(wch);
+
+		wch = PtrToStringChars(infoBox->txtAlbum->Text);
+		tag->setAlbum(wch);
+
+		wch = PtrToStringChars(infoBox->txtYear->Text);
+		TagLib::String year(wch);
+		tag->setYear(year.toInt());
+
+		wch = PtrToStringChars(infoBox->txtTrack->Text);
+		TagLib::String track(wch);
+		tag->setTrack(track.toInt());
+
+		wch = PtrToStringChars(infoBox->comboGenre->Text);
+		tag->setGenre(wch);
+
+		wch = PtrToStringChars(infoBox->txtComment->Text);
+		tag->setComment(wch);
+
+		tag_file->save(); // FIXME : make all crash
+	}
+}
+
+int mpc_player::infoDlg(HWND hwnd)
+{
+	mpc_info infoBox(this);
+	System::String ^ tmp;
+
+	tmp = "Streamversion ";
+	tmp += si.stream_version;
+	tmp += "\nEncoder : ";
+	tmp += gcnew String(si.encoder);
+	tmp += "\nProfile : ";
+	tmp += gcnew String(si.profile_name);
+	tmp += "\nPNS : ";
+	tmp += si.pns ? "on" : "off";
+	tmp += "\nGapless : ";
+	tmp += si.is_true_gapless ? "on" : "off";
+	tmp += "\nAverage bitrate : ";
+	tmp += floor(si.average_bitrate * 1.e-3 + .5);
+	tmp += " Kbps \nSamplerate : ";
+	tmp += si.sample_freq;
+	tmp += "\nChannels : ";
+	tmp += si.channels;
+	tmp += "\nFile size : ";
+	tmp += si.total_file_length;
+	tmp += " Bytes";
+	// FIXME : add replay gain info
+
+	infoBox.lblStreamInfo->Text = tmp;
+
+	loadTags(% infoBox);
+
+	infoBox.ShowDialog();
+	return 0;
+}
Index: /winamp-musepack/trunk/mpc_player.h
===================================================================
--- /winamp-musepack/trunk/mpc_player.h	(revision 248)
+++ /winamp-musepack/trunk/mpc_player.h	(revision 248)
@@ -0,0 +1,81 @@
+/*
+	Copyright (C) 2006 Nicolas BOTTI <rududu at laposte.net>
+	This file is part of the Musepack Winamp plugin.
+
+	This library is free software; you can redistribute it and/or
+	modify it under the terms of the GNU Lesser General Public
+	License as published by the Free Software Foundation; either
+	version 2.1 of the License, or (at your option) any later version.
+
+	This library is distributed in the hope that it will be useful,
+	but WITHOUT ANY WARRANTY; without even the implied warranty of
+	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+	Lesser General Public License for more details.
+
+	You should have received a copy of the GNU Lesser General Public
+	License along with this library; if not, write to the Free Software
+	Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*/
+
+#pragma once
+
+#include <mpcdec/mpcdec.h>
+#include <fileref.h>
+#include "mpc_info.h"
+
+using namespace winamp_musepack;
+
+// post this to the main window at end of file (after playback as stopped)
+#define WM_WA_EOF WM_USER+2
+
+
+class mpc_player
+{
+public:
+	mpc_player(In_Module * in_mod);
+	mpc_player(char * fn, In_Module * in_mod);
+	~mpc_player(void);
+
+	int play(char *fn);
+	void stop(void);
+
+	void getFileInfo(char *title, int *length_in_ms);
+	int getLength(void) {return si.samples * 1000 / si.sample_freq;}
+	int getOutputTime(void) {return decode_pos_sample * 1000 / si.sample_freq;}
+
+	void setOutputTime(int time_in_ms);
+
+	int infoDlg(HWND hwnd);
+	void loadTags(mpc_info ^ infoBox);
+	void writeTags(mpc_info ^ infoBox);
+
+	int paused;				// are we paused?
+
+private:
+	char lastfn[MAX_PATH];	// currently playing file (used for getting info on the current file)
+	mpc_streaminfo si;
+	mpc_reader reader;
+	mpc_demux* demux;
+	TagLib::FileRef * tag_file;
+
+    MPC_SAMPLE_FORMAT sample_buffer[MPC_DECODER_BUFFER_LENGTH];
+
+	__int64 decode_pos_sample; // decoding position in samples;
+	volatile int seek_offset; // if != -1, it is the point that the decode 
+							  // thread should seek to, in ms.
+	volatile int killDecodeThread;	// the kill switch for the decode thread
+
+	HANDLE thread_handle;	// the handle to the decode thread
+	HANDLE wait_event;
+
+	In_Module * mod;
+
+	static DWORD WINAPI runThread(void * pThis);
+	int decodeFile(void);
+	int openFile(char * fn);
+	void closeFile(void);
+
+	void init(In_Module * in_mod);
+
+	void scaleSamples(short * buffer, int len);
+};
Index: /winamp-musepack/trunk/out.h
===================================================================
--- /winamp-musepack/trunk/out.h	(revision 248)
+++ /winamp-musepack/trunk/out.h	(revision 248)
@@ -0,0 +1,52 @@
+#define OUT_VER 0x10
+
+typedef struct 
+{
+	int version;				// module version (OUT_VER)
+	char *description;			// description of module, with version string
+	int id;						// module id. each input module gets its own. non-nullsoft modules should
+								// be >= 65536. 
+
+	HWND hMainWindow;			// winamp's main window (filled in by winamp)
+	HINSTANCE hDllInstance;		// DLL instance handle (filled in by winamp)
+
+	void (*Config)(HWND hwndParent); // configuration dialog 
+	void (*About)(HWND hwndParent);  // about dialog
+
+	void (*Init)();				// called when loaded
+	void (*Quit)();				// called when unloaded
+
+	int (*Open)(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms); 
+					// returns >=0 on success, <0 on failure
+					// NOTENOTENOTE: bufferlenms and prebufferms are ignored in most if not all output plug-ins. 
+					//    ... so don't expect the max latency returned to be what you asked for.
+					// returns max latency in ms (0 for diskwriters, etc)
+					// bufferlenms and prebufferms must be in ms. 0 to use defaults. 
+					// prebufferms must be <= bufferlenms
+
+	void (*Close)();	// close the ol' output device.
+
+	int (*Write)(char *buf, int len);	
+					// 0 on success. Len == bytes to write (<= 8192 always). buf is straight audio data. 
+					// 1 returns not able to write (yet). Non-blocking, always.
+
+	int (*CanWrite)();	// returns number of bytes possible to write at a given time. 
+						// Never will decrease unless you call Write (or Close, heh)
+
+	int (*IsPlaying)(); // non0 if output is still going or if data in buffers waiting to be
+						// written (i.e. closing while IsPlaying() returns 1 would truncate the song
+
+	int (*Pause)(int pause); // returns previous pause state
+
+	void (*SetVolume)(int volume); // volume is 0-255
+	void (*SetPan)(int pan); // pan is -128 to 128
+
+	void (*Flush)(int t);	// flushes buffers and restarts output at time t (in ms) 
+							// (used for seeking)
+
+	int (*GetOutputTime)(); // returns played time in MS
+	int (*GetWrittenTime)(); // returns time written in MS (used for synching up vis stuff)
+
+} Out_Module;
+
+
Index: /winamp-musepack/trunk/winamp-musepack.vcproj
===================================================================
--- /winamp-musepack/trunk/winamp-musepack.vcproj	(revision 248)
+++ /winamp-musepack/trunk/winamp-musepack.vcproj	(revision 248)
@@ -0,0 +1,282 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="8.00"
+	Name="winamp-musepack"
+	ProjectGUID="{EEA7D671-FB86-4E8D-8F1A-CC05174342F0}"
+	RootNamespace="winamp-musepack"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\libmpc\include;C:\Program Files\taglib\include\taglib"
+				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE"
+				RuntimeLibrary="2"
+				WarningLevel="3"
+				DebugInformationFormat="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="User32.lib libmpcdec_d.lib libcommon_d.lib tag.lib"
+				OutputFile="E:\Program Files\Winamp\Plugins\in_mpc.dll"
+				AdditionalLibraryDirectories="..\..\libmpc\win32\Debug;C:\Program Files\taglib\lib"
+				GenerateManifest="false"
+				IgnoreAllDefaultLibraries="false"
+				IgnoreDefaultLibraryNames="LIBCMTD;MSVCRT;MSVCMRT"
+				GenerateDebugInformation="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
+			IntermediateDirectory="$(ConfigurationName)"
+			ConfigurationType="2"
+			ManagedExtensions="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\libmpc\include;C:\Program Files\taglib\include\taglib"
+				PreprocessorDefinitions="_CRT_SECURE_NO_DEPRECATE;WIN32"
+				RuntimeLibrary="2"
+				WarningLevel="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="User32.lib libmpcdec.lib libcommon.lib tag.lib"
+				OutputFile="E:\Program Files\Winamp\Plugins\in_mpc.dll"
+				AdditionalLibraryDirectories="..\..\libmpc\win32\Release;C:\Program Files\taglib\lib"
+				GenerateManifest="true"
+				IgnoreDefaultLibraryNames="LIBCMT"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+		<AssemblyReference
+			RelativePath="System.dll"
+			AssemblyName="System, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+		/>
+		<AssemblyReference
+			RelativePath="System.Data.dll"
+			AssemblyName="System.Data, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=x86"
+		/>
+		<AssemblyReference
+			RelativePath="System.Drawing.dll"
+			AssemblyName="System.Drawing, Version=2.0.0.0, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL"
+		/>
+		<AssemblyReference
+			RelativePath="System.Windows.Forms.dll"
+			AssemblyName="System.Windows.Forms, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+		/>
+		<AssemblyReference
+			RelativePath="System.XML.dll"
+			AssemblyName="System.Xml, Version=2.0.0.0, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL"
+		/>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+			>
+			<File
+				RelativePath=".\in_mpc.cpp"
+				>
+			</File>
+			<File
+				RelativePath=".\mpc_info.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						MinimalRebuild="false"
+						ExceptionHandling="2"
+						BasicRuntimeChecks="0"
+						UsePrecompiledHeader="0"
+						DebugInformationFormat="3"
+						CompileAsManaged="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						MinimalRebuild="false"
+						ExceptionHandling="2"
+						BasicRuntimeChecks="0"
+						UsePrecompiledHeader="0"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\mpc_player.cpp"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ExceptionHandling="2"
+						CompileAsManaged="1"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						ExceptionHandling="2"
+					/>
+				</FileConfiguration>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc;xsd"
+			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+			>
+			<File
+				RelativePath=".\in2.h"
+				>
+			</File>
+			<File
+				RelativePath=".\mpc_info.h"
+				FileType="3"
+				>
+				<File
+					RelativePath=".\mpc_info.resx"
+					SubType="Designer"
+					>
+				</File>
+			</File>
+			<File
+				RelativePath=".\mpc_player.h"
+				>
+			</File>
+			<File
+				RelativePath=".\out.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
+			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
