mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 00:20:47 +01:00
Update Winamp plugin with the "latest" (2008) SDK defs [unicode preps]
This commit is contained in:
parent
fa829d49f7
commit
3fc6db0414
166
winamp/in2.h
166
winamp/in2.h
@ -1,103 +1,137 @@
|
||||
#ifndef NULLSOFT_WINAMP_IN2H
|
||||
#define NULLSOFT_WINAMP_IN2H
|
||||
#include "out.h"
|
||||
|
||||
// note: exported symbol is now winampGetInModule2.
|
||||
|
||||
#define IN_VER 0x100
|
||||
#define IN_UNICODE 0x0F000000
|
||||
|
||||
#ifdef UNICODE_INPUT_PLUGIN
|
||||
#define in_char wchar_t
|
||||
#define IN_VER (IN_UNICODE | 0x100)
|
||||
#else
|
||||
#define in_char char
|
||||
#define IN_VER 0x100
|
||||
#endif
|
||||
|
||||
#define IN_MODULE_FLAG_USES_OUTPUT_PLUGIN 1
|
||||
// By default, Winamp assumes that your input plugin wants to use Winamp's EQ, and doesn't do replay gain
|
||||
// if you handle any of these yourself (EQ, Replay Gain adjustments), then set these flags accordingly
|
||||
#define IN_MODULE_FLAG_EQ 2 // set this if you do your own EQ
|
||||
#define IN_MODULE_FLAG_REPLAYGAIN 8 // set this if you adjusted volume for replay gain
|
||||
// for tracks with no replay gain metadata, you should clear this flag
|
||||
// UNLESS you handle "non_replaygain" gain adjustment yourself
|
||||
#define IN_MODULE_FLAG_REPLAYGAIN_PREAMP 16 // use this if you queried for the replay gain preamp parameter and used it
|
||||
// this parameter is new to 5.54
|
||||
typedef struct
|
||||
{
|
||||
int version; // module type (IN_VER)
|
||||
char *description; // description of module, with version string
|
||||
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)
|
||||
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
|
||||
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 :)
|
||||
int is_seekable; // is this stream seekable?
|
||||
int UsesOutputPlug; // does this plug-in use the output plug-ins? (musn't ever change, ever :)
|
||||
// note that this has turned into a "flags" field
|
||||
// see IN_MODULE_FLAG_*
|
||||
|
||||
void (*Config)(HWND hwndParent); // configuration dialog
|
||||
void (*About)(HWND hwndParent); // about dialog
|
||||
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 (*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);
|
||||
#define GETFILEINFO_TITLE_LENGTH 2048
|
||||
void (*GetFileInfo)(const in_char *file, in_char *title, int *length_in_ms); // if file == NULL, current playing is used
|
||||
|
||||
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
|
||||
#define INFOBOX_EDITED 0
|
||||
#define INFOBOX_UNCHANGED 1
|
||||
int (*InfoBox)(const in_char *file, HWND hwndParent);
|
||||
|
||||
// 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()..
|
||||
int (*IsOurFile)(const in_char *fn); // called before extension checks, to allow detection of mms://, etc
|
||||
// playback stuff
|
||||
int (*Play)(const in_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
|
||||
|
||||
// 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
|
||||
// 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 your thread to seek, which seeks and calls outMod->Flush()..
|
||||
|
||||
// in-window builtin vis stuff
|
||||
// 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
|
||||
|
||||
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()
|
||||
// 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 :)
|
||||
// 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
|
||||
// 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()
|
||||
int (*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 :)
|
||||
// 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
|
||||
// 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
|
||||
int (*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);
|
||||
// call this in Play() to tell the vis plug-ins the current output params.
|
||||
void (*VSASetInfo)(int srate, int nch); // <-- Correct (benski, dec 2005).. old declaration had the params backwards
|
||||
|
||||
|
||||
// dsp plug-in processing:
|
||||
// (filled in by winamp, called by input plug)
|
||||
// dsp plug-in processing:
|
||||
// (filled in by winamp, calld 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 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);
|
||||
// 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.
|
||||
// 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? :)
|
||||
// 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 :)
|
||||
Out_Module *outMod; // filled in by winamp, optionally used :)
|
||||
} In_Module;
|
||||
|
||||
// return values from the winampUninstallPlugin(HINSTANCE hdll, HWND parent, int param)
|
||||
// which determine if we can uninstall the plugin immediately or on winamp restart
|
||||
//
|
||||
// uninstall support was added from 5.0+ and uninstall now support from 5.5+
|
||||
// it is down to you to ensure that if uninstall now is returned that it will not cause a crash
|
||||
// (ie don't use if you've been subclassing the main window)
|
||||
#define IN_PLUGIN_UNINSTALL_NOW 0x1
|
||||
#define IN_PLUGIN_UNINSTALL_REBOOT 0x0
|
||||
|
||||
#endif
|
||||
|
@ -5,6 +5,10 @@
|
||||
** Copyright (c) 1998, Justin Frankel/Nullsoft Inc.
|
||||
*/
|
||||
|
||||
/* Winamp uses wchar_t when this is on, so extra steps are needed */
|
||||
//#define UNICODE_INPUT_PLUGIN
|
||||
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_DEPRECATE
|
||||
#endif
|
||||
@ -22,6 +26,7 @@
|
||||
#include "wa_ipc.h"
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
#ifndef VERSION
|
||||
#include "../version.h"
|
||||
#endif
|
||||
@ -33,14 +38,16 @@
|
||||
#define PLUGIN_DESCRIPTION "vgmstream plugin " VERSION " " __DATE__
|
||||
#define INI_NAME "plugin.ini"
|
||||
|
||||
|
||||
/* post when playback stops */
|
||||
#define WM_WA_MPEG_EOF WM_USER+2
|
||||
|
||||
In_Module input_module; /* the input module, declared at the bottom of this file */
|
||||
DWORD WINAPI __stdcall decode(void *arg);
|
||||
|
||||
char lastfn[MAX_PATH+1] = {0}; /* name of the currently playing file */
|
||||
short sample_buffer[576*2*2]; /* 576 16-bit samples, stereo, possibly doubled in size for DSP */
|
||||
#define WINAMP_MAX_PATH 32768 /* originally 260+1 */
|
||||
char lastfn[WINAMP_MAX_PATH] = {0}; /* name of the currently playing file */
|
||||
|
||||
|
||||
#define DEFAULT_FADE_SECONDS "10.00"
|
||||
#define DEFAULT_FADE_DELAY_SECONDS "0.00"
|
||||
@ -56,6 +63,16 @@ short sample_buffer[576*2*2]; /* 576 16-bit samples, stereo, possibly doubled in
|
||||
#define LOOP_FOREVER_INI_ENTRY "loop_forever"
|
||||
#define IGNORE_LOOP_INI_ENTRY "ignore_loop"
|
||||
|
||||
char *priority_strings[] = {"Idle","Lowest","Below Normal","Normal","Above Normal","Highest (not recommended)","Time Critical (not recommended)"};
|
||||
int priority_values[] = {THREAD_PRIORITY_IDLE,THREAD_PRIORITY_LOWEST,THREAD_PRIORITY_BELOW_NORMAL,THREAD_PRIORITY_NORMAL,THREAD_PRIORITY_ABOVE_NORMAL,THREAD_PRIORITY_HIGHEST,THREAD_PRIORITY_TIME_CRITICAL};
|
||||
|
||||
|
||||
/* Winamp Play extension list, needed to accept/play and associate extensions in Windows */
|
||||
#define EXTENSION_LIST_SIZE VGM_EXTENSION_LIST_CHAR_SIZE * 6
|
||||
#define EXT_BUFFER_SIZE 200
|
||||
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
|
||||
|
||||
/* plugin config */
|
||||
double fade_seconds;
|
||||
double fade_delay_seconds;
|
||||
double loop_count;
|
||||
@ -63,11 +80,11 @@ int thread_priority;
|
||||
int loop_forever;
|
||||
int ignore_loop;
|
||||
|
||||
char *priority_strings[] = {"Idle","Lowest","Below Normal","Normal","Above Normal","Highest (not recommended)","Time Critical (not recommended)"};
|
||||
int priority_values[] = {THREAD_PRIORITY_IDLE,THREAD_PRIORITY_LOWEST,THREAD_PRIORITY_BELOW_NORMAL,THREAD_PRIORITY_NORMAL,THREAD_PRIORITY_ABOVE_NORMAL,THREAD_PRIORITY_HIGHEST,THREAD_PRIORITY_TIME_CRITICAL};
|
||||
|
||||
/* plugin state */
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
HANDLE decode_thread_handle = INVALID_HANDLE_VALUE;
|
||||
short sample_buffer[576*2*2]; /* 576 16-bit samples, stereo, possibly doubled in size for DSP */
|
||||
|
||||
int paused = 0;
|
||||
int decode_abort = 0;
|
||||
int seek_needed_samples = -1;
|
||||
@ -76,15 +93,93 @@ int decode_pos_samples = 0;
|
||||
int stream_length_samples = 0;
|
||||
int fade_samples = 0;
|
||||
|
||||
/* Winamp Play extension list, needed to accept/play and associate extensions in Windows */
|
||||
#define EXTENSION_LIST_SIZE VGM_EXTENSION_LIST_CHAR_SIZE * 6
|
||||
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
|
||||
#define EXT_BUFFER_SIZE 200
|
||||
/* ***************************************** */
|
||||
|
||||
static void add_extension(int length, char * dst, const char * src);
|
||||
static void build_extension_list();
|
||||
/* Winamp INI reader */
|
||||
static void GetINIFileName(char * iniFile) {
|
||||
/* if we're running on a newer winamp version that better supports
|
||||
* saving of settings to a per-user directory, use that directory - if not
|
||||
* then just revert to the old behaviour */
|
||||
|
||||
if(IsWindow(input_module.hMainWindow) && SendMessage(input_module.hMainWindow, WM_WA_IPC,0,IPC_GETVERSION) >= 0x5000) {
|
||||
char * iniDir = (char *)SendMessage(input_module.hMainWindow, WM_WA_IPC, 0, IPC_GETINIDIRECTORY);
|
||||
strncpy(iniFile, iniDir, WINAMP_MAX_PATH);
|
||||
|
||||
strncat(iniFile, "\\Plugins\\", WINAMP_MAX_PATH);
|
||||
/* can't be certain that \Plugins already exists in the user dir */
|
||||
CreateDirectory(iniFile,NULL);
|
||||
strncat(iniFile, INI_NAME, WINAMP_MAX_PATH);
|
||||
}
|
||||
else {
|
||||
char * lastSlash;
|
||||
|
||||
GetModuleFileName(NULL, iniFile, WINAMP_MAX_PATH);
|
||||
lastSlash = strrchr(iniFile, '\\');
|
||||
|
||||
*(lastSlash + 1) = 0;
|
||||
strncat(iniFile, "Plugins\\" INI_NAME,WINAMP_MAX_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
/* Adds ext to Winamp's extension list */
|
||||
static void add_extension(int length, char * dst, const char * ext) {
|
||||
char buf[EXT_BUFFER_SIZE];
|
||||
char ext_upp[EXT_BUFFER_SIZE];
|
||||
int ext_len, written;
|
||||
int i,j;
|
||||
if (length <= 1)
|
||||
return;
|
||||
|
||||
ext_len = strlen(ext);
|
||||
|
||||
/* find end of dst (double \0), saved in i */
|
||||
for (i=0; i<length-2 && (dst[i] || dst[i+1]); i++)
|
||||
;
|
||||
|
||||
/* check if end reached or not enough room to add */
|
||||
if (i == length-2 || i + EXT_BUFFER_SIZE+2 > length-2 || ext_len * 3 + 20+2 > EXT_BUFFER_SIZE) {
|
||||
dst[i]='\0';
|
||||
dst[i+1]='\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
i++;
|
||||
|
||||
/* uppercase ext */
|
||||
for (j=0; j < ext_len; j++)
|
||||
ext_upp[j] = toupper(ext[j]);
|
||||
ext_upp[j] = '\0';
|
||||
|
||||
/* copy new extension + double null terminate */
|
||||
written = sprintf(buf, "%s%c%s Audio File (*.%s)%c", ext,'\0',ext_upp,ext_upp,'\0'); /*ex: "vgmstream\0vgmstream Audio File (*.VGMSTREAM)\0" */
|
||||
for (j=0; j < written; i++,j++)
|
||||
dst[i] = buf[j];
|
||||
dst[i]='\0';
|
||||
dst[i+1]='\0';
|
||||
}
|
||||
|
||||
/* Creates Winamp's extension list, a single string that ends with \0\0.
|
||||
* Each extension must be in this format: "extension\0Description\0" */
|
||||
static void build_extension_list() {
|
||||
const char ** ext_list;
|
||||
int ext_list_len;
|
||||
int i;
|
||||
|
||||
working_extension_list[0]='\0';
|
||||
working_extension_list[1]='\0';
|
||||
|
||||
ext_list = vgmstream_get_formats();
|
||||
ext_list_len = vgmstream_get_formats_length();
|
||||
|
||||
for (i=0; i < ext_list_len; i++) {
|
||||
add_extension(EXTENSION_LIST_SIZE, working_extension_list, ext_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/* ***************************************** */
|
||||
|
||||
/* about dialog */
|
||||
void about(HWND hwndParent) {
|
||||
MessageBox(hwndParent,
|
||||
PLUGIN_DESCRIPTION "\n"
|
||||
@ -92,36 +187,10 @@ void about(HWND hwndParent) {
|
||||
"http://sourceforge.net/projects/vgmstream"
|
||||
,"about in_vgmstream",MB_OK);
|
||||
}
|
||||
void quit() {}
|
||||
|
||||
void GetINIFileName(char * iniFile) {
|
||||
/* if we're running on a newer winamp version that better supports
|
||||
* saving of settings to a per-user directory, use that directory - if not
|
||||
* then just revert to the old behaviour */
|
||||
|
||||
if(IsWindow(input_module.hMainWindow) && SendMessage(input_module.hMainWindow, WM_WA_IPC,0,IPC_GETVERSION) >= 0x5000) {
|
||||
char * iniDir = (char *)SendMessage(input_module.hMainWindow, WM_WA_IPC, 0, IPC_GETINIDIRECTORY);
|
||||
strncpy(iniFile, iniDir, MAX_PATH);
|
||||
|
||||
strncat(iniFile, "\\Plugins\\", MAX_PATH);
|
||||
/* can't be certain that \Plugins already exists in the user dir */
|
||||
CreateDirectory(iniFile,NULL);
|
||||
strncat(iniFile, INI_NAME, MAX_PATH);
|
||||
|
||||
}
|
||||
else {
|
||||
char * lastSlash;
|
||||
|
||||
GetModuleFileName(NULL, iniFile, MAX_PATH);
|
||||
lastSlash = strrchr(iniFile, '\\');
|
||||
|
||||
*(lastSlash + 1) = 0;
|
||||
strncat(iniFile, "Plugins\\" INI_NAME,MAX_PATH);
|
||||
}
|
||||
}
|
||||
|
||||
/* called at program init */
|
||||
void init() {
|
||||
char iniFile[MAX_PATH+1];
|
||||
char iniFile[WINAMP_MAX_PATH];
|
||||
char buf[256];
|
||||
int consumed;
|
||||
|
||||
@ -167,18 +236,23 @@ void init() {
|
||||
build_extension_list();
|
||||
}
|
||||
|
||||
/* we don't recognize protocols */
|
||||
int isourfile(char *fn) { return 0; }
|
||||
/* called at program quit */
|
||||
void quit() {
|
||||
}
|
||||
|
||||
/* called before extension checks, to allow detection of mms://, etc */
|
||||
int isourfile(const in_char *fn) {
|
||||
return 0; /* we don't recognize protocols */
|
||||
}
|
||||
|
||||
/* request to start playing a file */
|
||||
int play(char *fn)
|
||||
{
|
||||
int play(const in_char *fn) {
|
||||
int max_latency;
|
||||
|
||||
/* don't lose a pointer! */
|
||||
if (vgmstream) {
|
||||
/* TODO: this should either pop up an error box or close the file */
|
||||
return 1;
|
||||
return 1; /* error */
|
||||
}
|
||||
/* open the stream, set up */
|
||||
vgmstream = init_vgmstream(fn);
|
||||
@ -191,11 +265,11 @@ int play(char *fn)
|
||||
if (vgmstream->channels <= 0) {
|
||||
close_vgmstream(vgmstream);
|
||||
vgmstream=NULL;
|
||||
return 1;
|
||||
return 1; /* error */
|
||||
}
|
||||
|
||||
/* Remember that name, friends! */
|
||||
strncpy(lastfn,fn,MAX_PATH);
|
||||
strncpy(lastfn,fn,WINAMP_MAX_PATH);
|
||||
|
||||
/* open the output plugin */
|
||||
max_latency = input_module.outMod->Open(vgmstream->sample_rate,vgmstream->channels,
|
||||
@ -204,7 +278,7 @@ int play(char *fn)
|
||||
if (max_latency < 0) {
|
||||
close_vgmstream(vgmstream);
|
||||
vgmstream=NULL;
|
||||
return 1;
|
||||
return 1; /* error */
|
||||
}
|
||||
|
||||
/* Set info display */
|
||||
@ -234,15 +308,27 @@ int play(char *fn)
|
||||
|
||||
SetThreadPriority(decode_thread_handle,priority_values[thread_priority]);
|
||||
|
||||
return 0;
|
||||
return 0; /* success */
|
||||
}
|
||||
|
||||
/* pausing... */
|
||||
void pause() { paused=1; input_module.outMod->Pause(1); }
|
||||
void unpause() {paused=0; input_module.outMod->Pause(0); }
|
||||
int ispaused() { return paused; }
|
||||
/* pause stream */
|
||||
void pause() {
|
||||
paused=1;
|
||||
input_module.outMod->Pause(1);
|
||||
}
|
||||
|
||||
/* stop playback */
|
||||
/* unpause stream */
|
||||
void unpause() {
|
||||
paused=0;
|
||||
input_module.outMod->Pause(0);
|
||||
}
|
||||
|
||||
/* ispaused? return 1 if paused, 0 if not */
|
||||
int ispaused() {
|
||||
return paused;
|
||||
}
|
||||
|
||||
/* stop (unload) stream */
|
||||
void stop() {
|
||||
if (decode_thread_handle != INVALID_HANDLE_VALUE) {
|
||||
decode_abort=1;
|
||||
@ -265,28 +351,32 @@ void stop() {
|
||||
input_module.SAVSADeInit();
|
||||
}
|
||||
|
||||
/* get current stream length */
|
||||
/* get length in ms */
|
||||
int getlength() {
|
||||
return stream_length_samples*1000LL/vgmstream->sample_rate;
|
||||
}
|
||||
|
||||
/* get current output time */
|
||||
/* current output time in ms */
|
||||
int getoutputtime() {
|
||||
return decode_pos_ms+(input_module.outMod->GetOutputTime()-input_module.outMod->GetWrittenTime());
|
||||
}
|
||||
|
||||
/* seek */
|
||||
/* seeks to point in stream (in ms) */
|
||||
void setoutputtime(int t) {
|
||||
if (vgmstream)
|
||||
seek_needed_samples = (long long)t * vgmstream->sample_rate / 1000LL;
|
||||
}
|
||||
|
||||
/* pass these commands through */
|
||||
void setvolume(int volume) { input_module.outMod->SetVolume(volume); }
|
||||
void setpan(int pan) { input_module.outMod->SetPan(pan); }
|
||||
void setvolume(int volume) {
|
||||
input_module.outMod->SetVolume(volume);
|
||||
}
|
||||
void setpan(int pan) {
|
||||
input_module.outMod->SetPan(pan);
|
||||
}
|
||||
|
||||
/* display information */
|
||||
int infoDlg(char *fn, HWND hwnd) {
|
||||
int infoDlg(const in_char *fn, HWND hwnd) {
|
||||
VGMSTREAM * infostream = NULL;
|
||||
char description[1024];
|
||||
description[0]='\0';
|
||||
@ -297,7 +387,7 @@ int infoDlg(char *fn, HWND hwnd) {
|
||||
if (!vgmstream) return 0;
|
||||
describe_vgmstream(vgmstream,description,sizeof(description));
|
||||
} else {
|
||||
infostream = init_vgmstream(fn);
|
||||
infostream = init_vgmstream((char*)fn);
|
||||
if (!infostream) return 0;
|
||||
describe_vgmstream(infostream,description,sizeof(description));
|
||||
close_vgmstream(infostream);
|
||||
@ -309,7 +399,7 @@ int infoDlg(char *fn, HWND hwnd) {
|
||||
}
|
||||
|
||||
/* retrieve information on this or possibly another file */
|
||||
void getfileinfo(char *filename, char *title, int *length_in_ms) {
|
||||
void getfileinfo(const in_char *filename, in_char *title, int *length_in_ms) {
|
||||
if (!filename || !*filename) /* currently playing file*/
|
||||
{
|
||||
if (!vgmstream) return;
|
||||
@ -318,7 +408,7 @@ void getfileinfo(char *filename, char *title, int *length_in_ms) {
|
||||
{
|
||||
char *p=lastfn+strlen(lastfn);
|
||||
while (*p != '\\' && p >= lastfn) p--;
|
||||
strcpy(title,++p);
|
||||
strcpy((char*)title,++p);
|
||||
}
|
||||
}
|
||||
else /* some other file */
|
||||
@ -337,15 +427,17 @@ void getfileinfo(char *filename, char *title, int *length_in_ms) {
|
||||
}
|
||||
if (title)
|
||||
{
|
||||
char *p=filename+strlen(filename);
|
||||
const char *p = filename + strlen(filename);
|
||||
while (*p != '\\' && p >= filename) p--;
|
||||
strcpy(title,++p);
|
||||
strcpy((char*)title,++p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* nothin' */
|
||||
void eq_set(int on, char data[10], int preamp) {}
|
||||
/* eq stuff */
|
||||
void eq_set(int on, char data[10], int preamp) {
|
||||
/* nothin' */
|
||||
}
|
||||
|
||||
/* the decode thread */
|
||||
DWORD WINAPI __stdcall decode(void *arg) {
|
||||
@ -439,7 +531,7 @@ DWORD WINAPI __stdcall decode(void *arg) {
|
||||
|
||||
INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
|
||||
char buf[256];
|
||||
char iniFile[MAX_PATH+1];
|
||||
char iniFile[WINAMP_MAX_PATH];
|
||||
static int mypri;
|
||||
HANDLE hSlider;
|
||||
|
||||
@ -587,12 +679,16 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* configuration dialog */
|
||||
void config(HWND hwndParent) {
|
||||
/* defined in resource.rc */
|
||||
DialogBox(input_module.hDllInstance, (const char *)IDD_CONFIG, hwndParent, configDlgProc);
|
||||
}
|
||||
|
||||
In_Module input_module =
|
||||
{
|
||||
/* *********************************** */
|
||||
|
||||
/* main plugin def */
|
||||
In_Module input_module = {
|
||||
IN_VER,
|
||||
PLUGIN_DESCRIPTION,
|
||||
0, /* hMainWindow */
|
||||
@ -624,68 +720,6 @@ In_Module input_module =
|
||||
0 // out_mod
|
||||
};
|
||||
|
||||
__declspec( dllexport ) In_Module * winampGetInModule2()
|
||||
{
|
||||
__declspec( dllexport ) In_Module * winampGetInModule2() {
|
||||
return &input_module;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates Winamp's extension list, a single string that ends with \0\0.
|
||||
* Each extension must be in this format: "extension\0Description\0"
|
||||
*/
|
||||
static void build_extension_list() {
|
||||
const char ** ext_list;
|
||||
int ext_list_len;
|
||||
int i;
|
||||
|
||||
working_extension_list[0]='\0';
|
||||
working_extension_list[1]='\0';
|
||||
|
||||
ext_list = vgmstream_get_formats();
|
||||
ext_list_len = vgmstream_get_formats_length();
|
||||
|
||||
for (i=0; i < ext_list_len; i++) {
|
||||
add_extension(EXTENSION_LIST_SIZE, working_extension_list, ext_list[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds ext to Winamp's extension list.
|
||||
*/
|
||||
static void add_extension(int length, char * dst, const char * ext) {
|
||||
char buf[EXT_BUFFER_SIZE];
|
||||
char ext_upp[EXT_BUFFER_SIZE];
|
||||
int ext_len, written;
|
||||
int i,j;
|
||||
if (length <= 1)
|
||||
return;
|
||||
|
||||
ext_len = strlen(ext);
|
||||
|
||||
/* find end of dst (double \0), saved in i */
|
||||
for (i=0; i<length-2 && (dst[i] || dst[i+1]); i++)
|
||||
;
|
||||
|
||||
/* check if end reached or not enough room to add */
|
||||
if (i == length-2 || i + EXT_BUFFER_SIZE+2 > length-2 || ext_len * 3 + 20+2 > EXT_BUFFER_SIZE) {
|
||||
dst[i]='\0';
|
||||
dst[i+1]='\0';
|
||||
return;
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
i++;
|
||||
|
||||
/* uppercase ext */
|
||||
for (j=0; j < ext_len; j++)
|
||||
ext_upp[j] = toupper(ext[j]);
|
||||
ext_upp[j] = '\0';
|
||||
|
||||
/* copy new extension + double null terminate */
|
||||
written = sprintf(buf, "%s%c%s Audio File (*.%s)%c", ext,'\0',ext_upp,ext_upp,'\0'); /*ex: "vgmstream\0vgmstream Audio File (*.VGMSTREAM)\0" */
|
||||
for (j=0; j < written; i++,j++)
|
||||
dst[i] = buf[j];
|
||||
dst[i]='\0';
|
||||
dst[i+1]='\0';
|
||||
}
|
||||
|
85
winamp/out.h
85
winamp/out.h
@ -1,52 +1,73 @@
|
||||
#ifndef NULLSOFT_OUTH
|
||||
#define NULLSOFT_OUTH
|
||||
#include <windows.h>
|
||||
#include <stddef.h>
|
||||
// ids:
|
||||
// waveout: 32
|
||||
// gapless: 64
|
||||
// xfade: 63
|
||||
// disk: 33
|
||||
// dsound: 38
|
||||
// NULL: 65
|
||||
// mm2: 69
|
||||
|
||||
#if (_MSC_VER <= 1200)
|
||||
typedef int intptr_t;
|
||||
#endif
|
||||
|
||||
#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.
|
||||
int version; // module version (OUT_VER)
|
||||
char *description; // description of module, with version string
|
||||
intptr_t 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)
|
||||
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 (*Config)(HWND hwndParent); // configuration dialog
|
||||
void (*About)(HWND hwndParent); // about dialog
|
||||
|
||||
void (*Init)(); // called when loaded
|
||||
void (*Quit)(); // called when unloaded
|
||||
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
|
||||
int (*Open)(int samplerate, int numchannels, int bitspersamp, int bufferlenms, int prebufferms);
|
||||
// returns >=0 on success, <0 on failure
|
||||
|
||||
void (*Close)(); // close the ol' output device.
|
||||
// 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
|
||||
// pass bufferlenms==-666 to tell the output plugin that it's clock is going to be used to sync video
|
||||
// out_ds turns off silence-eating when -666 is passed
|
||||
|
||||
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.
|
||||
void (*Close)(); // close the ol' output device.
|
||||
|
||||
int (*CanWrite)(); // returns number of bytes possible to write at a given time.
|
||||
// Never will decrease unless you call Write (or Close, heh)
|
||||
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 (*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 (*CanWrite)(); // returns number of bytes possible to write at a given time.
|
||||
// Never will decrease unless you call Write (or Close, heh)
|
||||
|
||||
int (*Pause)(int pause); // returns previous pause state
|
||||
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
|
||||
|
||||
void (*SetVolume)(int volume); // volume is 0-255
|
||||
void (*SetPan)(int pan); // pan is -128 to 128
|
||||
int (*Pause)(int pause); // returns previous pause state
|
||||
|
||||
void (*Flush)(int t); // flushes buffers and restarts output at time t (in ms)
|
||||
// (used for seeking)
|
||||
void (*SetVolume)(int volume); // volume is 0-255
|
||||
void (*SetPan)(int pan); // pan is -128 to 128
|
||||
|
||||
int (*GetOutputTime)(); // returns played time in MS
|
||||
int (*GetWrittenTime)(); // returns time written in MS (used for synching up vis stuff)
|
||||
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;
|
||||
|
||||
|
||||
#endif
|
||||
|
1250
winamp/wa_ipc.h
1250
winamp/wa_ipc.h
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user