mirror of
https://github.com/WinampDesktop/winamp.git
synced 2025-06-17 10:15:47 -04:00
Initial community commit
This commit is contained in:
53
Src/Plugins/Library/ml_rg/Process.cpp
Normal file
53
Src/Plugins/Library/ml_rg/Process.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
#include "main.h"
|
||||
#include "Process.h"
|
||||
|
||||
int ProcessReplayGain::Open(int _mode)
|
||||
{
|
||||
mode=_mode;
|
||||
if (mode != RG_INDIVIDUAL_TRACKS
|
||||
&& mode != RG_ALBUM)
|
||||
return RG_MODE_NOT_SUPPORTED;
|
||||
context=CreateRG();
|
||||
if (!context)
|
||||
return RG_FAILURE;
|
||||
|
||||
StartRG(context);
|
||||
return RG_SUCCESS;
|
||||
}
|
||||
|
||||
int ProcessReplayGain::ProcessTrack(const wchar_t *filename)
|
||||
{
|
||||
int killSwitch=0;
|
||||
RGWorkFile workFile(filename);
|
||||
|
||||
CalculateRG(context, workFile.filename, workFile.track_gain, workFile.track_peak, 0, &killSwitch, albumPeak);
|
||||
queue.push_back(workFile);
|
||||
|
||||
return RG_SUCCESS;
|
||||
}
|
||||
|
||||
int ProcessReplayGain::Write()
|
||||
{
|
||||
if (mode == RG_ALBUM)
|
||||
{
|
||||
wchar_t album_gain[64]=L"", album_peak[64]=L"";
|
||||
CalculateAlbumRG(context, album_gain, album_peak, albumPeak);
|
||||
CopyAlbumData(queue, album_gain, album_peak);
|
||||
}
|
||||
WriteAlbum(queue);
|
||||
|
||||
return RG_SUCCESS;
|
||||
}
|
||||
|
||||
void ProcessReplayGain::Close()
|
||||
{
|
||||
DestroyRG(context);
|
||||
}
|
||||
|
||||
#define CBCLASS ProcessReplayGain
|
||||
START_DISPATCH;
|
||||
CB(OBJ_REPLAYGAIN_OPEN, Open)
|
||||
CB(OBJ_REPLAYGAIN_PROCESSTRACK, ProcessTrack)
|
||||
CB(OBJ_REPLAYGAIN_WRITE, Write)
|
||||
VCB(OBJ_REPLAYGAIN_CLOSE,Close)
|
||||
END_DISPATCH;
|
25
Src/Plugins/Library/ml_rg/Process.h
Normal file
25
Src/Plugins/Library/ml_rg/Process.h
Normal file
@ -0,0 +1,25 @@
|
||||
#ifndef NULLSOFT_ML_RG_PROCESS_H
|
||||
#define NULLSOFT_ML_RG_PROCESS_H
|
||||
|
||||
#include "obj_replaygain.h"
|
||||
|
||||
//this class is meant for use as a service
|
||||
|
||||
class ProcessReplayGain : public obj_replaygain
|
||||
{
|
||||
public:
|
||||
ProcessReplayGain() : context(0), albumPeak(0), mode(RG_INDIVIDUAL_TRACKS) {}
|
||||
int Open(int mode);
|
||||
int ProcessTrack(const wchar_t *filename);
|
||||
int Write();
|
||||
void Close();
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
void *context;
|
||||
int mode;
|
||||
float albumPeak;
|
||||
WorkQueue::RGWorkQueue queue;
|
||||
};
|
||||
|
||||
#endif
|
261
Src/Plugins/Library/ml_rg/Progress.cpp
Normal file
261
Src/Plugins/Library/ml_rg/Progress.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
#include "main.h"
|
||||
#include "resource.h"
|
||||
#include"api__ml_rg.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
struct Progress
|
||||
{
|
||||
Progress()
|
||||
{
|
||||
processedFiles = 0;
|
||||
currentBytes = 0;
|
||||
totalBytes = 0;
|
||||
activeHWND = 0;
|
||||
threadHandle = 0;
|
||||
openDialogs = 0;
|
||||
done = false;
|
||||
killSwitch = 0;
|
||||
}
|
||||
|
||||
size_t processedFiles;
|
||||
uint64_t currentBytes;
|
||||
uint32_t totalBytes;
|
||||
WorkQueue activeQueue;
|
||||
HWND activeHWND;
|
||||
HANDLE threadHandle;
|
||||
size_t openDialogs;
|
||||
bool done;
|
||||
int killSwitch;
|
||||
};
|
||||
|
||||
DWORD WINAPI ThreadProc(void *param)
|
||||
{
|
||||
Progress *progress = (Progress *)param;
|
||||
ProgressCallback callback(progress->activeHWND);
|
||||
progress->activeQueue.Calculate(&callback, &progress->killSwitch);
|
||||
PostMessage(progress->activeHWND, WM_USER + 2, 0, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void getViewport(RECT *r, HWND wnd, int full, RECT *sr)
|
||||
{
|
||||
POINT *p = NULL;
|
||||
|
||||
if (p || sr || wnd)
|
||||
{
|
||||
HMONITOR hm = NULL;
|
||||
|
||||
if (sr)
|
||||
hm = MonitorFromRect(sr, MONITOR_DEFAULTTONEAREST);
|
||||
else if (wnd)
|
||||
hm = MonitorFromWindow(wnd, MONITOR_DEFAULTTONEAREST);
|
||||
else if (p)
|
||||
hm = MonitorFromPoint(*p, MONITOR_DEFAULTTONEAREST);
|
||||
|
||||
if (hm)
|
||||
{
|
||||
MONITORINFOEXW mi;
|
||||
memset(&mi, 0, sizeof(mi));
|
||||
mi.cbSize = sizeof(mi);
|
||||
|
||||
if (GetMonitorInfoW(hm, &mi))
|
||||
{
|
||||
if (!full)
|
||||
*r = mi.rcWork;
|
||||
else
|
||||
*r = mi.rcMonitor;
|
||||
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (full)
|
||||
{ // this might be borked =)
|
||||
r->top = r->left = 0;
|
||||
r->right = GetSystemMetrics(SM_CXSCREEN);
|
||||
r->bottom = GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
else
|
||||
{
|
||||
SystemParametersInfoW(SPI_GETWORKAREA, 0, r, 0);
|
||||
}
|
||||
}
|
||||
|
||||
BOOL windowOffScreen(HWND hwnd, POINT pt)
|
||||
{
|
||||
RECT r = {0}, wnd = {0}, sr = {0};
|
||||
GetWindowRect(hwnd, &wnd);
|
||||
sr.left = pt.x;
|
||||
sr.top = pt.y;
|
||||
sr.right = sr.left + (wnd.right - wnd.left);
|
||||
sr.bottom = sr.top + (wnd.bottom - wnd.top);
|
||||
getViewport(&r, hwnd, 0, &sr);
|
||||
return !PtInRect(&r, pt);
|
||||
}
|
||||
|
||||
void SaveWindowPos(HWND hwnd)
|
||||
{
|
||||
RECT rect = {0};
|
||||
GetWindowRect(hwnd, &rect);
|
||||
char buf[16] = {0};
|
||||
StringCchPrintfA(buf, 16, "%d", rect.left);
|
||||
WritePrivateProfileStringA("ml_rg", "prog_x", buf, iniFile);
|
||||
StringCchPrintfA(buf, 16, "%d", rect.top);
|
||||
WritePrivateProfileStringA("ml_rg", "prog_y", buf, iniFile);
|
||||
}
|
||||
|
||||
INT_PTR WINAPI ReplayGainProgressProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
Progress *progress = (Progress *)lParam;
|
||||
progress->killSwitch = 0;
|
||||
progress->done = false;
|
||||
progress->openDialogs = 0;
|
||||
progress->processedFiles = 0;
|
||||
progress->activeHWND = hwndDlg;
|
||||
|
||||
wchar_t dummy[64] = {0};
|
||||
StringCchPrintfW(dummy, 64, WASABI_API_LNGSTRINGW(IDS_1_OF_X_FILES), progress->activeQueue.totalFiles);
|
||||
SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, dummy);
|
||||
|
||||
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, (LONG_PTR)progress);
|
||||
DWORD threadId;
|
||||
progress->threadHandle = CreateThread(NULL, 0, ThreadProc, (void *)progress, CREATE_SUSPENDED, &threadId);
|
||||
SetThreadPriority(progress->threadHandle, THREAD_PRIORITY_IDLE);
|
||||
ResumeThread(progress->threadHandle);
|
||||
|
||||
POINT pt = {(LONG)GetPrivateProfileIntA("ml_rg", "prog_x", -1, iniFile),
|
||||
(LONG)GetPrivateProfileIntA("ml_rg", "prog_y", -1, iniFile)};
|
||||
if (!windowOffScreen(hwndDlg, pt))
|
||||
SetWindowPos(hwndDlg, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
|
||||
else
|
||||
ShowWindow(hwndDlg, SW_SHOW);
|
||||
}
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
SaveWindowPos(hwndDlg);
|
||||
Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
CloseHandle(progress->threadHandle);
|
||||
progress->activeHWND = 0;
|
||||
delete progress;
|
||||
}
|
||||
break;
|
||||
case WM_USER: // file finished
|
||||
{
|
||||
Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
progress->processedFiles++;
|
||||
|
||||
if (progress->processedFiles + 1 > progress->activeQueue.totalFiles)
|
||||
SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, WASABI_API_LNGSTRINGW(IDS_FINISHED));
|
||||
else
|
||||
{
|
||||
wchar_t dummy[64] = {0};
|
||||
StringCchPrintfW(dummy, 64,
|
||||
WASABI_API_LNGSTRINGW(IDS_X_OF_X_FILES),
|
||||
progress->processedFiles + 1, progress->activeQueue.totalFiles);
|
||||
SetDlgItemTextW(hwndDlg, IDC_PROGRESS_FILES, dummy);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_USER + 1: // album done
|
||||
{
|
||||
Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
WorkQueue::RGWorkQueue *queue = (WorkQueue::RGWorkQueue *)lParam;
|
||||
SaveWindowPos(hwndDlg);
|
||||
if (config_ask && config_ask_each_album)
|
||||
{
|
||||
progress->openDialogs++;
|
||||
DoResults(*queue);
|
||||
progress->openDialogs--;
|
||||
if (!progress->openDialogs && progress->done)
|
||||
DestroyWindow(hwndDlg);
|
||||
}
|
||||
else if (config_ask == 0)
|
||||
{
|
||||
WriteAlbum(*queue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_USER + 2: // all tracks done
|
||||
{
|
||||
Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
ShowWindow(hwndDlg, SW_HIDE);
|
||||
SaveWindowPos(hwndDlg);
|
||||
if (config_ask && config_ask_each_album == 0)
|
||||
{
|
||||
DoResults(progress->activeQueue);
|
||||
}
|
||||
progress->killSwitch = 1;
|
||||
WaitForSingleObject(progress->threadHandle, INFINITE);
|
||||
progress->done = true;
|
||||
if (!progress->openDialogs)
|
||||
DestroyWindow(hwndDlg);
|
||||
}
|
||||
break;
|
||||
case WM_USER + 3: // total bytes of current file
|
||||
{
|
||||
Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
progress->currentBytes = 0;
|
||||
progress->totalBytes = (uint32_t)lParam;
|
||||
if (progress->totalBytes == 0)
|
||||
{
|
||||
SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, WASABI_API_LNGSTRINGW(IDS_PROCESSING));
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t dummy[64] = {0};
|
||||
StringCchPrintfW(dummy, 64, L"%u%%", (progress->currentBytes * 100) / progress->totalBytes);
|
||||
SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, dummy);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_USER + 4: // more bytes read
|
||||
{
|
||||
Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
progress->currentBytes += lParam;
|
||||
if (progress->totalBytes == 0)
|
||||
{
|
||||
SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, WASABI_API_LNGSTRINGW(IDS_PROCESSING));
|
||||
}
|
||||
else
|
||||
{
|
||||
wchar_t dummy[64] = {0};
|
||||
StringCchPrintfW(dummy, 64, L"%u%%", (progress->currentBytes * 100) / progress->totalBytes);
|
||||
SetDlgItemTextW(hwndDlg, IDC_FILE_PROGRESS, dummy);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
{
|
||||
Progress *progress = (Progress *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
progress->killSwitch = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DoProgress(WorkQueue &workQueue)
|
||||
{
|
||||
Progress *progress = new Progress;
|
||||
progress->activeQueue = workQueue; // this is a huge slow copy, but I don't care at the moment
|
||||
WASABI_API_CREATEDIALOGPARAMW(IDD_PROGRESS, GetDialogBoxParent(), ReplayGainProgressProc, (LPARAM)progress);
|
||||
}
|
||||
|
||||
HWND GetDialogBoxParent()
|
||||
{
|
||||
HWND parent = (HWND)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETDIALOGBOXPARENT);
|
||||
if (!parent || parent == (HWND)1)
|
||||
return plugin.hwndWinampParent;
|
||||
return parent;
|
||||
}
|
67
Src/Plugins/Library/ml_rg/RGFactory.cpp
Normal file
67
Src/Plugins/Library/ml_rg/RGFactory.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
#include "main.h"
|
||||
#include "RGFactory.h"
|
||||
#include "Process.h"
|
||||
static const char serviceName[] = "Replay Gain Processor";
|
||||
|
||||
FOURCC RGFactory::GetServiceType()
|
||||
{
|
||||
return WaSvc::OBJECT;
|
||||
}
|
||||
|
||||
const char *RGFactory::GetServiceName()
|
||||
{
|
||||
return serviceName;
|
||||
}
|
||||
|
||||
GUID RGFactory::GetGUID()
|
||||
{
|
||||
return RGGUID;
|
||||
}
|
||||
|
||||
void *RGFactory::GetInterface(int global_lock)
|
||||
{
|
||||
obj_replaygain *ifc=new ProcessReplayGain;
|
||||
// if (global_lock)
|
||||
// plugin.service->service_lock(this, (void *)ifc);
|
||||
return ifc;
|
||||
}
|
||||
|
||||
int RGFactory::SupportNonLockingInterface()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
int RGFactory::ReleaseInterface(void *ifc)
|
||||
{
|
||||
//plugin.service->service_unlock(ifc);
|
||||
obj_replaygain *api_ = static_cast<obj_replaygain *>(ifc);
|
||||
ProcessReplayGain *svc_ = static_cast<ProcessReplayGain *>(api_);
|
||||
delete svc_;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const char *RGFactory::GetTestString()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int RGFactory::ServiceNotify(int msg, int param1, int param2)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CBCLASS
|
||||
#undef CBCLASS
|
||||
#endif
|
||||
|
||||
#define CBCLASS RGFactory
|
||||
START_DISPATCH;
|
||||
CB(WASERVICEFACTORY_GETSERVICETYPE, GetServiceType)
|
||||
CB(WASERVICEFACTORY_GETSERVICENAME, GetServiceName)
|
||||
CB(WASERVICEFACTORY_GETGUID, GetGUID)
|
||||
CB(WASERVICEFACTORY_GETINTERFACE, GetInterface)
|
||||
CB(WASERVICEFACTORY_SUPPORTNONLOCKINGGETINTERFACE, SupportNonLockingInterface)
|
||||
CB(WASERVICEFACTORY_RELEASEINTERFACE, ReleaseInterface)
|
||||
CB(WASERVICEFACTORY_GETTESTSTRING, GetTestString)
|
||||
CB(WASERVICEFACTORY_SERVICENOTIFY, ServiceNotify)
|
||||
END_DISPATCH;
|
24
Src/Plugins/Library/ml_rg/RGFactory.h
Normal file
24
Src/Plugins/Library/ml_rg/RGFactory.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef NULLSOFT_RG_FACTORY_H
|
||||
#define NULLSOFT_RG_FACTORY_H
|
||||
|
||||
#include <api/service/waservicefactory.h>
|
||||
#include <api/service/services.h>
|
||||
|
||||
class RGFactory : public waServiceFactory
|
||||
{
|
||||
public:
|
||||
FOURCC GetServiceType();
|
||||
const char *GetServiceName();
|
||||
GUID GetGUID();
|
||||
void *GetInterface(int global_lock);
|
||||
int SupportNonLockingInterface();
|
||||
int ReleaseInterface(void *ifc);
|
||||
const char *GetTestString();
|
||||
int ServiceNotify(int msg, int param1, int param2);
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
172
Src/Plugins/Library/ml_rg/Results.cpp
Normal file
172
Src/Plugins/Library/ml_rg/Results.cpp
Normal file
@ -0,0 +1,172 @@
|
||||
#include "main.h"
|
||||
#include "resource.h"
|
||||
#include "../nu/listview.h"
|
||||
#include "api__ml_rg.h"
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
// this isn't nice but it localises the values for display as they're saved in "C" locale
|
||||
enum { GAIN_MODE=0, PEAK_MODE };
|
||||
wchar_t* LocaliseNumericText(wchar_t str[64], int mode){
|
||||
static wchar_t tmp[64];
|
||||
double value;
|
||||
tmp[0]=0;
|
||||
value = _wtof_l(str,WASABI_API_LNG->Get_C_NumericLocale());
|
||||
StringCchPrintfW(tmp,64,(mode==GAIN_MODE?L"%-+.2f dB":L"%-.9f"),value);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
static void AddQueueToListView(W_ListView *listView, WorkQueue::RGWorkQueue *queue)
|
||||
{
|
||||
int i=listView->GetCount();
|
||||
for(WorkQueue::RGWorkQueue::iterator itr = queue->begin(); itr!= queue->end(); itr++)
|
||||
{
|
||||
listView->InsertItem(i, PathFindFileNameW(itr->filename), (int)&*itr);
|
||||
listView->SetItemText(i, 1, LocaliseNumericText(itr->track_gain,GAIN_MODE));
|
||||
listView->SetItemText(i, 2, LocaliseNumericText(itr->track_peak,PEAK_MODE));
|
||||
listView->SetItemText(i, 3, LocaliseNumericText(itr->album_gain,GAIN_MODE));
|
||||
listView->SetItemText(i, 4, LocaliseNumericText(itr->album_peak,PEAK_MODE));
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
INT_PTR WINAPI ReplayGainDialogProc(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
W_ListView listView(GetDlgItem(hwndDlg, IDC_RGLIST));
|
||||
listView.setwnd(GetDlgItem(hwndDlg, IDC_RGLIST));
|
||||
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_FILENAME), 200);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_TRACK_GAIN), 65);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_TRACK_PEAK), 80);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_ALBUM_GAIN), 65);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_ALBUM_PEAK), 80);
|
||||
|
||||
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
|
||||
|
||||
WorkQueue::RGWorkQueue *queue = (WorkQueue::RGWorkQueue *)lParam;
|
||||
|
||||
AddQueueToListView(&listView, queue);
|
||||
|
||||
POINT pt = {(LONG)GetPrivateProfileIntA("ml_rg", "res_x", -1, iniFile),
|
||||
(LONG)GetPrivateProfileIntA("ml_rg", "res_y", -1, iniFile)};
|
||||
if (!windowOffScreen(hwndDlg, pt))
|
||||
SetWindowPos(hwndDlg, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch(LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
WorkQueue::RGWorkQueue *queue = (WorkQueue::RGWorkQueue *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
WriteAlbum(*queue);
|
||||
}
|
||||
case IDCANCEL:
|
||||
{
|
||||
RECT rect = {0};
|
||||
GetWindowRect(hwndDlg, &rect);
|
||||
char buf[16] = {0};
|
||||
StringCchPrintfA(buf, 16, "%d", rect.left);
|
||||
WritePrivateProfileStringA("ml_rg", "res_x", buf, iniFile);
|
||||
StringCchPrintfA(buf, 16, "%d", rect.top);
|
||||
WritePrivateProfileStringA("ml_rg", "res_y", buf, iniFile);
|
||||
EndDialog(hwndDlg, 0);
|
||||
}
|
||||
break;
|
||||
case IDC_SAVETRACK:
|
||||
{
|
||||
WorkQueue::RGWorkQueue *queue = (WorkQueue::RGWorkQueue *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
WriteTracks(*queue);
|
||||
EndDialog(hwndDlg, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
INT_PTR WINAPI ReplayGainDialogProcAll(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
W_ListView listView(GetDlgItem(hwndDlg, IDC_RGLIST));
|
||||
listView.setwnd(GetDlgItem(hwndDlg, IDC_RGLIST));
|
||||
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_FILENAME), 200);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_TRACK_GAIN), 65);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_TRACK_PEAK), 80);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_ALBUM_GAIN), 65);
|
||||
listView.AddCol(WASABI_API_LNGSTRINGW(IDS_COL_ALBUM_PEAK), 80);
|
||||
|
||||
SetWindowLongPtr(hwndDlg, GWLP_USERDATA, lParam);
|
||||
|
||||
WorkQueue *queue = (WorkQueue *)lParam;
|
||||
|
||||
AddQueueToListView(&listView, &queue->unclassified);
|
||||
for (WorkQueue::AlbumMap::iterator mapItr=queue->albums.begin();mapItr!=queue->albums.end();mapItr++)
|
||||
{
|
||||
AddQueueToListView(&listView, &mapItr->second);
|
||||
}
|
||||
|
||||
POINT pt = {(LONG)GetPrivateProfileIntA("ml_rg", "res_x", -1, iniFile),
|
||||
(LONG)GetPrivateProfileIntA("ml_rg", "res_y", -1, iniFile)};
|
||||
if (!windowOffScreen(hwndDlg, pt))
|
||||
SetWindowPos(hwndDlg, HWND_TOP, pt.x, pt.y, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
|
||||
}
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch(LOWORD(wParam))
|
||||
{
|
||||
case IDOK:
|
||||
{
|
||||
WorkQueue *queue = (WorkQueue *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
WriteAlbum(queue->unclassified);
|
||||
for (WorkQueue::AlbumMap::iterator mapItr=queue->albums.begin();mapItr!=queue->albums.end();mapItr++)
|
||||
{
|
||||
WriteAlbum(mapItr->second);
|
||||
}
|
||||
}
|
||||
case IDCANCEL:
|
||||
{
|
||||
RECT rect = {0};
|
||||
GetWindowRect(hwndDlg, &rect);
|
||||
char buf[16] = {0};
|
||||
StringCchPrintfA(buf, 16, "%d", rect.left);
|
||||
WritePrivateProfileStringA("ml_rg", "res_x", buf, iniFile);
|
||||
StringCchPrintfA(buf, 16, "%d", rect.top);
|
||||
WritePrivateProfileStringA("ml_rg", "res_y", buf, iniFile);
|
||||
EndDialog(hwndDlg, 0);
|
||||
}
|
||||
break;
|
||||
case IDC_SAVETRACK:
|
||||
{
|
||||
WorkQueue *queue = (WorkQueue *)GetWindowLongPtr(hwndDlg, GWLP_USERDATA);
|
||||
WriteTracks(queue->unclassified);
|
||||
for (WorkQueue::AlbumMap::iterator mapItr=queue->albums.begin();mapItr!=queue->albums.end();mapItr++)
|
||||
{
|
||||
WriteTracks(mapItr->second);
|
||||
}
|
||||
EndDialog(hwndDlg, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DoResults(WorkQueue::RGWorkQueue &queue)
|
||||
{
|
||||
if (!queue.empty())
|
||||
WASABI_API_DIALOGBOXPARAM(IDD_RESULTS, GetDialogBoxParent(), ReplayGainDialogProc, (LPARAM)&queue);
|
||||
}
|
||||
|
||||
void DoResults(WorkQueue &queue)
|
||||
{
|
||||
WASABI_API_DIALOGBOXPARAM(IDD_RESULTS, GetDialogBoxParent(), ReplayGainDialogProcAll, (LPARAM)&queue);
|
||||
}
|
24
Src/Plugins/Library/ml_rg/api__ml_rg.h
Normal file
24
Src/Plugins/Library/ml_rg/api__ml_rg.h
Normal file
@ -0,0 +1,24 @@
|
||||
#ifndef NULLSOFT_ML_RG_API_H
|
||||
#define NULLSOFT_ML_RG_API_H
|
||||
|
||||
#include "../Winamp/api_decodefile.h"
|
||||
extern api_decodefile *decodeFile;
|
||||
#define AGAVE_API_DECODE decodeFile
|
||||
|
||||
#include "api/application/api_application.h"
|
||||
extern api_application *applicationApi;
|
||||
#define WASABI_API_APP applicationApi
|
||||
|
||||
#include "../playlist/api_playlistmanager.h"
|
||||
extern api_playlistmanager *playlistManager;
|
||||
#define AGAVE_API_PLAYLISTMANAGER playlistManager
|
||||
|
||||
#include "../Agave/Language/api_language.h"
|
||||
|
||||
#include "../Winamp/api_stats.h"
|
||||
extern api_stats *statsApi;
|
||||
#define AGAVE_API_STATS statsApi
|
||||
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
#endif
|
52
Src/Plugins/Library/ml_rg/config.cpp
Normal file
52
Src/Plugins/Library/ml_rg/config.cpp
Normal file
@ -0,0 +1,52 @@
|
||||
#include "main.h"
|
||||
#include "resource.h"
|
||||
|
||||
int config_ask=1;
|
||||
int config_ask_each_album=1;
|
||||
int config_ignore_gained_album=0;
|
||||
|
||||
void DoButtons(HWND hwndDlg)
|
||||
{
|
||||
config_ask = IsDlgButtonChecked(hwndDlg, IDC_ASK);
|
||||
config_ask_each_album = IsDlgButtonChecked(hwndDlg, IDC_ALBUM);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_ALBUM), config_ask);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_ALL), config_ask);
|
||||
}
|
||||
|
||||
INT_PTR WINAPI RGConfig(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
CheckDlgButton(hwndDlg, IDC_ASK, config_ask);
|
||||
if (config_ask_each_album)
|
||||
CheckDlgButton(hwndDlg, IDC_ALBUM, BST_CHECKED);
|
||||
else
|
||||
CheckDlgButton(hwndDlg, IDC_ALL, BST_CHECKED);
|
||||
DoButtons(hwndDlg);
|
||||
break;
|
||||
case WM_DESTROY:
|
||||
{
|
||||
config_ask = IsDlgButtonChecked(hwndDlg, IDC_ASK);
|
||||
config_ask_each_album = IsDlgButtonChecked(hwndDlg, IDC_ALBUM);
|
||||
WritePrivateProfileStringA("ml_rg", "config_ask", config_ask ? "1" : "0", iniFile);
|
||||
WritePrivateProfileStringA("ml_rg", "config_ask_each_album", config_ask_each_album ? "1" : "0", iniFile);
|
||||
break;
|
||||
}
|
||||
case WM_COMMAND:
|
||||
switch(LOWORD(wParam))
|
||||
{
|
||||
case IDCANCEL:
|
||||
case IDOK:
|
||||
EndDialog(hwndDlg, 0);
|
||||
break;
|
||||
case IDC_ASK:
|
||||
case IDC_ALBUM:
|
||||
case IDC_ALL:
|
||||
DoButtons(hwndDlg);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
146
Src/Plugins/Library/ml_rg/main.h
Normal file
146
Src/Plugins/Library/ml_rg/main.h
Normal file
@ -0,0 +1,146 @@
|
||||
#ifndef NULLSOFT_ML_RG_MAIN_H
|
||||
#define NULLSOFT_ML_RG_MAIN_H
|
||||
|
||||
#include <windows.h>
|
||||
#include "../../General/gen_ml/ml.h"
|
||||
#include <windowsx.h>
|
||||
#include "../winamp/wa_ipc.h"
|
||||
#include "../../General/gen_ml/ml.h"
|
||||
#include "resource.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
extern winampMediaLibraryPlugin plugin;
|
||||
extern char *iniFile;
|
||||
|
||||
LRESULT SetFileInfo(const wchar_t *filename, const wchar_t *metadata, const wchar_t *data);
|
||||
int GetFileInfo(const wchar_t *filename, const wchar_t *metadata, wchar_t *dest, int len);
|
||||
void WriteFileInfo();
|
||||
void TagUpdated(const wchar_t *filename);
|
||||
|
||||
struct RGWorkFile
|
||||
{
|
||||
RGWorkFile(const wchar_t *_filename=0)
|
||||
{
|
||||
if (_filename)
|
||||
lstrcpynW(filename, _filename, MAX_PATH);
|
||||
else
|
||||
filename[0]=0;
|
||||
track_gain[0]=0;
|
||||
track_peak[0]=0;
|
||||
album_gain[0]=0;
|
||||
album_peak[0]=0;
|
||||
}
|
||||
|
||||
wchar_t filename[MAX_PATH];
|
||||
wchar_t track_gain[64];
|
||||
wchar_t track_peak[64];
|
||||
wchar_t album_gain[64];
|
||||
wchar_t album_peak[64];
|
||||
};
|
||||
|
||||
class ProgressCallback;
|
||||
|
||||
class WorkQueue
|
||||
{
|
||||
public:
|
||||
WorkQueue() : totalFiles(0){}
|
||||
void Add(const wchar_t *filename);
|
||||
void Calculate(ProgressCallback *callback, int *killSwitch);
|
||||
typedef std::vector<RGWorkFile> RGWorkQueue;
|
||||
typedef std::map<std::wstring, RGWorkQueue> AlbumMap;
|
||||
AlbumMap albums;
|
||||
RGWorkQueue unclassified;
|
||||
size_t totalFiles;
|
||||
};
|
||||
|
||||
constexpr auto TIME_SPAN_MS = 10;
|
||||
|
||||
class ProgressCallback
|
||||
{
|
||||
public:
|
||||
ProgressCallback(HWND _c)
|
||||
: callback(_c),
|
||||
totalReceived(0)
|
||||
{
|
||||
ticks = GetTickCount64();
|
||||
}
|
||||
|
||||
void InformSize(size_t bytes)
|
||||
{
|
||||
if (!PostMessage(callback, WM_USER + 3, 0, bytes))
|
||||
{
|
||||
// LOG the error
|
||||
DWORD e = GetLastError();
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// This function may fire an "ERROR_NOT_ENOUGH_QUOTA" 1816 (0x718) error when the limit is hit!
|
||||
/// Put some throttle here, post message every 10 ms, not each time we receive a progress.
|
||||
/// </summary>
|
||||
/// <param name="bytes"></param>
|
||||
void Progress(size_t bytes)
|
||||
{
|
||||
totalReceived += bytes;
|
||||
ULONGLONG currentTicks = GetTickCount64();
|
||||
if (currentTicks - ticks >= TIME_SPAN_MS)
|
||||
{
|
||||
ticks = currentTicks;
|
||||
if (!PostMessage(callback, WM_USER + 4, 0, totalReceived))
|
||||
{
|
||||
// LOG the error
|
||||
DWORD e = GetLastError();
|
||||
}
|
||||
|
||||
totalReceived = 0;
|
||||
}
|
||||
}
|
||||
void FileFinished()
|
||||
{
|
||||
// notify remaining bytes
|
||||
if (totalReceived)
|
||||
{
|
||||
PostMessage(callback, WM_USER + 4, 0, totalReceived);
|
||||
totalReceived = 0;
|
||||
}
|
||||
|
||||
if(!PostMessage(callback, WM_USER, 0, 0))
|
||||
{
|
||||
// LOG the error
|
||||
DWORD e = GetLastError();
|
||||
}
|
||||
}
|
||||
void AlbumFinished(WorkQueue::RGWorkQueue *album)
|
||||
{
|
||||
if(!PostMessage(callback, WM_USER + 1, 0, (LPARAM)album))
|
||||
{
|
||||
// LOG the error
|
||||
DWORD e = GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
HWND callback;
|
||||
ULONGLONG ticks;
|
||||
size_t totalReceived;
|
||||
};
|
||||
|
||||
void CopyAlbumData(WorkQueue::RGWorkQueue &workQueue, const wchar_t *album_gain, const wchar_t *album_peak);
|
||||
void WriteAlbum(WorkQueue::RGWorkQueue &workQueue);
|
||||
void WriteTracks(WorkQueue::RGWorkQueue &workQueue);
|
||||
void DoResults(WorkQueue::RGWorkQueue &queue);
|
||||
void DoResults(WorkQueue &queue);
|
||||
void DoProgress(WorkQueue &workQueue);
|
||||
|
||||
void DestroyRG(void *context);
|
||||
void *CreateRG();
|
||||
void CalculateAlbumRG(void *context, wchar_t album_gain[64], wchar_t album_peak[64], float &albumPeak);
|
||||
void StartRG(void *context);
|
||||
void CalculateRG(void *context, const wchar_t *filename, wchar_t track_gain[64], wchar_t track_peak[64], ProgressCallback *callback, int *killSwitch, float &albumPeak);
|
||||
|
||||
HWND GetDialogBoxParent();
|
||||
BOOL windowOffScreen(HWND hwnd, POINT pt);
|
||||
|
||||
extern int config_ask, config_ask_each_album, config_ignore_gained_album;
|
||||
INT_PTR WINAPI RGConfig(HWND hwndDlg, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
#endif
|
28
Src/Plugins/Library/ml_rg/metadata.cpp
Normal file
28
Src/Plugins/Library/ml_rg/metadata.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
#include "main.h"
|
||||
|
||||
LRESULT SetFileInfo(const wchar_t *filename, const wchar_t *metadata, const wchar_t *data)
|
||||
{
|
||||
extendedFileInfoStructW efis = {
|
||||
filename,
|
||||
metadata,
|
||||
data ? data : L"",
|
||||
data ? (size_t)lstrlenW(data) : 0,
|
||||
};
|
||||
return SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&efis, IPC_SET_EXTENDED_FILE_INFOW);
|
||||
}
|
||||
|
||||
void WriteFileInfo()
|
||||
{
|
||||
SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_WRITE_EXTENDED_FILE_INFO);
|
||||
}
|
||||
|
||||
int GetFileInfo(const wchar_t *filename, const wchar_t *metadata, wchar_t *dest, int len)
|
||||
{
|
||||
extendedFileInfoStructW efis = { filename, metadata, dest, (size_t)len, };
|
||||
return (int)(INT_PTR)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)&efis, IPC_GET_EXTENDED_FILE_INFOW_HOOKABLE); //will return 1 if wa2 supports this IPC call
|
||||
}
|
||||
|
||||
void TagUpdated(const wchar_t *filename)
|
||||
{
|
||||
SendMessage(plugin.hwndWinampParent, WM_WA_IPC, (WPARAM)filename, IPC_FILE_TAG_MAY_HAVE_UPDATEDW);
|
||||
}
|
409
Src/Plugins/Library/ml_rg/ml_rg.cpp
Normal file
409
Src/Plugins/Library/ml_rg/ml_rg.cpp
Normal file
@ -0,0 +1,409 @@
|
||||
#include "Main.h"
|
||||
#include "../nu/AutoWideFn.h"
|
||||
#include "api__ml_rg.h"
|
||||
//#include <api/service/waservicefactory.h>
|
||||
#include "RGFactory.h"
|
||||
#include "../playlist/ifc_playlistloadercallback.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
// wasabi based services for localisation support
|
||||
api_language *WASABI_API_LNG = 0;
|
||||
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
|
||||
|
||||
int uninstalling = 0;
|
||||
RGFactory rgFactory;
|
||||
static DWORD ml_rg_config_ipc;
|
||||
static BOOL ml_rg_open_prefs;
|
||||
|
||||
template <class api_T>
|
||||
void ServiceBuild(api_T *&api_t, GUID factoryGUID_t)
|
||||
{
|
||||
if (plugin.service)
|
||||
{
|
||||
waServiceFactory *factory = plugin.service->service_getServiceByGuid(factoryGUID_t);
|
||||
if (factory)
|
||||
api_t = reinterpret_cast<api_T *>( factory->getInterface() );
|
||||
}
|
||||
}
|
||||
|
||||
template <class api_T>
|
||||
void ServiceRelease(api_T *api_t, GUID factoryGUID_t)
|
||||
{
|
||||
if (plugin.service && api_t)
|
||||
{
|
||||
waServiceFactory *factory = plugin.service->service_getServiceByGuid(factoryGUID_t);
|
||||
if (factory)
|
||||
factory->releaseInterface(api_t);
|
||||
}
|
||||
api_t = NULL;
|
||||
}
|
||||
|
||||
static int Init();
|
||||
static void Quit();
|
||||
static INT_PTR PluginMessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3);
|
||||
|
||||
#define PLUG_VER L"1.29"
|
||||
extern "C" winampMediaLibraryPlugin plugin =
|
||||
{
|
||||
MLHDR_VER,
|
||||
"nullsoft(ml_rg.dll)",
|
||||
Init,
|
||||
Quit,
|
||||
PluginMessageProc,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
api_decodefile *AGAVE_API_DECODE = 0;
|
||||
api_application *WASABI_API_APP = 0;
|
||||
api_playlistmanager *AGAVE_API_PLAYLISTMANAGER = 0;
|
||||
api_stats *AGAVE_API_STATS = 0;
|
||||
|
||||
char *iniFile = 0;
|
||||
int Init()
|
||||
{
|
||||
waServiceFactory *sf = 0;
|
||||
|
||||
|
||||
ServiceBuild( AGAVE_API_PLAYLISTMANAGER, api_playlistmanagerGUID );
|
||||
ServiceBuild( AGAVE_API_DECODE, decodeFileGUID );
|
||||
ServiceBuild( WASABI_API_APP, applicationApiServiceGuid );
|
||||
ServiceBuild( AGAVE_API_STATS, AnonymousStatsGUID );
|
||||
|
||||
plugin.service->service_register( &rgFactory );
|
||||
|
||||
// loader so that we can get the localisation service api for use
|
||||
ServiceBuild( WASABI_API_LNG, languageApiGUID );
|
||||
|
||||
// need to have this initialised before we try to do anything with localisation features
|
||||
WASABI_API_START_LANG( plugin.hDllInstance, MlReplayGainLangGUID );
|
||||
|
||||
static wchar_t szDescription[ 256 ];
|
||||
StringCchPrintfW( szDescription, ARRAYSIZE( szDescription ), WASABI_API_LNGSTRINGW( IDS_NULLSOFT_REPLAY_GAIN_ANALYZER ), PLUG_VER );
|
||||
|
||||
plugin.description = (char *)szDescription;
|
||||
|
||||
ml_rg_config_ipc = (DWORD)SendMessageA( plugin.hwndWinampParent, WM_WA_IPC, ( WPARAM ) & "ml_rg_config", IPC_REGISTER_WINAMP_IPCMESSAGE );
|
||||
|
||||
iniFile = (char *)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETINIFILE );
|
||||
config_ask = GetPrivateProfileIntA( "ml_rg", "config_ask", config_ask, iniFile );
|
||||
config_ask_each_album = GetPrivateProfileIntA( "ml_rg", "config_ask_each_album", config_ask_each_album, iniFile );
|
||||
|
||||
|
||||
return ML_INIT_SUCCESS;
|
||||
}
|
||||
|
||||
void Quit()
|
||||
{
|
||||
ServiceRelease(decodeFile, decodeFileGUID);
|
||||
ServiceRelease(WASABI_API_APP, applicationApiServiceGuid);
|
||||
ServiceRelease(WASABI_API_LNG, languageApiGUID);
|
||||
ServiceRelease(AGAVE_API_PLAYLISTMANAGER, api_playlistmanagerGUID);
|
||||
ServiceRelease(AGAVE_API_STATS, AnonymousStatsGUID);
|
||||
plugin.service->service_deregister(&rgFactory);
|
||||
}
|
||||
|
||||
void WorkQueue::Add(const wchar_t *filename)
|
||||
{
|
||||
wchar_t album[512] = L"";
|
||||
|
||||
// if the user wants to ignore tracks already scanned, check and skip appropriately
|
||||
if (config_ignore_gained_album && GetFileInfo(filename, L"replaygain_album_gain", album, 256) && album[0] != 0)
|
||||
return;
|
||||
|
||||
|
||||
GetFileInfo(filename, L"album", album, 256);
|
||||
if (album[0])
|
||||
{
|
||||
RGWorkFile workFile;
|
||||
lstrcpynW(workFile.filename, filename, MAX_PATH);
|
||||
albums[album].push_back(workFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
RGWorkFile workFile;
|
||||
lstrcpynW(workFile.filename, filename, MAX_PATH);
|
||||
unclassified.push_back(workFile);
|
||||
}
|
||||
totalFiles++;
|
||||
}
|
||||
|
||||
void WriteAlbum(WorkQueue::RGWorkQueue &workQueue)
|
||||
{
|
||||
for (WorkQueue::RGWorkQueue::iterator itr = workQueue.begin();itr != workQueue.end();itr++)
|
||||
{
|
||||
if (itr->track_gain[0])
|
||||
SetFileInfo(itr->filename, L"replaygain_track_gain", itr->track_gain);
|
||||
|
||||
if (itr->track_peak[0])
|
||||
SetFileInfo(itr->filename, L"replaygain_track_peak", itr->track_peak);
|
||||
|
||||
if (itr->album_gain[0])
|
||||
SetFileInfo(itr->filename, L"replaygain_album_gain", itr->album_gain);
|
||||
|
||||
if (itr->album_peak[0])
|
||||
SetFileInfo(itr->filename, L"replaygain_album_peak", itr->album_peak);
|
||||
|
||||
WriteFileInfo();
|
||||
if (AGAVE_API_STATS)
|
||||
AGAVE_API_STATS->IncrementStat(api_stats::REPLAYGAIN_COUNT);
|
||||
|
||||
TagUpdated(itr->filename);
|
||||
}
|
||||
}
|
||||
|
||||
void WriteTracks(WorkQueue::RGWorkQueue &workQueue)
|
||||
{
|
||||
for (WorkQueue::RGWorkQueue::iterator itr = workQueue.begin();itr != workQueue.end();itr++)
|
||||
{
|
||||
if (itr->track_gain[0])
|
||||
SetFileInfo(itr->filename, L"replaygain_track_gain", itr->track_gain);
|
||||
|
||||
if (itr->track_peak[0])
|
||||
SetFileInfo(itr->filename, L"replaygain_track_peak", itr->track_peak);
|
||||
|
||||
WriteFileInfo();
|
||||
if (AGAVE_API_STATS)
|
||||
AGAVE_API_STATS->IncrementStat(api_stats::REPLAYGAIN_COUNT);
|
||||
|
||||
TagUpdated(itr->filename);
|
||||
}
|
||||
}
|
||||
|
||||
void CopyAlbumData(WorkQueue::RGWorkQueue &workQueue, const wchar_t *album_gain, const wchar_t *album_peak)
|
||||
{
|
||||
for (WorkQueue::RGWorkQueue::iterator itr = workQueue.begin();itr != workQueue.end();itr++)
|
||||
{
|
||||
if (itr->track_gain && itr->track_gain[0]) // if there's no track gain, it's because there was an error!
|
||||
{
|
||||
if (album_gain && album_gain[0])
|
||||
lstrcpynW(itr->album_gain, album_gain, 64);
|
||||
|
||||
if (album_peak && album_peak[0])
|
||||
lstrcpynW(itr->album_peak, album_peak, 64);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorkQueue::Calculate(ProgressCallback *callback, int *killSwitch)
|
||||
{
|
||||
void *context = CreateRG();
|
||||
StartRG(context);
|
||||
|
||||
float albumPeak = 0;
|
||||
for (RGWorkQueue::iterator itr = unclassified.begin();itr != unclassified.end();itr++)
|
||||
{
|
||||
if (*killSwitch) {DestroyRG(context); return ;}
|
||||
CalculateRG(context, itr->filename, itr->track_gain, itr->track_peak, callback, killSwitch, albumPeak);
|
||||
callback->FileFinished();
|
||||
}
|
||||
if (*killSwitch) {DestroyRG(context); return ;}
|
||||
callback->AlbumFinished(&unclassified);
|
||||
|
||||
for (AlbumMap::iterator mapItr = albums.begin();mapItr != albums.end();mapItr++)
|
||||
{
|
||||
albumPeak = 0;
|
||||
StartRG(context);
|
||||
for (RGWorkQueue::iterator itr = mapItr->second.begin();itr != mapItr->second.end();itr++)
|
||||
{
|
||||
if (*killSwitch) {DestroyRG(context); return ;}
|
||||
CalculateRG(context, itr->filename, itr->track_gain, itr->track_peak, callback, killSwitch, albumPeak);
|
||||
callback->FileFinished();
|
||||
}
|
||||
wchar_t album_gain[64] = L"", album_peak[64] = L"";
|
||||
CalculateAlbumRG(context, album_gain, album_peak, albumPeak);
|
||||
CopyAlbumData(mapItr->second, album_gain, album_peak);
|
||||
if (*killSwitch) {DestroyRG(context); return ;}
|
||||
callback->AlbumFinished(&(mapItr->second));
|
||||
}
|
||||
DestroyRG(context);
|
||||
}
|
||||
|
||||
class WorkQueuePlaylistLoader : public ifc_playlistloadercallback
|
||||
{
|
||||
public:
|
||||
WorkQueuePlaylistLoader(WorkQueue *_queue);
|
||||
void OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info);
|
||||
|
||||
protected:
|
||||
WorkQueue *queue;
|
||||
RECVS_DISPATCH;
|
||||
};
|
||||
|
||||
WorkQueuePlaylistLoader::WorkQueuePlaylistLoader(WorkQueue *_queue)
|
||||
{
|
||||
queue = _queue;
|
||||
}
|
||||
|
||||
void WorkQueuePlaylistLoader::OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info)
|
||||
{
|
||||
queue->Add(filename);
|
||||
}
|
||||
|
||||
#define CBCLASS WorkQueuePlaylistLoader
|
||||
START_DISPATCH;
|
||||
VCB(IFC_PLAYLISTLOADERCALLBACK_ONFILE, OnFile)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
||||
|
||||
INT_PTR PluginMessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3)
|
||||
{
|
||||
if (message_type == ML_MSG_ONSENDTOBUILD)
|
||||
{
|
||||
if (param1 == ML_TYPE_ITEMRECORDLISTW || param1 == ML_TYPE_ITEMRECORDLIST ||
|
||||
param1 == ML_TYPE_FILENAMES || param1 == ML_TYPE_STREAMNAMES ||
|
||||
param1 == ML_TYPE_FILENAMESW || param1 == ML_TYPE_STREAMNAMESW ||
|
||||
(AGAVE_API_PLAYLISTMANAGER && (param1 == ML_TYPE_PLAYLIST || param1 == ML_TYPE_PLAYLISTS)))
|
||||
{
|
||||
wchar_t description[512] = {0};
|
||||
WASABI_API_LNGSTRINGW_BUF(IDS_CALCULATE_REPLAY_GAIN, description, 512);
|
||||
|
||||
mlAddToSendToStructW s = {0};
|
||||
s.context = param2;
|
||||
s.desc = description;
|
||||
s.user32 = (INT_PTR)PluginMessageProc;
|
||||
SendMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&s, ML_IPC_ADDTOSENDTOW);
|
||||
}
|
||||
}
|
||||
else if (message_type == ML_MSG_ONSENDTOSELECT)
|
||||
{
|
||||
if (param3 != (INT_PTR)PluginMessageProc) return 0;
|
||||
|
||||
INT_PTR type = param1;
|
||||
INT_PTR data = param2;
|
||||
|
||||
if (data)
|
||||
{
|
||||
WorkQueue workQueue;
|
||||
if (type == ML_TYPE_ITEMRECORDLIST)
|
||||
{
|
||||
itemRecordList *p = (itemRecordList*)data;
|
||||
for (int x = 0; x < p->Size; x ++)
|
||||
{
|
||||
workQueue.Add(AutoWideFn(p->Items[x].filename));
|
||||
}
|
||||
|
||||
DoProgress(workQueue);
|
||||
return 1;
|
||||
}
|
||||
else if (type == ML_TYPE_ITEMRECORDLISTW)
|
||||
{
|
||||
itemRecordListW *p = (itemRecordListW*)data;
|
||||
for (int x = 0; x < p->Size; x ++)
|
||||
{
|
||||
workQueue.Add(p->Items[x].filename);
|
||||
}
|
||||
|
||||
DoProgress(workQueue);
|
||||
return 1;
|
||||
}
|
||||
else if (type == ML_TYPE_FILENAMES || type == ML_TYPE_STREAMNAMES)
|
||||
{
|
||||
char *p = (char*)data;
|
||||
while (p && *p)
|
||||
{
|
||||
workQueue.Add(AutoWideFn(p));
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
DoProgress(workQueue);
|
||||
return 1;
|
||||
}
|
||||
else if (type == ML_TYPE_FILENAMESW || type == ML_TYPE_STREAMNAMESW)
|
||||
{
|
||||
wchar_t *p = (wchar_t*)data;
|
||||
while (p && *p)
|
||||
{
|
||||
workQueue.Add(p);
|
||||
p += wcslen(p) + 1;
|
||||
}
|
||||
DoProgress(workQueue);
|
||||
return 1;
|
||||
}
|
||||
else if (type == ML_TYPE_PLAYLIST)
|
||||
{
|
||||
mlPlaylist *playlist = (mlPlaylist *)param2;
|
||||
WorkQueuePlaylistLoader loader(&workQueue);
|
||||
AGAVE_API_PLAYLISTMANAGER->Load(playlist->filename, &loader);
|
||||
DoProgress(workQueue);
|
||||
return 1;
|
||||
}
|
||||
else if (type == ML_TYPE_PLAYLISTS)
|
||||
{
|
||||
mlPlaylist **playlists = (mlPlaylist **)param2;
|
||||
WorkQueuePlaylistLoader loader(&workQueue);
|
||||
while (playlists && *playlists)
|
||||
{
|
||||
mlPlaylist *playlist = *playlists;
|
||||
AGAVE_API_PLAYLISTMANAGER->Load(playlist->filename, &loader);
|
||||
playlists++;
|
||||
}
|
||||
DoProgress(workQueue);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (message_type == ML_MSG_CONFIG)
|
||||
{
|
||||
ml_rg_open_prefs = TRUE;
|
||||
SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 42, IPC_OPENPREFSTOPAGE);
|
||||
ml_rg_open_prefs = FALSE;
|
||||
return 1;
|
||||
}
|
||||
// this will be sent if we've opened the playback->replay gain prefs page
|
||||
// so that we can enable the embedded controls and return the RGConfig proc
|
||||
else if (message_type == ml_rg_config_ipc)
|
||||
{
|
||||
// sanity check by winamp.exe to make sure that we're valid
|
||||
if(!param1)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
// return the config dialog proceedure
|
||||
else if(param1 == 1)
|
||||
{
|
||||
return (INT_PTR)RGConfig;
|
||||
}
|
||||
// queried when the playback prefs page is opened to see if we [ml_rg] caused it
|
||||
else if(param1 == 2)
|
||||
{
|
||||
if(ml_rg_open_prefs)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
__declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
|
||||
{
|
||||
return &plugin;
|
||||
}
|
||||
|
||||
__declspec( dllexport ) int winampUninstallPlugin(HINSTANCE hDllInst, HWND hwndDlg, int param) {
|
||||
uninstalling = 1;
|
||||
|
||||
// prompt to remove our settings with default as no (just incase)
|
||||
if(MessageBoxW(hwndDlg,WASABI_API_LNGSTRINGW(IDS_DO_YOU_ALSO_WANT_TO_REMOVE_SETTINGS),
|
||||
(wchar_t*)plugin.description,MB_YESNO|MB_DEFBUTTON2) == IDYES)
|
||||
{
|
||||
WritePrivateProfileStringA("ml_rg", 0, 0, iniFile);
|
||||
}
|
||||
|
||||
// also attempt to remove the ReplayGainAnalysis.dll so everything is kept cleaner
|
||||
wchar_t path[MAX_PATH] = {0};
|
||||
PathCombineW(path, (wchar_t*)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETSHAREDDLLDIRECTORYW), L"ReplayGainAnalysis.dll");
|
||||
|
||||
// if we get a handle then try to lower the handle count so we can delete
|
||||
HINSTANCE rgLib = GetModuleHandleW(path);
|
||||
if(rgLib) {
|
||||
FreeLibrary(rgLib);
|
||||
}
|
||||
DeleteFileW(path);
|
||||
|
||||
// allow an on-the-fly removal (since we've got to be with a compatible client build)
|
||||
return ML_PLUGIN_UNINSTALL_NOW;
|
||||
}
|
||||
};
|
152
Src/Plugins/Library/ml_rg/ml_rg.rc
Normal file
152
Src/Plugins/Library/ml_rg/ml_rg.rc
Normal file
@ -0,0 +1,152 @@
|
||||
// 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
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// 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
|
||||
|
||||
#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
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_RESULTS DIALOGEX 0, 0, 356, 170
|
||||
STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_CONTROLPARENT | WS_EX_APPWINDOW
|
||||
CAPTION "Replay Gain Results"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
CONTROL "",IDC_RGLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | WS_BORDER | WS_TABSTOP,4,7,348,141
|
||||
DEFPUSHBUTTON "Save as Album",IDOK,116,153,76,13
|
||||
PUSHBUTTON "Save Track data",IDC_SAVETRACK,196,153,76,13
|
||||
PUSHBUTTON "Cancel",IDCANCEL,276,153,76,13
|
||||
END
|
||||
|
||||
IDD_PROGRESS DIALOGEX 0, 0, 186, 63
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_APPWINDOW
|
||||
CAPTION "Calculating Replay Gain"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "File Progress:",IDC_STATIC,7,7,44,8
|
||||
LTEXT "Calculating...",IDC_FILE_PROGRESS,63,7,116,8
|
||||
LTEXT "Total Progress:",IDC_STATIC,7,23,50,8
|
||||
LTEXT "Calculating...",IDC_PROGRESS_FILES,63,23,116,8
|
||||
PUSHBUTTON "Abort",IDCANCEL,129,41,50,14
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_RESULTS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 4
|
||||
RIGHTMARGIN, 352
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 166
|
||||
END
|
||||
|
||||
IDD_PROGRESS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 56
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_NULLSOFT_REPLAY_GAIN_ANALYZER "Nullsoft Replay Gain Analyzer v%s"
|
||||
65535 "{5F633543-148D-48cc-B683-DA82F592CF28}"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_CALCULATE_REPLAY_GAIN "Calculate Replay Gain"
|
||||
IDS_1_OF_X_FILES "1 of %u files"
|
||||
IDS_FINISHED "Finished."
|
||||
IDS_X_OF_X_FILES "%u of %u files"
|
||||
IDS_PROCESSING "Processing..."
|
||||
IDS_TOO_MANY_CHANNELS "Too many channels, can't deal with this yet"
|
||||
IDS_REPLAYGAIN "ReplayGain"
|
||||
IDS_NOT_ABLE_TO_OPEN_RG_DLL "Not able to open ReplayGainAnalysis.dll"
|
||||
IDS_COL_FILENAME "Filename"
|
||||
IDS_COL_TRACK_GAIN "Track Gain"
|
||||
IDS_COL_TRACK_PEAK "Track Peak"
|
||||
IDS_COL_ALBUM_GAIN "Album Gain"
|
||||
IDS_COL_ALBUM_PEAK "Album Peak"
|
||||
IDS_DO_YOU_ALSO_WANT_TO_REMOVE_SETTINGS
|
||||
"Do you also want to remove the saved settings for this plug-in?"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#include "version.rc2"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
57
Src/Plugins/Library/ml_rg/ml_rg.sln
Normal file
57
Src/Plugins/Library/ml_rg/ml_rg.sln
Normal file
@ -0,0 +1,57 @@
|
||||
|
||||
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}") = "ml_rg", "ml_rg.vcxproj", "{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D} = {8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReplayGainAnalysis", "..\ReplayGainAnalysis\ReplayGainAnalysis.vcxproj", "{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsutil", "..\nsutil\nsutil.vcxproj", "{DABE6307-F8DD-416D-9DAC-673E2DECB73F}"
|
||||
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
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Debug|x64.Build.0 = Debug|x64
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Release|Win32.Build.0 = Release|Win32
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Release|x64.ActiveCfg = Release|x64
|
||||
{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}.Release|x64.Build.0 = Release|x64
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Debug|x64.Build.0 = Debug|x64
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Release|Win32.Build.0 = Release|Win32
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Release|x64.ActiveCfg = Release|x64
|
||||
{8155E1C4-B6F8-4A1D-96A3-E4FF0FE9192D}.Release|x64.Build.0 = Release|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.Build.0 = Debug|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.Build.0 = Release|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.ActiveCfg = Release|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {FC646532-2050-40A5-A2AB-F699F1C071C4}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
310
Src/Plugins/Library/ml_rg/ml_rg.vcxproj
Normal file
310
Src/Plugins/Library/ml_rg/ml_rg.vcxproj
Normal file
@ -0,0 +1,310 @@
|
||||
<?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>{F42B3AC8-E719-4AA6-B9EC-1F9BFC799861}</ProjectGuid>
|
||||
<RootNamespace>ml_rg</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||
<PlatformToolset>v142</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|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)'=='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|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>
|
||||
<EmbedManifest>true</EmbedManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<EmbedManifest>true</EmbedManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
<EmbedManifest>true</EmbedManifest>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<EmbedManifest>true</EmbedManifest>
|
||||
</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_WINNT=0x0601;WINVER=0x0601;WIN32;_DEBUG;_WINDOWS;_USRDLL;ML_RG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<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>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Manifest>
|
||||
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;_DEBUG;_WINDOWS;_USRDLL;ML_RG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4311;4302;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<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>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Manifest>
|
||||
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;NDEBUG;_WINDOWS;_USRDLL;ML_RG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<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>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Manifest>
|
||||
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>..\..\..\Wasabi;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;NDEBUG;_WINDOWS;_USRDLL;ML_RG_EXPORTS;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4311;4302;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<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>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Manifest>
|
||||
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
|
||||
</Manifest>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="api__ml_rg.h" />
|
||||
<ClInclude Include="main.h" />
|
||||
<ClInclude Include="obj_replaygain.h" />
|
||||
<ClInclude Include="Process.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="RGFactory.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\..\nu\listview.cpp" />
|
||||
<ClCompile Include="config.cpp" />
|
||||
<ClCompile Include="metadata.cpp" />
|
||||
<ClCompile Include="ml_rg.cpp" />
|
||||
<ClCompile Include="Process.cpp" />
|
||||
<ClCompile Include="Progress.cpp" />
|
||||
<ClCompile Include="replaygain.cpp" />
|
||||
<ClCompile Include="Results.cpp" />
|
||||
<ClCompile Include="RGFactory.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ml_rg.rc" />
|
||||
</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>
|
68
Src/Plugins/Library/ml_rg/ml_rg.vcxproj.filters
Normal file
68
Src/Plugins/Library/ml_rg/ml_rg.vcxproj.filters
Normal file
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="config.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="metadata.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Process.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Progress.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="replaygain.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Results.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="RGFactory.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="ml_rg.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\..\nu\listview.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="api__ml_rg.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="main.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="obj_replaygain.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Process.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="RGFactory.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{20ba2df7-10e3-42e6-896b-4c0a795e542f}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ressource Files">
|
||||
<UniqueIdentifier>{018c7bf8-fe6c-4705-aa4d-c641ffd71994}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{916716df-cad8-4fa2-9a6f-2203f1fbade7}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="ml_rg.rc">
|
||||
<Filter>Ressource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
62
Src/Plugins/Library/ml_rg/obj_replaygain.h
Normal file
62
Src/Plugins/Library/ml_rg/obj_replaygain.h
Normal file
@ -0,0 +1,62 @@
|
||||
#ifndef NULLSOFT_ML_RG_OBJ_REPLAYGAIN_H
|
||||
#define NULLSOFT_ML_RG_OBJ_REPLAYGAIN_H
|
||||
|
||||
#include <bfc/dispatch.h>
|
||||
|
||||
enum
|
||||
{
|
||||
RG_SUCCESS = 0,
|
||||
RG_FAILURE = 1,
|
||||
RG_MODE_NOT_SUPPORTED=2,
|
||||
|
||||
RG_INDIVIDUAL_TRACKS = 0, // use this mode to calculate each track sent individually
|
||||
RG_ALBUM = 1, // use this mode to treat all tracks sent as belonging to the same album
|
||||
RG_AUTO = 2, // retrieve tags from the files to determine album info
|
||||
};
|
||||
|
||||
class obj_replaygain : public Dispatchable
|
||||
{
|
||||
protected:
|
||||
obj_replaygain() {}
|
||||
~obj_replaygain() {}
|
||||
public:
|
||||
int Open(int mode);
|
||||
int ProcessTrack(const wchar_t *filename);
|
||||
int Write();
|
||||
void Close();
|
||||
|
||||
DISPATCH_CODES
|
||||
{
|
||||
OBJ_REPLAYGAIN_OPEN = 10,
|
||||
OBJ_REPLAYGAIN_PROCESSTRACK = 20,
|
||||
OBJ_REPLAYGAIN_WRITE = 30,
|
||||
OBJ_REPLAYGAIN_CLOSE = 40,
|
||||
};
|
||||
};
|
||||
|
||||
inline int obj_replaygain::Open(int mode)
|
||||
{
|
||||
return _call(OBJ_REPLAYGAIN_OPEN, (int)RG_FAILURE, mode);
|
||||
}
|
||||
|
||||
inline int obj_replaygain::ProcessTrack(const wchar_t *filename)
|
||||
{
|
||||
return _call(OBJ_REPLAYGAIN_PROCESSTRACK, (int)RG_FAILURE, filename);
|
||||
}
|
||||
|
||||
inline int obj_replaygain::Write()
|
||||
{
|
||||
return _call(OBJ_REPLAYGAIN_WRITE, (int)RG_FAILURE);
|
||||
}
|
||||
|
||||
inline void obj_replaygain::Close()
|
||||
{
|
||||
_voidcall(OBJ_REPLAYGAIN_CLOSE);
|
||||
}
|
||||
|
||||
// {3A398A1B-D316-4094-993E-27EAEA553D19}
|
||||
static const GUID RGGUID =
|
||||
{ 0x3a398a1b, 0xd316, 0x4094, { 0x99, 0x3e, 0x27, 0xea, 0xea, 0x55, 0x3d, 0x19 } };
|
||||
|
||||
|
||||
#endif
|
370
Src/Plugins/Library/ml_rg/replaygain.cpp
Normal file
370
Src/Plugins/Library/ml_rg/replaygain.cpp
Normal file
@ -0,0 +1,370 @@
|
||||
#include "main.h"
|
||||
#include <math.h>
|
||||
#include "../ReplayGainAnalysis/gain_analysis.h"
|
||||
#include "api__ml_rg.h"
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
#include <locale.h>
|
||||
|
||||
#pragma intrinsic(fabs)
|
||||
|
||||
static inline float fastmax(float x, float a)
|
||||
{
|
||||
x -= a;
|
||||
x += (float)fabs(x);
|
||||
x *= 0.5f;
|
||||
x += a;
|
||||
return (x);
|
||||
}
|
||||
|
||||
static HMODULE rgLib = 0;
|
||||
typedef int(*INITGAINANALYSIS)(void *context, long samplefreq);
|
||||
static INITGAINANALYSIS InitGainAnalysis = 0;
|
||||
typedef int(*ANALYZESAMPLES)(void *context, const float * left_samples, const float * right_samples, size_t num_samples, int num_channels);
|
||||
static ANALYZESAMPLES AnalyzeSamples = 0;
|
||||
typedef int(*RESETSAMPLEFREQUENCY)(void *context, long samplefreq);
|
||||
static RESETSAMPLEFREQUENCY ResetSampleFrequency = 0;
|
||||
typedef float(*GETTITLEGAIN)(void *context);
|
||||
static GETTITLEGAIN GetTitleGain = 0;
|
||||
typedef float(*GETALBUMGAIN)(void *context);
|
||||
static GETALBUMGAIN GetAlbumGain = 0;
|
||||
typedef void *(* CREATERGCONTEXT)();
|
||||
static CREATERGCONTEXT CreateRGContext = 0;
|
||||
typedef void(*FREERGCONTEXT)(void *context);
|
||||
static FREERGCONTEXT FreeRGContext = 0;
|
||||
|
||||
void LoadRG()
|
||||
{
|
||||
if (rgLib)
|
||||
return ;
|
||||
|
||||
wchar_t path[MAX_PATH] = {0};
|
||||
PathCombineW(path, (wchar_t*)SendMessage(plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETSHAREDDLLDIRECTORYW), L"ReplayGainAnalysis.dll");
|
||||
rgLib = LoadLibraryW(path);
|
||||
|
||||
if (rgLib)
|
||||
{
|
||||
InitGainAnalysis = (INITGAINANALYSIS)GetProcAddress(rgLib, "WAInitGainAnalysis");
|
||||
AnalyzeSamples = (ANALYZESAMPLES)GetProcAddress(rgLib, "WAAnalyzeSamples");
|
||||
GetTitleGain = (GETTITLEGAIN)GetProcAddress(rgLib, "WAGetTitleGain");
|
||||
ResetSampleFrequency = (RESETSAMPLEFREQUENCY)GetProcAddress(rgLib, "WAResetSampleFrequency");
|
||||
GetAlbumGain = (GETALBUMGAIN)GetProcAddress(rgLib, "WAGetAlbumGain");
|
||||
CreateRGContext = (CREATERGCONTEXT)GetProcAddress(rgLib, "WACreateRGContext");
|
||||
FreeRGContext = (FREERGCONTEXT)GetProcAddress(rgLib, "WAFreeRGContext");
|
||||
}
|
||||
}
|
||||
|
||||
void *CreateRG()
|
||||
{
|
||||
LoadRG();
|
||||
|
||||
return CreateRGContext();
|
||||
}
|
||||
|
||||
void DestroyRG(void *context)
|
||||
{
|
||||
FreeRGContext(context);
|
||||
}
|
||||
|
||||
#define CHUNKSIZE 16384
|
||||
static void CalculateRG_float(void *context, ifc_audiostream *decoder, AudioParameters *parameters, wchar_t track_gain[64], wchar_t track_peak[64], ProgressCallback *callback, int *killSwitch, float &albumPeak)
|
||||
{
|
||||
float data[2*CHUNKSIZE] = {0};
|
||||
float right[CHUNKSIZE] = {0};
|
||||
float peak = 0;
|
||||
|
||||
if (parameters->channels > 2)
|
||||
{
|
||||
char titleStr[32] = {0};
|
||||
MessageBoxA(GetDialogBoxParent(),
|
||||
WASABI_API_LNGSTRING(IDS_TOO_MANY_CHANNELS),
|
||||
WASABI_API_LNGSTRING_BUF(IDS_REPLAYGAIN,titleStr,32),
|
||||
MB_OK);
|
||||
decodeFile->CloseAudio(decoder);
|
||||
return ;
|
||||
}
|
||||
ResetSampleFrequency(context, parameters->sampleRate);
|
||||
if (callback) callback->InformSize((parameters->sizeBytes == -1) ? 0 : parameters->sizeBytes);
|
||||
while (1)
|
||||
{
|
||||
if (*killSwitch)
|
||||
{
|
||||
decodeFile->CloseAudio(decoder);
|
||||
return ;
|
||||
}
|
||||
int error=0;
|
||||
size_t bytesRead = decoder->ReadAudio((void *)data, sizeof(data), killSwitch, &error);
|
||||
if (*killSwitch)
|
||||
{
|
||||
decodeFile->CloseAudio(decoder);
|
||||
return ;
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (callback) callback->Progress(bytesRead);
|
||||
|
||||
size_t samples = bytesRead / sizeof(*data);
|
||||
|
||||
if (!samples)
|
||||
break;
|
||||
|
||||
for (size_t i = 0;i != samples;i++)
|
||||
{
|
||||
peak = fastmax(peak, (float)fabs(data[i]));
|
||||
data[i] *= 32768.0f;
|
||||
}
|
||||
albumPeak = fastmax(peak, albumPeak);
|
||||
|
||||
if (parameters->channels == 1)
|
||||
AnalyzeSamples(context, data, NULL, samples, 1);
|
||||
else
|
||||
{
|
||||
size_t samples2 = samples / 2;
|
||||
for (size_t i = 0;i != samples2;i++)
|
||||
{
|
||||
data[i] = data[i * 2];
|
||||
right[i] = data[i * 2 + 1];
|
||||
}
|
||||
AnalyzeSamples(context, data, right, samples2, 2);
|
||||
}
|
||||
}
|
||||
decodeFile->CloseAudio(decoder);
|
||||
float gain = GetTitleGain(context);
|
||||
if (gain != GAIN_NOT_ENOUGH_SAMPLES)
|
||||
{
|
||||
_locale_t C_locale = WASABI_API_LNG->Get_C_NumericLocale();
|
||||
_snwprintf_l(track_gain, 64, L"%-+.2f dB", C_locale, gain);
|
||||
_snwprintf_l(track_peak, 64, L"%-.9f", C_locale, peak);
|
||||
}
|
||||
}
|
||||
|
||||
static void FillFloat(float *left, float *right, void *samples, size_t bps, size_t numSamples, size_t numChannels, float &peak, float &albumPeak, float gain)
|
||||
{
|
||||
switch (bps)
|
||||
{
|
||||
case 8:
|
||||
{
|
||||
unsigned __int8 *samples8 = (unsigned __int8 *)samples;
|
||||
size_t t = 0;
|
||||
for (size_t x = 0; x != numSamples; x ++)
|
||||
{
|
||||
left[x] = (float)(samples8[t++] - 128) * 256.0f * gain;
|
||||
|
||||
if (numChannels == 2)
|
||||
{
|
||||
right[x] = (float)(samples8[t++] - 128) * 256.0f* gain;
|
||||
}
|
||||
else
|
||||
right[x] = left[x];
|
||||
peak = fastmax(peak, (float)fabs(left[x]));
|
||||
peak = fastmax(peak, (float)fabs(right[x]));
|
||||
albumPeak=fastmax(albumPeak, peak);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 16:
|
||||
{
|
||||
short *samples16 = (short *)samples;
|
||||
size_t t = 0;
|
||||
if (numChannels == 1)
|
||||
{
|
||||
for (size_t x = 0; x != numSamples; x ++)
|
||||
{
|
||||
left[x] = (float)samples16[t++] * gain;
|
||||
right[x] = left[x];
|
||||
peak = fastmax(peak, (float)fabs(left[x]));
|
||||
albumPeak=fastmax(albumPeak, peak);
|
||||
|
||||
}
|
||||
}
|
||||
else if (numChannels == 2)
|
||||
{
|
||||
for (size_t x = 0; x != numSamples; x ++)
|
||||
{
|
||||
left[x] = (float)samples16[t++] * gain ;
|
||||
right[x] = (float)samples16[t++] * gain;
|
||||
|
||||
peak = fastmax(peak, (float)fabs(left[x]));
|
||||
peak = fastmax(peak, (float)fabs(right[x]));
|
||||
albumPeak=fastmax(albumPeak, peak);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 24:
|
||||
{
|
||||
unsigned __int8 *samples8 = (unsigned __int8 *)samples;
|
||||
for (size_t x = 0; x != numSamples; x ++)
|
||||
{
|
||||
long temp = (((long)samples8[0]) << 8);
|
||||
temp = temp | (((long)samples8[1]) << 16);
|
||||
temp = temp | (((long)samples8[2]) << 24);
|
||||
left[x] = (float)temp* gain / 65536.0f;
|
||||
samples8 += 3;
|
||||
if (numChannels == 2)
|
||||
{
|
||||
temp = (((long)samples8[0]) << 8);
|
||||
temp = temp | (((long)samples8[1]) << 16);
|
||||
temp = temp | (((long)samples8[2]) << 24);
|
||||
right[x] = (float)temp* gain / 65536.0f;
|
||||
samples8 += 3;
|
||||
}
|
||||
else
|
||||
right[x] = left[x];
|
||||
peak = fastmax(peak, (float)fabs(left[x]));
|
||||
peak = fastmax(peak, (float)fabs(right[x]));
|
||||
albumPeak=fastmax(albumPeak, peak);
|
||||
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
#undef CHUNKSIZE
|
||||
#define CHUNKSIZE 4096
|
||||
static void CalculateRG_pcm(void *context, ifc_audiostream *decoder, AudioParameters *parameters, wchar_t track_gain[64], wchar_t track_peak[64], ProgressCallback *callback, int *killSwitch, float &albumPeak)
|
||||
{
|
||||
char data[4*2*CHUNKSIZE] = {0};
|
||||
float left[CHUNKSIZE] = {0};
|
||||
float right[CHUNKSIZE] = {0};
|
||||
float peak = 0;
|
||||
if (parameters->channels > 2)
|
||||
{
|
||||
char titleStr[32];
|
||||
MessageBoxA(GetDialogBoxParent(),
|
||||
WASABI_API_LNGSTRING(IDS_TOO_MANY_CHANNELS),
|
||||
WASABI_API_LNGSTRING_BUF(IDS_REPLAYGAIN,titleStr,32),
|
||||
MB_OK);
|
||||
decodeFile->CloseAudio(decoder);
|
||||
return ;
|
||||
}
|
||||
|
||||
int padded_bits = (parameters->bitsPerSample + 7) & (~7);
|
||||
albumPeak *= 32768.0f;
|
||||
ResetSampleFrequency(context, parameters->sampleRate);
|
||||
if (callback) callback->InformSize((parameters->sizeBytes == -1) ? 0 : parameters->sizeBytes);
|
||||
while (1)
|
||||
{
|
||||
if (*killSwitch)
|
||||
{
|
||||
decodeFile->CloseAudio(decoder);
|
||||
return ;
|
||||
}
|
||||
int error=0;
|
||||
size_t bytesRead = decoder->ReadAudio((void *)data, 4096 * parameters->channels * (padded_bits / 8), killSwitch, &error);
|
||||
if (*killSwitch)
|
||||
{
|
||||
decodeFile->CloseAudio(decoder);
|
||||
return ;
|
||||
}
|
||||
else if (error)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (callback) callback->Progress(bytesRead);
|
||||
|
||||
size_t samples = bytesRead / (padded_bits / 8);
|
||||
|
||||
if (!samples)
|
||||
break;
|
||||
|
||||
FillFloat(left, right, data, padded_bits, samples / parameters->channels, parameters->channels, peak, albumPeak, (float)pow(2., (double)(padded_bits - parameters->bitsPerSample)));
|
||||
|
||||
size_t samples2 = samples / 2;
|
||||
AnalyzeSamples(context, left, right, samples2, 2);
|
||||
}
|
||||
decodeFile->CloseAudio(decoder);
|
||||
float gain = GetTitleGain(context);
|
||||
if (gain != GAIN_NOT_ENOUGH_SAMPLES)
|
||||
{
|
||||
StringCchPrintfW(track_gain, 64, L"%-+.2f dB", gain);
|
||||
StringCchPrintfW(track_peak, 64, L"%-.9f", peak / 32768.0f);
|
||||
}
|
||||
|
||||
albumPeak /= 32768.0f;
|
||||
}
|
||||
|
||||
void CalculateRG(void *context, const wchar_t *filename, wchar_t track_gain[64], wchar_t track_peak[64], ProgressCallback *callback, int *killSwitch, float &albumPeak)
|
||||
{
|
||||
LoadRG();
|
||||
if (!rgLib)
|
||||
{
|
||||
char titleStr[32] = {0};
|
||||
MessageBoxA(GetDialogBoxParent(),
|
||||
WASABI_API_LNGSTRING(IDS_NOT_ABLE_TO_OPEN_RG_DLL),
|
||||
WASABI_API_LNGSTRING_BUF(IDS_REPLAYGAIN,titleStr,32),
|
||||
MB_OK);
|
||||
return ;
|
||||
}
|
||||
|
||||
wchar_t dummy[64] = {0};
|
||||
if (!GetFileInfo(filename, L"replaygain_track_gain", dummy, 64)) // check if the plugin even supports replaygain
|
||||
return ;
|
||||
|
||||
/*
|
||||
TODO: want to do something like this, but have to do it on the main thread (ugh)
|
||||
if (!_wcsnicmp(dummy, "-24601", 6))
|
||||
{
|
||||
SetFileInfo(itr->filename, L"replaygain_track_gain", L"");
|
||||
SetFileInfo(itr->filename, L"replaygain_track_peak", L"");
|
||||
SetFileInfo(itr->filename, L"replaygain_album_gain", L"");
|
||||
SetFileInfo(itr->filename, L"replaygain_album_peak", L"");
|
||||
WriteFileInfo();
|
||||
}
|
||||
*/
|
||||
|
||||
AudioParameters parameters;
|
||||
parameters.flags = AUDIOPARAMETERS_FLOAT | AUDIOPARAMETERS_MAXCHANNELS | AUDIOPARAMETERS_MAXSAMPLERATE;
|
||||
parameters.channels = 2;
|
||||
parameters.sampleRate = 192000;
|
||||
|
||||
ifc_audiostream *decoder = decodeFile->OpenAudioBackground(filename, ¶meters);
|
||||
if (decoder)
|
||||
CalculateRG_float(context, decoder, ¶meters, track_gain, track_peak, callback, killSwitch, albumPeak);
|
||||
else
|
||||
{
|
||||
// try PCM
|
||||
memset(¶meters, 0, sizeof(AudioParameters));
|
||||
parameters.flags = AUDIOPARAMETERS_MAXCHANNELS | AUDIOPARAMETERS_MAXSAMPLERATE;
|
||||
parameters.channels = 2;
|
||||
parameters.sampleRate = 192000;
|
||||
|
||||
ifc_audiostream *decoder = decodeFile->OpenAudioBackground(filename, ¶meters);
|
||||
if (decoder)
|
||||
CalculateRG_pcm(context, decoder, ¶meters, track_gain, track_peak, callback, killSwitch, albumPeak);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CalculateAlbumRG(void *context, wchar_t album_gain[64], wchar_t album_peak[64], float &albumPeak)
|
||||
{
|
||||
float gain = GetAlbumGain(context);
|
||||
if (gain != GAIN_NOT_ENOUGH_SAMPLES)
|
||||
{
|
||||
/*StringCchPrintfW(album_gain, 64, L"%-+.2f dB", gain);
|
||||
StringCchPrintfW(album_peak, 64, L"%-.9f", albumPeak);*/
|
||||
_locale_t C_locale = WASABI_API_LNG->Get_C_NumericLocale();
|
||||
_snwprintf_l(album_gain, 64, L"%-+.2f dB", C_locale, gain);
|
||||
_snwprintf_l(album_peak, 64, L"%-.9f", C_locale, albumPeak);
|
||||
}
|
||||
}
|
||||
|
||||
void StartRG(void *context)
|
||||
{
|
||||
LoadRG();
|
||||
if (!rgLib)
|
||||
{
|
||||
char titleStr[32] = {0};
|
||||
MessageBoxA(GetDialogBoxParent(),
|
||||
WASABI_API_LNGSTRING(IDS_NOT_ABLE_TO_OPEN_RG_DLL),
|
||||
WASABI_API_LNGSTRING_BUF(IDS_REPLAYGAIN,titleStr,32),
|
||||
MB_OK);
|
||||
return ;
|
||||
}
|
||||
|
||||
InitGainAnalysis(context, 44100); // since this is most common. We'll reset it before doing a real calculation anyway
|
||||
}
|
40
Src/Plugins/Library/ml_rg/resource.h
Normal file
40
Src/Plugins/Library/ml_rg/resource.h
Normal file
@ -0,0 +1,40 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by ml_rg.rc
|
||||
//
|
||||
#define IDS_CALCULATE_REPLAY_GAIN 1
|
||||
#define IDS_1_OF_X_FILES 2
|
||||
#define IDS_FINISHED 3
|
||||
#define IDS_X_OF_X_FILES 4
|
||||
#define IDS_PROCESSING 5
|
||||
#define IDS_TOO_MANY_CHANNELS 6
|
||||
#define IDS_REPLAYGAIN 7
|
||||
#define IDS_NOT_ABLE_TO_OPEN_RG_DLL 8
|
||||
#define IDS_COL_FILENAME 9
|
||||
#define IDS_COL_TRACK_GAIN 10
|
||||
#define IDS_COL_TRACK_PEAK 11
|
||||
#define IDS_COL_ALBUM_GAIN 12
|
||||
#define IDS_COL_ALBUM_PEAK 13
|
||||
#define IDS_STRING14 14
|
||||
#define IDS_DO_YOU_ALSO_WANT_TO_REMOVE_SETTINGS 14
|
||||
#define IDD_RESULTS 101
|
||||
#define IDD_PROGRESS 102
|
||||
#define IDC_RGLIST 1001
|
||||
#define IDC_SAVETRACK 1002
|
||||
#define IDC_PROGRESS_FILES 1003
|
||||
#define IDC_FILE_PROGRESS 1004
|
||||
#define IDC_ASK 1005
|
||||
#define IDC_ALBUM 1006
|
||||
#define IDC_ALL 1007
|
||||
#define IDS_NULLSOFT_REPLAY_GAIN_ANALYZER 65534
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 107
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1008
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
39
Src/Plugins/Library/ml_rg/version.rc2
Normal file
39
Src/Plugins/Library/ml_rg/version.rc2
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "../../../Winamp/buildType.h"
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,29,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 Media Library Plug-in"
|
||||
VALUE "FileVersion", "1,29,0,0"
|
||||
VALUE "InternalName", "Nullsoft Replay Gain Analyzer"
|
||||
VALUE "LegalCopyright", "Copyright <20> 2006-2023 Winamp SA"
|
||||
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
|
||||
VALUE "OriginalFilename", "ml_rg.dll"
|
||||
VALUE "ProductName", "Winamp"
|
||||
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
Reference in New Issue
Block a user