aboutsummaryrefslogtreecommitdiff
path: root/Src/Plugins/Output/out_disk
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Output/out_disk
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/Plugins/Output/out_disk')
-rw-r--r--Src/Plugins/Output/out_disk/main.cpp1203
-rw-r--r--Src/Plugins/Output/out_disk/out_disk.h18
-rw-r--r--Src/Plugins/Output/out_disk/out_disk.rc184
-rw-r--r--Src/Plugins/Output/out_disk/out_disk.sln30
-rw-r--r--Src/Plugins/Output/out_disk/out_disk.vcxproj301
-rw-r--r--Src/Plugins/Output/out_disk/out_disk.vcxproj.filters35
-rw-r--r--Src/Plugins/Output/out_disk/resource.h80
-rw-r--r--Src/Plugins/Output/out_disk/version.rc239
8 files changed, 1890 insertions, 0 deletions
diff --git a/Src/Plugins/Output/out_disk/main.cpp b/Src/Plugins/Output/out_disk/main.cpp
new file mode 100644
index 00000000..ca0ed8ce
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/main.cpp
@@ -0,0 +1,1203 @@
+#define STRICT
+#include <windows.h>
+#include <windowsx.h>
+#include <commctrl.h>
+#include <shlobj.h>
+#include <mmreg.h>
+#include <msacm.h>
+#include "out_disk.h"
+#include "../winamp/wa_ipc.h"
+#include <shlwapi.h>
+#include <strsafe.h>
+
+// wasabi based services for localisation support
+api_service *WASABI_API_SVC = 0;
+api_language *WASABI_API_LNG = 0;
+HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
+
+class CriticalSection : public CRITICAL_SECTION
+{
+public:
+ inline void Enter() {EnterCriticalSection(this);}
+ inline void Leave() {LeaveCriticalSection(this);}
+ CriticalSection() {InitializeCriticalSection(this);}
+ ~CriticalSection() {DeleteCriticalSection(this);}
+ //BOOL TryEnter() {return TryEnterCriticalSection(this);}
+};
+
+class __T_SYNC
+{
+private:
+ CriticalSection *p;
+public:
+ inline __T_SYNC(CriticalSection& s) {p=&s;p->Enter();}
+ inline void Leave() {if (p) p->Leave();}
+ inline void Enter() {if (p) p->Enter();}
+ inline void Abort() {p=0;}
+ inline ~__T_SYNC() {Leave();}
+};
+
+static CriticalSection g_sync;
+
+#define SYNCFUNC __T_SYNC __sync(g_sync);
+
+#define tabsize(X) (sizeof(X)/sizeof(*X))
+
+enum
+{
+ MODE_AUTO=0,
+ MODE_WAV=1,
+ MODE_RAW=2
+};
+
+int mode_names_idx[] = {IDS_AUTO_RECOMMENDED,IDS_FORCE_WAV_FILE,IDS_FORCE_RAW_DATA};
+static const wchar_t* format_names[]={L"%title%",L"%filename%",L"%title%_%extension%",L"%filename%_%extension%"};
+static wchar_t szDescription[256];
+int index_name_idx[] = {IDS_DISABLED,IDS_1_DIGIT,IDS_2_DIGITS,IDS_3_DIGITS,IDS_4_DIGITS};
+
+#define rev32(X) ((((DWORD)(X)&0xFF)<<24)|(((DWORD)(X)&0xFF00)<<8)|(((DWORD)(X)&0xFF0000)>>8)|(((DWORD)(X)&0xFF000000)>>24))
+
+static char cfg_output_dir[MAX_PATH]="c:\\";
+static char cfg_singlefile_output[MAX_PATH]="c:\\output.wav";
+static bool cfg_singlefile_enabled = 0;
+static bool cfg_convert_enabled=0;
+static bool cfg_thread_override = 0;
+static bool cfg_output_source_dir = 0;
+static int cfg_output_mode=0;
+static bool cfg_show_saveas=0;
+static int cfg_format_mode=0;
+static int cfg_format_index=2;
+
+static bool use_convert;
+
+
+static bool GetCheck(HWND wnd,int id) {return !!SendDlgItemMessage(wnd,id,BM_GETCHECK,0,0);}
+
+static void SetCheck(HWND wnd,int id,bool b) {SendDlgItemMessage(wnd,id,BM_SETCHECK,b ? BST_CHECKED : BST_UNCHECKED,0);}
+
+void SetPathChoiceButtonText(HWND hwndDlg, char* path, UINT id)
+{
+ HWND control = GetDlgItem(hwndDlg, id);
+ HDC hdc = GetDC(control);
+ RECT r = {0};
+ char temp[MAX_PATH] = {0};
+
+ lstrcpynA(temp, path, MAX_PATH);
+ SelectObject(hdc, (HFONT)SendMessage(control, WM_GETFONT, 0, 0));
+ GetClientRect(control, &r);
+ r.left += 5;
+ r.right -= 5;
+ DrawTextA(hdc, temp, -1, &r, DT_PATH_ELLIPSIS|DT_WORD_ELLIPSIS|DT_MODIFYSTRING);
+ SetWindowTextA(control, temp);
+ ReleaseDC(control, hdc);
+}
+
+BOOL CALLBACK browseEnumProc(HWND hwnd, LPARAM lParam)
+{
+ char cl[32] = {0};
+ GetClassNameA(hwnd, cl, ARRAYSIZE(cl));
+ if (!lstrcmpiA(cl, WC_TREEVIEW))
+ {
+ PostMessage(hwnd, TVM_ENSUREVISIBLE, 0, (LPARAM)TreeView_GetSelection(hwnd));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int _stdcall browzaproc(HWND hwnd, UINT msg, LPARAM lp, LPARAM dat)
+{
+ if (msg == BFFM_INITIALIZED)
+ {
+ SendMessage(hwnd, BFFM_SETSELECTION, 1, dat);
+
+ // this is not nice but it fixes the selection not working correctly on all OSes
+ EnumChildWindows(hwnd, browseEnumProc, 0);
+ }
+ return 0;
+}
+
+char g_tmp[MAX_PATH] = {0}, g_tmp_sf[MAX_PATH] = {0};
+static void d_browza(HWND wnd,HWND bt,wchar_t* tx)
+{
+ IMalloc* pMalloc=0;
+ SHGetMalloc(&pMalloc);
+ if (!pMalloc) return;
+
+ BROWSEINFOW bi=
+ {
+ wnd,
+ 0,
+ 0,
+ tx,
+ BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE,
+ browzaproc,
+#ifdef WIN64
+ (long long)g_tmp,
+#else
+ (long)g_tmp,
+#endif
+ 0
+ };
+ LPITEMIDLIST li=SHBrowseForFolderW(&bi);
+ if (li)
+ {
+ SHGetPathFromIDListA(li,g_tmp);
+ SetPathChoiceButtonText(wnd, g_tmp, IDC_OUTPUT_DIRECTORY);
+ pMalloc->Free(li);
+ }
+ pMalloc->Release();
+}
+
+static WAVEFORMATEX singlefile_wfx,singlefile_wfx_temp;
+
+#define WFSIZ 0x800
+typedef struct
+{
+ WAVEFORMATEX wfx;
+ BYTE crap[WFSIZ];
+} EXT_WFX;
+
+EXT_WFX convert_wfx,convert_wfx_temp;
+static const WAVEFORMATEX wfx_default =
+{
+ WAVE_FORMAT_PCM,
+ 2,
+ 44100,
+ 44100*4,
+ 4,
+ 16,
+ 0
+};
+
+void _inline ACM_gettext1(char* tx, int txCch)
+{
+ ACMFORMATDETAILS afd;
+ ZeroMemory(&afd, sizeof(afd));
+ afd.cbStruct = sizeof(afd);
+ afd.dwFormatTag = WAVE_FORMAT_PCM;
+ afd.pwfx = &singlefile_wfx_temp;
+ afd.cbwfx = sizeof(singlefile_wfx_temp);
+ if (!acmFormatDetails(0, &afd, ACM_FORMATDETAILSF_FORMAT))
+ {
+ lstrcpyn(tx, afd.szFormat, txCch);
+ }
+}
+
+void _inline ACM_gettext(char* tx)
+{
+ ACMFORMATTAGDETAILS aftd;
+ ZeroMemory(&aftd,sizeof(aftd));
+ aftd.cbStruct=sizeof(aftd);
+ aftd.dwFormatTag=convert_wfx_temp.wfx.wFormatTag;
+ if (!acmFormatTagDetails(0,&aftd,ACM_FORMATTAGDETAILSF_FORMATTAG))
+ {
+ char* p=aftd.szFormatTag;
+ while(p && *p) *(tx++)=*(p++);
+ *(tx++)=13;
+ *(tx++)=10;
+ }
+ ACMFORMATDETAILS afd;
+ ZeroMemory(&afd,sizeof(afd));
+ afd.cbStruct=sizeof(afd);
+ afd.dwFormatTag=convert_wfx_temp.wfx.wFormatTag;
+ afd.pwfx=&convert_wfx_temp.wfx;
+ afd.cbwfx=sizeof(convert_wfx_temp);
+ if (!acmFormatDetails(0,&afd,ACM_FORMATDETAILSF_FORMAT))
+ {
+ char* p=afd.szFormat;
+ while(p && *p) *(tx++)=*(p++);
+ }
+ *tx=0;
+}
+
+void ACM_choose(HWND w,bool pcm)
+{
+ ACMFORMATCHOOSE afc;
+ memset(&afc,0,sizeof(afc));
+ afc.cbStruct=sizeof(afc);
+ afc.fdwStyle=ACMFORMATCHOOSE_STYLEF_INITTOWFXSTRUCT;
+ if (pcm)
+ {
+ singlefile_wfx_temp.wFormatTag=WAVE_FORMAT_PCM;
+ afc.pwfxEnum=&singlefile_wfx_temp;
+ afc.fdwEnum=ACM_FORMATENUMF_WFORMATTAG;
+ afc.pwfx = &singlefile_wfx_temp;
+ afc.cbwfx = sizeof(singlefile_wfx_temp);
+ }
+ else
+ {
+ afc.pwfx = &convert_wfx_temp.wfx;
+ afc.cbwfx = sizeof(convert_wfx_temp);
+ }
+
+ afc.hwndOwner=w;
+
+ if (!acmFormatChoose(&afc))
+ {
+ if (pcm)
+ {
+ SetDlgItemText(w,IDC_SINGLEFILE_FORMAT_BUTTON,afc.szFormat);
+ }
+ else
+ {
+ char tmp[512] = {0};
+ StringCchPrintf(tmp, 512, "%s\x0d\x0a%s",afc.szFormatTag,afc.szFormat);
+ SetDlgItemText(w,IDC_CONVERT_BUTTON,tmp);
+ }
+ }
+}
+
+void _inline do_acm_text(HWND wnd)
+{
+ char tmp[256] = {0};
+ ACM_gettext(tmp);
+ SetDlgItemText(wnd,IDC_CONVERT_BUTTON,tmp);
+}
+
+void _inline do_acm_text1(HWND wnd)
+{
+ char tmp[256] = {0};
+ ACM_gettext1(tmp, 256);
+ SetDlgItemText(wnd,IDC_SINGLEFILE_FORMAT_BUTTON,tmp);
+}
+
+void wav1_set(HWND w,bool b)
+{
+ static struct
+ {
+ WORD id;
+ bool t;
+ } wav1_w_c[]=
+ {
+ {IDC_OUTPUT_STATIC,1},
+ {IDC_OUTPUT_DIRECTORY_STATIC,1},
+ {IDC_OUTPUT_DIRECTORY,1},
+ {IDC_OUTPUT_SRCDIR,1},
+ {IDC_FILENAME_SAVEAS,1},
+ {IDC_FILENAME_INDEX_STATIC,1},
+ {IDC_FILENAME_INDEX,1},
+ {IDC_OUTMODE_STATIC,1},
+ {IDC_OUTMODE,1},
+ {IDC_CONVERT_STATIC,1},
+ {IDC_CONVERT_CHECK,1},
+ {IDC_CONVERT_BUTTON,1},
+ {IDC_CONVERT_NOTE,1},
+ {IDC_FILENAME_FORMAT,1},
+ {IDC_FILENAME_FORMAT_STATIC,1},
+ {IDC_SINGLEFILE_FILE_STATIC,0},
+ {IDC_SINGLEFILE_FILE_BUTTON,0},
+ {IDC_SINGLEFILE_FORMAT_STATIC,0},
+ {IDC_SINGLEFILE_FORMAT_BUTTON,0},
+ };
+
+ UINT n;
+ for(n=0;n<tabsize(wav1_w_c);n++)
+ {
+ EnableWindow(GetDlgItem(w,wav1_w_c[n].id),wav1_w_c[n].t^b);
+ }
+}
+
+BOOL CALLBACK DlgProc(HWND wnd,UINT msg,WPARAM wp,LPARAM lp)
+{
+ switch(msg)
+ {
+ case WM_INITDIALOG:
+ {
+ wchar_t title[128] = {0}, temp[128] = {0};
+ StringCchPrintfW(title,128,WASABI_API_LNGSTRINGW(IDS_SETTINGS_TITLE),WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_DISK_WRITER_OLD, temp, 128));
+ SetWindowTextW(wnd,title);
+ SetDlgItemText(wnd,IDC_OUTPUT_DIRECTORY,cfg_output_dir);
+ SetPathChoiceButtonText(wnd,cfg_output_dir,IDC_OUTPUT_DIRECTORY);
+ lstrcpyn(g_tmp,cfg_output_dir,MAX_PATH);
+ SetCheck(wnd,IDC_CONVERT,cfg_convert_enabled);
+ memcpy(&convert_wfx_temp,&convert_wfx,sizeof(convert_wfx));
+ memcpy(&singlefile_wfx_temp,&singlefile_wfx,sizeof(WAVEFORMATEX));
+ SetCheck(wnd,IDC_SINGLEFILE_CHECK,cfg_singlefile_enabled);
+ SetCheck(wnd,IDC_THREAD_HACK,cfg_thread_override);
+ SetPathChoiceButtonText(wnd,cfg_singlefile_output,IDC_SINGLEFILE_FILE_BUTTON);
+ lstrcpyn(g_tmp_sf,cfg_singlefile_output,MAX_PATH);
+ do_acm_text(wnd);
+ do_acm_text1(wnd);
+
+ {
+ HWND w=GetDlgItem(wnd,IDC_MODE);
+ int n;
+ for(n=0;n<tabsize(mode_names_idx);n++)
+ SendMessageW(w,CB_ADDSTRING,0,
+#ifdef WIN64
+ (long long)WASABI_API_LNGSTRINGW(mode_names_idx[n])
+#else
+ (long)WASABI_API_LNGSTRINGW(mode_names_idx[n])
+#endif
+ );
+ SendMessage(w,CB_SETCURSEL,cfg_output_mode,0);
+
+ w=GetDlgItem(wnd,IDC_FILENAME_FORMAT);
+ for(n=0;n<tabsize(format_names);n++)
+ SendMessageW(w,CB_ADDSTRING,0,
+#ifdef WIN64
+ (long long)format_names[n]
+#else
+ (long)format_names[n]
+#endif
+ );
+ SendMessage(w,CB_SETCURSEL,cfg_format_mode,0);
+
+ w=GetDlgItem(wnd,IDC_FILENAME_INDEX);
+ for(n=0;n<tabsize(index_name_idx);n++)
+ SendMessageW(w,CB_ADDSTRING,0,
+#ifdef WIN64
+ (long long)WASABI_API_LNGSTRINGW(index_name_idx[n])
+#else
+ (long)WASABI_API_LNGSTRINGW(index_name_idx[n])
+#endif
+ );
+ SendMessage(w,CB_SETCURSEL,cfg_format_index,0);
+ }
+
+ wav1_set(wnd,cfg_singlefile_enabled);
+
+ SetCheck(wnd,IDC_OUTPUT_SRCDIR,cfg_output_source_dir);
+ SetCheck(wnd,IDC_FILENAME_SAVEAS,cfg_show_saveas);
+
+ return 1;
+ }
+ case WM_COMMAND:
+ if (wp==IDC_CONVERT_BUTTON)
+ {
+ ACM_choose(wnd,0);
+ }
+ else if (wp==IDC_OUTPUT_DIRECTORY)
+ {
+ d_browza(wnd,(HWND)lp,WASABI_API_LNGSTRINGW(IDS_SELECT_OUTPUT_DIRECTORY));
+ }
+ else if (wp==IDCANCEL) EndDialog(wnd,0);
+ else if (wp==IDOK)
+ {
+ cfg_convert_enabled=GetCheck(wnd,IDC_CONVERT);
+ lstrcpyn(cfg_output_dir,g_tmp,MAX_PATH);
+ memcpy(&convert_wfx,&convert_wfx_temp,sizeof(convert_wfx));
+ memcpy(&singlefile_wfx,&singlefile_wfx_temp,sizeof(WAVEFORMATEX));
+ cfg_singlefile_enabled=GetCheck(wnd,IDC_SINGLEFILE_CHECK);
+ cfg_thread_override=GetCheck(wnd,IDC_THREAD_HACK);
+ cfg_output_mode=(int)SendDlgItemMessage(wnd,IDC_MODE,CB_GETCURSEL,0,0);
+ lstrcpyn(cfg_singlefile_output,g_tmp_sf,MAX_PATH);
+ cfg_output_source_dir=GetCheck(wnd,IDC_OUTPUT_SRCDIR);
+ cfg_show_saveas=GetCheck(wnd,IDC_FILENAME_SAVEAS);
+
+ cfg_format_mode=(int)SendDlgItemMessage(wnd,IDC_FILENAME_FORMAT,CB_GETCURSEL,0,0);
+ cfg_format_index=(int)SendDlgItemMessage(wnd,IDC_FILENAME_INDEX,CB_GETCURSEL,0,0);
+
+ EndDialog(wnd,0);
+ }
+ else if (wp==IDC_SINGLEFILE_FILE_BUTTON)
+ {
+ char tmp[MAX_PATH] = {0}, filter[64] = {0};
+
+ StringCchPrintf(filter,64, WASABI_API_LNGSTRING(IDS_X_FILES_DOT_X),"WAV",".wav");
+ char * ptr=filter;
+ while(ptr && *ptr)
+ {
+ if (*ptr=='|') *ptr=0;
+ ptr++;
+ }
+
+ GetDlgItemText(wnd,IDC_SINGLEFILE_FILE_BUTTON,tmp,MAX_PATH);
+ lstrcpyn(tmp,g_tmp_sf,MAX_PATH);
+ OPENFILENAME ofn = {0};
+ ofn.lStructSize=sizeof(ofn);
+ ofn.hwndOwner=wnd;
+ ofn.lpstrFilter=filter;
+ ofn.lpstrFile=tmp;
+ ofn.nMaxFile=MAX_PATH;
+ ofn.Flags=OFN_HIDEREADONLY|OFN_PATHMUSTEXIST;
+ ofn.lpstrDefExt="wav";
+ if (GetSaveFileName(&ofn))
+ {
+ SetPathChoiceButtonText(wnd,tmp,IDC_SINGLEFILE_FILE_BUTTON);
+ lstrcpyn(g_tmp_sf, tmp, MAX_PATH);
+ }
+ }
+ else if (wp==IDC_SINGLEFILE_FORMAT_BUTTON) ACM_choose(wnd,1);
+ else if (wp==IDC_SINGLEFILE_CHECK) wav1_set(wnd,GetCheck(wnd,IDC_SINGLEFILE_CHECK));
+
+ break;
+ }
+ return 0;
+}
+
+void Config(HWND hWnd)
+{
+ WASABI_API_DIALOGBOXW(IDD_DIALOG1,hWnd,DlgProc);
+}
+
+static int nsam;
+static int g_freq,g_nch,g_bps;
+static int paused;
+
+const static char badchars[]={'.','\\','/',':','*','?','\"','<','>','|'};
+
+char* GetDefaultSaveToFolder(char* path_to_store)
+{
+ if(FAILED(SHGetFolderPathA(NULL, CSIDL_MYMUSIC, NULL, SHGFP_TYPE_CURRENT, path_to_store)))
+ {
+ if(FAILED(SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path_to_store)))
+ {
+ lstrcpynA(path_to_store, "C:\\", MAX_PATH);
+ }
+ }
+ return path_to_store;
+}
+
+static void GetName(char* out, int outCch, const char* format_ext)
+{
+ int index = (int)SendMessage(mod.hMainWindow,WM_USER,0,IPC_GETLISTPOS);
+
+ if (cfg_output_source_dir)
+ {
+ const char * dir=(const char *)SendMessage(mod.hMainWindow,WM_USER,index,211);
+ const char * last=strrchr(dir,'\\');
+ while(dir<=last) {*(out++)=*(dir++);}
+ }
+ else
+ {
+ char * dir=cfg_output_dir;
+ if (!*dir)
+ {
+ char tmp[MAX_PATH] = {0};
+ dir=GetDefaultSaveToFolder(tmp);
+ }
+ while(dir && *dir) {*(out++)=*(dir++);}
+ if (out[-1]!='\\') *(out++)='\\';
+ }
+
+ char * badchar_test = out;
+
+ if (cfg_format_index>0)
+ {
+ char temp[16] = {0};
+ StringCchPrintf(temp, 16, "%09u_",index+1);
+ lstrcpyn(out, temp+9-cfg_format_index, outCch);
+ out+=cfg_format_index+1;
+ }
+
+ if (cfg_format_mode&1)//filename
+ {
+ const char * source_full = (const char*)SendMessage(mod.hMainWindow,WM_USER,index,211);
+ const char * source = strrchr(source_full,'\\');
+ if (!source) source = source_full;
+ else source++;
+
+ const char * dot = strrchr(source,'.');
+ if (dot) while(source<dot) *(out++)=*(source++);
+ else while(source && *source) *(out++)=*(source++);
+ }
+ else //title
+ {
+ const char * source = (const char*)SendMessage(mod.hMainWindow,WM_USER,index,212);
+ if (!source) source = "(unknown title)";
+ while(source && *source) *(out++)=*(source++);
+ }
+
+ if (cfg_format_mode&2)
+ {//add extension
+ const char * extension = strrchr((const char*)SendMessage(mod.hMainWindow,WM_USER,index,211),'.');
+ while(extension && *extension) *(out++)=*(extension++);
+ }
+
+
+ while(badchar_test<out)
+ {
+ BYTE c = *badchar_test;
+ int n;
+ for(n=0;n<tabsize(badchars);n++)
+ {
+ if (c==badchars[n]) {*badchar_test='_';break;}
+ }
+
+ badchar_test++;
+ }
+
+ while(format_ext && *format_ext) *(out++)=*(format_ext++);
+ *out=0;
+}
+
+static HANDLE hOut=INVALID_HANDLE_VALUE;
+
+static HACMSTREAM hStream;
+
+static DWORD fact_ofs,data_ofs;
+static bool riff;
+
+static DWORD FileTell(HANDLE hFile) {return SetFilePointer(hFile,0,0,FILE_CURRENT);}
+static void FileAlign(HANDLE hFile) {if (FileTell(hFile)&1) SetFilePointer(hFile,1,0,FILE_CURRENT);}
+
+#define BUFSIZE 0x20000
+
+static BYTE *acm_outbuf;
+static UINT acm_outbufsize;
+static BYTE *acm_buf;
+static BYTE *acm_buf1;
+static UINT inbuf,inbuf1;
+
+static ACMSTREAMHEADER ahd,ahd1;
+static bool active;
+
+static void file_err(char* f, wchar_t* t)
+{
+ wchar_t tmp[512+128] = {0};
+ StringCchPrintfW(tmp, 512+128, L"%s: \"%hs\"", t, f);
+ MessageBoxW(mod.hMainWindow, tmp, szDescription, MB_ICONERROR);
+}
+
+void acm_close();
+
+static int pos_delta;
+
+int Open(int sr,int nch,int bps,int xx,int xxx)
+{
+ // if someone didn't call Close(), close the file for them
+ if (hOut!=INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hOut);
+ hOut=INVALID_HANDLE_VALUE;
+ }
+ int failFlags = 0;
+ SYNCFUNC;
+ char fn[512] = {0};
+ use_convert=cfg_convert_enabled;
+ DWORD bw = 0, t = 0;
+ WAVEFORMATEX wfx=
+ {
+ WAVE_FORMAT_PCM,
+ (WORD)nch,
+ (DWORD)sr,
+ (DWORD)(sr*nch*(bps>>3)),
+ (WORD)(nch*(bps>>3)),
+ (WORD)bps,
+ 0
+ };
+ bool append=0;
+
+ WAVEFORMATEX *pDst=&convert_wfx.wfx;
+ if (!cfg_convert_enabled) pDst=&wfx;
+ if (cfg_singlefile_enabled)
+ {
+ pDst=&singlefile_wfx;
+ use_convert=1;
+ lstrcpyn(fn, cfg_singlefile_output,512);
+ riff=1;
+ }
+ else
+ {
+ const char* ext=".wav";
+ riff=1;
+ if (cfg_output_mode==MODE_RAW)
+ {
+ riff=0;
+ ext=".raw";
+ }
+ else if (cfg_output_mode==MODE_AUTO)
+ {
+ if (pDst->wFormatTag==WAVE_FORMAT_MPEGLAYER3)
+ {
+ riff=0;
+ ext=".mp3";
+ }
+ }
+ GetName(fn, 512, ext);
+ if (cfg_show_saveas)
+ {
+ char filter[64] = {0}, title[128] = {0}, title2[128] = {0};
+ StringCchPrintf(filter,64, WASABI_API_LNGSTRING(IDS_X_FILES_DOT_X),ext,ext);
+ char * ptr=filter;
+ while(ptr && *ptr)
+ {
+ if (*ptr=='|') *ptr=0;
+ ptr++;
+ }
+
+ OPENFILENAME ofn= {0};
+ ofn.lStructSize=sizeof(ofn);
+ ofn.hwndOwner=mod.hMainWindow;
+ ofn.lpstrFilter = filter;
+ ofn.lpstrFile = fn;
+ StringCchPrintf(title,128,WASABI_API_LNGSTRING(IDS_CHOOSE_FILE_NAME),
+ WASABI_API_LNGSTRING_BUF(IDS_NULLSOFT_DISK_WRITER,title2,128));
+ ofn.lpstrTitle = title;
+ ofn.nMaxFile = tabsize(fn);
+ ofn.Flags = OFN_HIDEREADONLY|OFN_PATHMUSTEXIST|OFN_OVERWRITEPROMPT;
+ ofn.lpstrDefExt = ext;
+ if (!GetOpenFileName(&ofn)) return -1;
+ }
+ }
+
+ if (memcmp(&wfx,pDst,sizeof(wfx))==0) use_convert=0;
+
+ nsam=0;
+ g_freq=sr;
+ g_nch=nch;
+ g_bps=bps;
+ paused=0;
+
+ SetLastError(0);
+ hOut=CreateFile(fn,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,0);
+
+ if (hOut==INVALID_HANDLE_VALUE)
+ {
+ DWORD e=GetLastError();
+
+ if (e==ERROR_ALREADY_EXISTS || e==0x50)
+ {
+ if (cfg_singlefile_enabled)
+ {
+ append=1;
+ goto _ap;
+ }
+ wchar_t tmp[512+128] = {0};
+ StringCchPrintfW(tmp, 512+128, WASABI_API_LNGSTRINGW(IDS_FILE_ALREADY_EXISTS_OVERWRITE),fn);
+ if (MessageBoxW(mod.hMainWindow,tmp,szDescription,MB_ICONQUESTION|MB_OKCANCEL)==IDOK)
+ {
+ hOut=CreateFile(fn,GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0);
+ }
+ else return -1;
+ }
+ if (hOut==INVALID_HANDLE_VALUE)
+ {
+ file_err(fn, WASABI_API_LNGSTRINGW(IDS_CANNOT_CREATE_OUTPUT_FILE));
+ return -1;
+ }
+ }
+_ap:
+ fact_ofs=data_ofs=0;
+ if (append)
+ {
+
+ hOut=CreateFile(fn,GENERIC_WRITE|GENERIC_READ,0,0,OPEN_EXISTING,0,0);
+ if (hOut==INVALID_HANDLE_VALUE)
+ {
+ file_err(fn, WASABI_API_LNGSTRINGW(IDS_CANNOT_OPEN_FILE));
+ return -1;
+ }
+ {
+ DWORD br=0;
+ DWORD rf=0,wfs=0;
+ ReadFile(hOut,&rf,4,&br,0);
+ if (rf!='FFIR') goto ap_f;
+ SetFilePointer(hOut,4,0,FILE_CURRENT);
+ br=0; ReadFile(hOut,&rf,4,&br,0);
+ if (rf!='EVAW') goto ap_f;
+ br=0; ReadFile(hOut,&rf,4,&br,0);
+ if (rf!=' tmf') goto ap_f;
+ static WAVEFORMATEX ap_wfx;
+ br=0; ReadFile(hOut,&wfs,4,&br,0);
+ if (wfs<sizeof(ap_wfx)-2 || wfs>sizeof(ap_wfx)) goto ap_f;
+ br=0; ReadFile(hOut,&ap_wfx,wfs,&br,0);
+ if (ap_wfx.wFormatTag!=WAVE_FORMAT_PCM) goto ap_f;
+ br=0; ReadFile(hOut,&rf,4,&br,0);
+ pDst=&ap_wfx;
+ if (rf!='atad') goto ap_f;
+ data_ofs=8+4+8+wfs+4;
+ DWORD data_size=0;
+ br=0; ReadFile(hOut,&data_size,4,&br,0);
+ SetFilePointer(hOut,data_size,0,FILE_CURRENT);
+ SetEndOfFile(hOut);
+ use_convert = !!memcmp(&wfx,&ap_wfx,sizeof(wfx));
+ }
+ goto ap_ok;
+ap_f:
+ file_err(fn, WASABI_API_LNGSTRINGW(IDS_NOT_A_PCM_WAV_FILE));
+ if (hOut && hOut!=INVALID_HANDLE_VALUE) {CloseHandle(hOut);hOut=INVALID_HANDLE_VALUE;}
+ return -1;
+ap_ok:;
+ }
+
+ if (riff && !append)
+ {
+ t=rev32('RIFF');
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ SetFilePointer(hOut,4,0,FILE_CURRENT);
+ t=rev32('WAVE');
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ t=rev32('fmt ');
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ }
+
+ if (use_convert)
+ {
+#ifdef SSRC
+ if (pDst->wFormatTag==WAVE_FORMAT_PCM)
+ {
+ if ((wfx.nChannels!=1 && wfx.nChannels!=2) || (pDst->nChannels!=1 && pDst->nChannels!=2)) goto fail;
+
+ res = SSRC_create(wfx.nSamplesPerSec,pDst->nSamplesPerSec,wfx.wBitsPerSample,pDst->wBitsPerSample,wfx.nChannels,2,1,0,0,wfx.nChannels!=pDst->nChannels);
+
+ acm_outbuf=0;
+ acm_outbufsize=0;
+ }
+ else
+#endif
+ {
+ MMRESULT rs=acmStreamOpen(&hStream,0,&wfx,pDst,0,0,0,ACM_STREAMOPENF_NONREALTIME);
+ if (rs)
+ {
+ WAVEFORMATEX wfx1;
+ ZeroMemory(&wfx1,sizeof(wfx1));
+ wfx1.wFormatTag=WAVE_FORMAT_PCM;
+ if (acmFormatSuggest(0,pDst,&wfx1,sizeof(WAVEFORMATEX),ACM_FORMATSUGGESTF_WFORMATTAG)) goto fail;
+ if (acmStreamOpen(&hStream,0,&wfx1,pDst,0,0,0,ACM_STREAMOPENF_NONREALTIME)) goto fail;
+
+ if ((wfx.nChannels!=1 && wfx.nChannels!=2) || (wfx1.nChannels!=1 && wfx1.nChannels!=2)) goto fail;
+#ifdef SSRC
+ res = SSRC_create(wfx.nSamplesPerSec,wfx1.nSamplesPerSec,wfx.wBitsPerSample,wfx1.wBitsPerSample,wfx.nChannels,2,1,0,0,wfx.nChannels!=wfx1.nChannels);
+ //TODO fix different channel setups
+#endif
+ acm_buf1=(BYTE*)malloc(BUFSIZE);
+
+ if (!acm_buf1
+#ifdef SSRC
+ || !res
+#endif
+ )
+ goto fail;
+ }
+ acm_buf=(BYTE*)malloc(BUFSIZE);
+ acm_outbuf=(BYTE*)malloc(BUFSIZE);
+ if (!acm_buf || !acm_outbuf) goto fail;
+ ZeroMemory(&ahd,sizeof(ahd));
+ ahd.cbStruct=sizeof(ahd);
+ ahd.pbSrc=acm_buf;
+ ahd.cbSrcLength=BUFSIZE;
+ ahd.pbDst=acm_outbuf;
+ ahd.cbDstLength=BUFSIZE;
+ if (acmStreamPrepareHeader(hStream,&ahd,0)) goto fail;
+ }
+
+ if (riff && !append)
+ {
+ if (pDst->wFormatTag==WAVE_FORMAT_PCM) t=0x10;
+ else t=sizeof(WAVEFORMATEX)+pDst->cbSize;
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ bw = 0; WriteFile(hOut,pDst,t,&bw,0);
+ FileAlign(hOut);
+
+ if (pDst->wFormatTag!=WAVE_FORMAT_PCM)
+ {
+ t=rev32('fact');
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ t=4;
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ fact_ofs=FileTell(hOut);
+ SetFilePointer(hOut,4,0,FILE_CURRENT);
+ }
+
+ t=rev32('data');
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ data_ofs=FileTell(hOut);
+ SetFilePointer(hOut,4,0,FILE_CURRENT);
+ }
+ }
+ else if (riff && !append)
+ {
+ t=0x10;
+ //t=sizeof(WAVEFORMATEX)+pDst->cbSize;
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ bw = 0; WriteFile(hOut,&wfx,t,&bw,0);
+ t=rev32('data');
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ data_ofs=FileTell(hOut);
+ SetFilePointer(hOut,4,0,FILE_CURRENT);
+ }
+ inbuf1=inbuf=0;
+
+ active=1;
+
+ pos_delta=0;
+
+ return 0;
+
+fail:
+ if (hOut && hOut!=INVALID_HANDLE_VALUE)
+ {
+ CloseHandle(hOut);
+ hOut=INVALID_HANDLE_VALUE;
+ DeleteFile(fn);
+ }
+ hOut=0;
+ acm_close();
+ MessageBoxW(mod.hMainWindow,WASABI_API_LNGSTRINGW(IDS_ERROR_INITIALIZING_OUTPUT),
+ szDescription,MB_ICONERROR);
+ return -1;
+}
+
+void acm_close()
+{
+#ifdef SSRC
+ if (res)
+ {
+ if (acm_buf1)
+ {
+ free(acm_buf1);
+ acm_buf1=0;
+ }
+ delete res;
+ res=0;
+ }
+#endif
+ if (hStream)
+ {
+ if (ahd.fdwStatus & ACMSTREAMHEADER_STATUSF_PREPARED) acmStreamUnprepareHeader(hStream,&ahd,0);
+ ZeroMemory(&ahd,sizeof(ahd));
+ acmStreamClose(hStream,0);
+ hStream=0;
+ if (acm_buf)
+ {
+ free(acm_buf);
+ acm_buf=0;
+ }
+ if (acm_outbuf)
+ {
+ free(acm_outbuf);
+ acm_outbuf=0;
+ }
+ }
+}
+
+void do_cvt(BYTE* data,UINT size);
+
+void Close()
+{
+ SYNCFUNC;
+ active=0;
+ if (use_convert)
+ {
+ do_cvt(0,0);
+ acm_close();
+ }
+ if (hOut!=INVALID_HANDLE_VALUE)
+ {
+ if (riff)
+ {
+ FileAlign(hOut);
+
+ DWORD t,bw = 0;
+ SetFilePointer(hOut,4,0,FILE_BEGIN);
+ t=GetFileSize(hOut,0)-8;
+ WriteFile(hOut,&t,4,&bw,0);
+ if (data_ofs)
+ {
+ DWORD data_size=GetFileSize(hOut,0)-(data_ofs+4);
+ SetFilePointer(hOut,data_ofs,0,FILE_BEGIN);
+ bw = 0; WriteFile(hOut,&data_size,4,&bw,0);
+ }
+ if (fact_ofs)
+ {
+ SetFilePointer(hOut,fact_ofs,0,FILE_BEGIN);
+ t=nsam;
+ bw = 0; WriteFile(hOut,&t,4,&bw,0);
+ }
+ }
+ CloseHandle(hOut);
+ hOut=INVALID_HANDLE_VALUE;
+ }
+}
+
+void do_cvt(BYTE* data,UINT size)
+{
+#ifdef SSRC
+ if (res && !hStream)
+ {
+ if (!data || !size) res->Finish();
+ else res->Write(data,size);
+
+ UINT out_size;
+ void *out = res->GetBuffer(&out_size);
+ DWORD bw = 0;
+ WriteFile(hOut,out,out_size,&bw,0);
+ res->Read(out_size);
+
+ }
+ else
+#endif
+ {
+ DWORD flags=0;
+ if (nsam==0) flags|=ACM_STREAMCONVERTF_START;
+ if (data) flags|=ACM_STREAMCONVERTF_BLOCKALIGN;
+#ifdef SSRC
+ if (res)
+ {
+ if (inbuf1+size>BUFSIZE) return;
+ if (data)
+ {
+ memcpy(acm_buf1+inbuf1,data,size);
+ inbuf1+=size;
+ }
+ res->Write(acm_buf1,inbuf1);
+ memcpy(acm_buf1,acm_buf1+inbuf1,inbuf1);
+ inbuf1=0;
+ if (!data || !size) res->Finish();
+ data = (BYTE*)res->GetBuffer(&size);
+ if (inbuf+size>BUFSIZE) return;
+ memcpy(acm_buf+inbuf,data,size);
+ inbuf+=size;
+ res->Read(size);
+ }
+ else
+#endif
+ if (data)
+ {
+ if (inbuf+size>BUFSIZE) return;
+ memcpy(acm_buf+inbuf,data,size);
+ inbuf+=size;
+ }
+
+ ahd.cbSrcLength=inbuf;
+ acmStreamConvert(hStream,&ahd,flags);
+ inbuf-=ahd.cbSrcLengthUsed;
+ memmove(acm_buf,acm_buf+ahd.cbSrcLengthUsed,inbuf);//memmove
+ DWORD bw = 0;
+ WriteFile(hOut,acm_outbuf,ahd.cbDstLengthUsed,&bw,0);
+ }
+}
+
+int Write(char *data, int len)
+{
+ SYNCFUNC;
+ if (!active) return 0;
+ if (cfg_thread_override) SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);
+ else Sleep(0);
+
+ len-=len%((g_bps>>3)*g_nch);
+
+ nsam+=len/((g_bps>>3)*g_nch);
+
+ if (use_convert)
+ {
+ do_cvt((BYTE*)data,len);
+ }
+ else
+ {
+ DWORD bw = 0;
+ WriteFile(hOut,data,len,&bw,0);
+ }
+
+
+ return 0;
+}
+
+int DoAboutMessageBox(HWND parent, wchar_t* title, wchar_t* message)
+{
+ MSGBOXPARAMSW msgbx = {sizeof(MSGBOXPARAMSW),0};
+ msgbx.lpszText = message;
+ msgbx.lpszCaption = title;
+ msgbx.lpszIcon = MAKEINTRESOURCEW(102);
+ msgbx.hInstance = GetModuleHandle(0);
+ msgbx.dwStyle = MB_USERICON;
+ msgbx.hwndOwner = parent;
+ return MessageBoxIndirectW(&msgbx);
+}
+
+void About(HWND hwndParent)
+{
+ wchar_t message[1024] = {0}, text[1024] = {0};
+ WASABI_API_LNGSTRINGW_BUF(IDS_NULLSOFT_DISK_WRITER_OLD,text,1024);
+ StringCchPrintfW(message, 1024, WASABI_API_LNGSTRINGW(IDS_ABOUT_TEXT),
+ szDescription, __DATE__);
+ DoAboutMessageBox(hwndParent,text,message);
+}
+
+static bool _cfg_store;
+static const char *inifile;
+
+#define CFG_NAME "out_disk"//fixme
+
+static void wppi(char* nam,UINT val)
+{
+ char t[16] = {0};
+ StringCchPrintf(t,16, "%u",val);
+ WritePrivateProfileString(CFG_NAME,nam,t,inifile);
+}
+
+#define WritePrivateProfileInt(A,B,C,D) wppi(B,C)
+
+static int _do_int(int x,char* nam)
+{
+ if (_cfg_store)
+ {
+ WritePrivateProfileInt(CFG_NAME,nam,x,inifile);
+ return x;
+ }
+ else
+ {
+ return GetPrivateProfileInt(CFG_NAME,nam,x,inifile);
+ }
+}
+
+#define do_int(x) x=_do_int(x,#x)
+#define do_bool(x) x=!!_do_int(x,#x)
+
+static void _do_string(char* x,char* nam)
+{
+ if (_cfg_store)
+ {
+ WritePrivateProfileString(CFG_NAME,nam,x,inifile);
+ }
+ else
+ {
+ GetPrivateProfileString(CFG_NAME,nam,x,x,MAX_PATH,inifile);
+ }
+}
+
+#define do_string(x) _do_string(x,#x)
+
+void do_cfg()
+{
+ if (!_cfg_store)
+ {
+ GetDefaultSaveToFolder(cfg_output_dir);
+ PathCombine(cfg_singlefile_output, cfg_output_dir, "output.wav");
+ }
+
+ do_string(cfg_output_dir);
+ do_string(cfg_singlefile_output);
+ do_bool(cfg_singlefile_enabled);
+ do_bool(cfg_convert_enabled);
+ do_bool(cfg_thread_override);
+ do_int(cfg_output_mode);
+ do_bool(cfg_output_source_dir);
+ do_bool(cfg_show_saveas);
+ do_int(cfg_format_mode);
+ do_int(cfg_format_index);
+
+
+ if (_cfg_store)
+ {
+ UINT _s=sizeof(WAVEFORMATEX)+convert_wfx.wfx.cbSize;
+ WritePrivateProfileInt(CFG_NAME,"cfg_wfx_s",_s,inifile);
+ WritePrivateProfileStruct(CFG_NAME,"cfg_wfx",&convert_wfx,_s,inifile);
+ WritePrivateProfileStruct(CFG_NAME,"cfg_wfx1",&singlefile_wfx,sizeof(singlefile_wfx),inifile);
+ }
+ else
+ {
+ UINT _s=GetPrivateProfileInt(CFG_NAME,"cfg_wfx_s",0,inifile);
+ if (_s && _s<=sizeof(convert_wfx))
+ {
+ GetPrivateProfileStruct(CFG_NAME,"cfg_wfx",&convert_wfx,_s,inifile);
+ }
+ GetPrivateProfileStruct(CFG_NAME,"cfg_wfx1",&singlefile_wfx,sizeof(singlefile_wfx),inifile);
+ }
+}
+
+void Init()
+{
+ SYNCFUNC;
+ if (!mod.hMainWindow)
+ return;
+ inifile = (const char *)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GETINIFILE);
+ singlefile_wfx = wfx_default;
+ convert_wfx.wfx = wfx_default;
+ memset(convert_wfx.crap, 0, sizeof(convert_wfx.crap));
+
+ // loader so that we can get the localisation service api for use
+ WASABI_API_SVC = (api_service*)SendMessage(mod.hMainWindow, WM_WA_IPC, 0, IPC_GET_API_SERVICE);
+ if (WASABI_API_SVC == (api_service*)1) WASABI_API_SVC = NULL;
+
+ waServiceFactory *sf = WASABI_API_SVC->service_getServiceByGuid(languageApiGUID);
+ if (sf) WASABI_API_LNG = reinterpret_cast<api_language*>(sf->getInterface());
+
+ // need to have this initialised before we try to do anything with localisation features
+ WASABI_API_START_LANG(mod.hDllInstance,OutDiskLangGUID);
+
+ StringCchPrintfW(szDescription, 256, WASABI_API_LNGSTRINGW(IDS_NULLSOFT_DISK_WRITER), PLUGIN_VERSION);
+ mod.description = (char*)szDescription;
+
+ _cfg_store=0;
+ do_cfg();
+}
+
+void Quit()
+{
+ SYNCFUNC;
+ if (active) Close();
+
+ _cfg_store=1;
+ do_cfg();
+}
+
+int CanWrite()
+{
+ return paused ? 0 : 666666666;
+}
+
+int IsPlaying()
+{
+ return 0;
+}
+
+int Pause(int p)
+{
+ int _p=paused;
+ paused=p;
+ return _p;
+}
+
+void SetVolume(int volume)
+{
+}
+
+void SetPan(int pan)
+{
+}
+
+void Flush(int t)
+{
+ nsam=0;
+ pos_delta=t;
+}
+
+int GetOutputTime()
+{
+ return pos_delta+MulDiv(nsam,1000,g_freq);
+}
+
+Out_Module mod=
+{
+ OUT_VER_U,
+ 0,
+ 426119909,
+ 0,
+ 0,
+ Config,
+ About,
+ Init,
+ Quit,
+ Open,
+ Close,
+ Write,
+ CanWrite,
+ IsPlaying,
+ Pause,
+ SetVolume,
+ SetVolume,
+ Flush,
+ GetOutputTime,
+ GetOutputTime
+};
+
+extern "C"
+{
+ __declspec( dllexport ) Out_Module * winampGetOutModule()
+ {
+ return &mod;
+ }
+}
+
+BOOL APIENTRY DllMain(HANDLE hMod,DWORD r,void*)
+{
+ if (r==DLL_PROCESS_ATTACH)
+ {
+ DisableThreadLibraryCalls((HMODULE)hMod);
+ }
+ return TRUE;
+} \ No newline at end of file
diff --git a/Src/Plugins/Output/out_disk/out_disk.h b/Src/Plugins/Output/out_disk/out_disk.h
new file mode 100644
index 00000000..5e01604f
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/out_disk.h
@@ -0,0 +1,18 @@
+#include "../Winamp/out.h"
+#include "resource.h"
+extern Out_Module mod;
+
+#include "../Agave/Language/api_language.h"
+#include <api/service/waServiceFactory.h>
+
+#define PLUGIN_VERSION L"2.18"
+
+inline void * z_malloc(UINT x)
+{
+ void * p=malloc(x);
+ if (p) memset(p,0,x);
+ return p;
+}
+#if 0
+#include "ssrc/ssrc.h"
+#endif \ No newline at end of file
diff --git a/Src/Plugins/Output/out_disk/out_disk.rc b/Src/Plugins/Output/out_disk/out_disk.rc
new file mode 100644
index 00000000..f90336b6
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/out_disk.rc
@@ -0,0 +1,184 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// Polish resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_PLK)
+#ifdef _WIN32
+LANGUAGE LANG_POLISH, SUBLANG_DEFAULT
+#pragma code_page(1250)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "#include ""version.rc2""\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+#endif // Polish resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_DIALOG1 DIALOGEX 0, 0, 388, 170
+STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
+FONT 8, "MS Shell Dlg", 0, 0, 0x0
+BEGIN
+ GROUPBOX "Output File Location",IDC_OUTPUT_STATIC,4,4,185,126
+ LTEXT "Directory:",IDC_OUTPUT_DIRECTORY_STATIC,11,20,31,8
+ PUSHBUTTON "",IDC_OUTPUT_DIRECTORY,45,18,137,13
+ CONTROL "Output to directory containing source files",IDC_OUTPUT_SRCDIR,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,39,151,10
+ CONTROL "Display ""save as"" dialog for every file",IDC_FILENAME_SAVEAS,
+ "Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,52,135,10
+ LTEXT "Playlist index at the beginning:",IDC_FILENAME_INDEX_STATIC,11,70,99,8
+ COMBOBOX IDC_FILENAME_INDEX,11,82,172,92,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ LTEXT "Output Filename Format:",IDC_FILENAME_FORMAT_STATIC,11,101,81,8
+ COMBOBOX IDC_FILENAME_FORMAT,11,111,172,94,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Output File Type",IDC_OUTMODE_STATIC,4,134,185,32
+ COMBOBOX IDC_OUTMODE,11,147,172,80,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
+ GROUPBOX "Single-File Mode",IDC_STATIC,194,4,188,61
+ CONTROL "Enabled",IDC_SINGLEFILE_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,17,41,10
+ LTEXT "File:",IDC_SINGLEFILE_FILE_STATIC,211,32,14,8
+ PUSHBUTTON "",IDC_SINGLEFILE_FILE_BUTTON,227,29,148,13
+ LTEXT "Format:",IDC_SINGLEFILE_FORMAT_STATIC,201,48,24,8
+ PUSHBUTTON "",IDC_SINGLEFILE_FORMAT_BUTTON,227,46,148,13
+ GROUPBOX "Conversion",IDC_CONVERT_STATIC,194,69,188,67
+ CONTROL "Convert to format:",IDC_CONVERT_CHECK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,201,81,77,10
+ PUSHBUTTON "",IDC_CONVERT_BUTTON,200,93,175,21,BS_MULTILINE
+ LTEXT "Note: some output formats will produce an error message",IDC_CONVERT_NOTE,199,115,178,17,SS_CENTERIMAGE | WS_DISABLED
+ CONTROL "Override thread priority (hack)",IDC_THREAD_HACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,194,140,114,10
+ DEFPUSHBUTTON "OK",IDOK,280,153,50,13
+ PUSHBUTTON "Cancel",IDCANCEL,334,153,50,13
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO
+BEGIN
+ IDD_DIALOG1, DIALOG
+ BEGIN
+ LEFTMARGIN, 4
+ RIGHTMARGIN, 384
+ TOPMARGIN, 4
+ BOTTOMMARGIN, 166
+ END
+END
+#endif // APSTUDIO_INVOKED
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.K.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
+#pragma code_page(1252)
+#endif //_WIN32
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_DISK_WRITER "Nullsoft Disk Writer v%s"
+ 65535 "{1A710E67-5180-49ac-8102-105856ED0A2F}"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NULLSOFT_DISK_WRITER_OLD "Nullsoft Disk Writer"
+ IDS_AUTO_RECOMMENDED "Auto (recommended)"
+ IDS_FORCE_WAV_FILE "Force WAV file"
+ IDS_FORCE_RAW_DATA "Force raw data"
+ IDS_DISABLED "disabled"
+ IDS_1_DIGIT "1 digit"
+ IDS_2_DIGITS "2 digits"
+ IDS_3_DIGITS "3 digits"
+ IDS_4_DIGITS "4 digits"
+ IDS_SELECT_OUTPUT_DIRECTORY "Select output directory"
+ IDS_CHOOSE_FILE_NAME "%s - Choose File Name"
+ IDS_X_FILES_DOT_X "%s files|*%s|"
+ IDS_FILE_ALREADY_EXISTS_OVERWRITE
+ "File: ""%hs"" already exists. Overwrite?"
+ IDS_CANNOT_CREATE_OUTPUT_FILE "Cannot create output file"
+ IDS_CANNOT_OPEN_FILE "Cannot open file"
+END
+
+STRINGTABLE
+BEGIN
+ IDS_NOT_A_PCM_WAV_FILE "Not a PCM WAV file"
+ IDS_ERROR_INITIALIZING_OUTPUT "Error initializing output."
+ IDS_ABOUT_TEXT "%s\n© 2005-2023 Winamp SA\n© 2001-2002 Peter Pawlowski\nBuild date: %hs"
+ IDS_SETTINGS_TITLE "%s Settings"
+END
+
+#endif // English (U.K.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+#include "version.rc2"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff --git a/Src/Plugins/Output/out_disk/out_disk.sln b/Src/Plugins/Output/out_disk/out_disk.sln
new file mode 100644
index 00000000..4e218035
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/out_disk.sln
@@ -0,0 +1,30 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.29424.173
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "out_disk", "out_disk.vcxproj", "{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Win32 = Debug|Win32
+ Debug|x64 = Debug|x64
+ Release|Win32 = Release|Win32
+ Release|x64 = Release|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|Win32.ActiveCfg = Debug|Win32
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|Win32.Build.0 = Debug|Win32
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|x64.ActiveCfg = Debug|x64
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Debug|x64.Build.0 = Debug|x64
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|Win32.ActiveCfg = Release|Win32
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|Win32.Build.0 = Release|Win32
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|x64.ActiveCfg = Release|x64
+ {D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}.Release|x64.Build.0 = Release|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {14A951ED-3F6F-4E8C-97C7-53A443DB461F}
+ EndGlobalSection
+EndGlobal
diff --git a/Src/Plugins/Output/out_disk/out_disk.vcxproj b/Src/Plugins/Output/out_disk/out_disk.vcxproj
new file mode 100644
index 00000000..89e93029
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/out_disk.vcxproj
@@ -0,0 +1,301 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{D9A8D79B-2035-45F0-BAA7-CCF9F8D18A83}</ProjectGuid>
+ <RootNamespace>out_disk</RootNamespace>
+ <WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>DynamicLibrary</ConfigurationType>
+ <PlatformToolset>v142</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ <IncludePath>$(IncludePath)</IncludePath>
+ <LibraryPath>$(LibraryPath)</LibraryPath>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
+ <IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg">
+ <VcpkgEnableManifest>false</VcpkgEnableManifest>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ <VcpkgConfiguration>Debug</VcpkgConfiguration>
+ </PropertyGroup>
+ <PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <VcpkgInstalledDir>
+ </VcpkgInstalledDir>
+ <VcpkgUseStatic>false</VcpkgUseStatic>
+ <VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <Optimization>Disabled</Optimization>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <MinimalRebuild>false</MinimalRebuild>
+ <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <DelayLoadDLLs>msacm32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
+xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>msacm32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <TargetMachine>MachineX86</TargetMachine>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <Optimization>MinSpace</Optimization>
+ <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+ <FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
+ <AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ <PreprocessorDefinitions>WIN64;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <StringPooling>true</StringPooling>
+ <MultiProcessorCompilation>true</MultiProcessorCompilation>
+ <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+ <BufferSecurityCheck>true</BufferSecurityCheck>
+ <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+ <ObjectFileName>$(IntDir)</ObjectFileName>
+ <ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
+ <WarningLevel>Level3</WarningLevel>
+ <DebugInformationFormat>None</DebugInformationFormat>
+ </ClCompile>
+ <ResourceCompile>
+ <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <Culture>0x0415</Culture>
+ </ResourceCompile>
+ <Link>
+ <AdditionalDependencies>msacm32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ <OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
+ <DelayLoadDLLs>msacm32.dll;%(DelayLoadDLLs)</DelayLoadDLLs>
+ <GenerateDebugInformation>false</GenerateDebugInformation>
+ <ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
+ <SubSystem>Windows</SubSystem>
+ <OptimizeReferences>true</OptimizeReferences>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <RandomizedBaseAddress>false</RandomizedBaseAddress>
+ <ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
+ <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
+ <AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
+ </Link>
+ <PostBuildEvent>
+ <Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
+ <Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
+ </PostBuildEvent>
+ </ItemDefinitionGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">_DEBUG;WIN32;_WINDOWS</PreprocessorDefinitions>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">NDEBUG;WIN32;_WINDOWS</PreprocessorDefinitions>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Disabled</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">_DEBUG;WIN64;_WINDOWS</PreprocessorDefinitions>
+ <Optimization Condition="'$(Configuration)|$(Platform)'=='Release|x64'">MinSpace</Optimization>
+ <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">NDEBUG;WIN64;_WINDOWS</PreprocessorDefinitions>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="out_disk.h" />
+ <ClInclude Include="resource.h" />
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="out_disk.rc" />
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="readme.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
+ <Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Output/out_disk/out_disk.vcxproj.filters b/Src/Plugins/Output/out_disk/out_disk.vcxproj.filters
new file mode 100644
index 00000000..3e18db05
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/out_disk.vcxproj.filters
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <ClInclude Include="out_disk.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ <ClInclude Include="resource.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+ <ItemGroup>
+ <Text Include="readme.txt" />
+ </ItemGroup>
+ <ItemGroup>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{3d730b77-a765-46b3-80a4-893d8ed28bca}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Ressource Files">
+ <UniqueIdentifier>{4e1c8c55-ef16-46e4-94a9-fbd4c5a74f0c}</UniqueIdentifier>
+ </Filter>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{8b744104-8938-49fc-ad58-e58f93746183}</UniqueIdentifier>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ResourceCompile Include="out_disk.rc">
+ <Filter>Ressource Files</Filter>
+ </ResourceCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+</Project> \ No newline at end of file
diff --git a/Src/Plugins/Output/out_disk/resource.h b/Src/Plugins/Output/out_disk/resource.h
new file mode 100644
index 00000000..adfaa478
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/resource.h
@@ -0,0 +1,80 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by acm.rc
+//
+#define IDS_NULLSOFT_DISK_WRITER_OLD 0
+#define IDS_AUTO_RECOMMENDED 1
+#define IDS_FORCE_WAV_FILE 2
+#define IDC_RTFM 3
+#define IDS_FORCE_RAW_DATA 3
+#define IDS_DISABLED 4
+#define IDS_1_DIGIT 5
+#define IDS_2_DIGITS 6
+#define IDS_3_DIGITS 7
+#define IDS_4_DIGITS 8
+#define IDS_CONFIGURATION_TITLE 9
+#define IDS_SELECT_OUTPUT_DIRECTORY 10
+#define IDS_CHOOSE_FILE_NAME 11
+#define IDS_X_FILES_DOT_X 12
+#define IDS_FILE_ALREADY_EXISTS_OVERWRITE 13
+#define IDS_CANNOT_CREATE_OUTPUT_FILE 14
+#define IDS_CANNOT_OPEN_FILE 15
+#define IDS_NOT_A_PCM_WAV_FILE 16
+#define IDS_ERROR_INITIALIZING_OUTPUT 17
+#define IDS_ABOUT 18
+#define IDS_STRING19 19
+#define IDS_ABOUT_STRING 20
+#define IDS_ABOUT_TEXT 20
+#define IDS_SETTINGS_TITLE 21
+#define IDD_DIALOG1 101
+#define IDR_README 103
+#define IDD_RTFM 109
+#define IDC_DIR 1000
+#define IDC_OUTPUT_DIRECTORY 1000
+#define IDC_CONVERT 1001
+#define IDC_CONVERT_CHECK 1001
+#define IDC_FORMAT 1002
+#define IDC_CONVERT_BUTTON 1002
+#define IDC_FMT_NAME 1005
+#define IDC_WAV1 1010
+#define IDC_SINGLEFILE_CHECK 1010
+#define IDC_WAV1E 1011
+#define IDC_WAV1B 1012
+#define IDC_SINGLEFILE_FILE_BUTTON 1012
+#define IDC_WAV1F 1013
+#define IDC_SINGLEFILE_FORMAT_BUTTON 1013
+#define IDC_STATIC1 1014
+#define IDC_STATIC2 1015
+#define IDC_SINGLEFILE_FILE_STATIC 1015
+#define IDC_STATIC3 1016
+#define IDC_SINGLEFILE_FORMAT_STATIC 1016
+#define IDC_STATIC4 1018
+#define IDC_MODE 1019
+#define IDC_OUTMODE 1019
+#define IDC_THREAD_HACK 1020
+#define IDC_FMTBLAH 1021
+#define IDC_CONVERT_NOTE 1021
+#define IDC_STARTHACK 1022
+#define IDC_OUTPUT_SRCDIR 1023
+#define IDC_CONVERT_STATIC 1024
+#define IDC_OUTPUT_STATIC 1025
+#define IDC_OUTMODE_STATIC 1026
+#define IDC_FILENAME_INDEX_STATIC 1028
+#define IDC_FILENAME_INDEX 1031
+#define IDC_FILENAME_SAVEAS 1033
+#define IDC_OUTPUT_DIRECTORY_STATIC 1034
+#define IDC_FILENAME_FORMAT_STATIC 1035
+#define IDC_FILENAME_FORMAT 1036
+#define IDC_EDIT1 1066
+#define IDS_NULLSOFT_DISK_WRITER 65534
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 108
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1037
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif
diff --git a/Src/Plugins/Output/out_disk/version.rc2 b/Src/Plugins/Output/out_disk/version.rc2
new file mode 100644
index 00000000..55f35d39
--- /dev/null
+++ b/Src/Plugins/Output/out_disk/version.rc2
@@ -0,0 +1,39 @@
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+#include "../../../Winamp/buildType.h"
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 2,18,0,0
+ PRODUCTVERSION WINAMP_PRODUCTVER
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "CompanyName", "Winamp SA"
+ VALUE "FileDescription", "Winamp Output Plug-in"
+ VALUE "FileVersion", "2,18,0,0"
+ VALUE "InternalName", "Nullsoft Disk Writer"
+ VALUE "LegalCopyright", "Copyright © 2005-2023 Winamp SA"
+ VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
+ VALUE "OriginalFilename", "out_disk.dll"
+ VALUE "ProductName", "Winamp"
+ VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END