mirror of
https://github.com/Gigaslav/HL2Overcharged.git
synced 2026-09-09 20:23:02 +03:00
1546 lines
46 KiB
C++
1546 lines
46 KiB
C++
/*===============================================================================================
|
|
DSP Plugin Viewer Example
|
|
Copyright (c), Firelight Technologies Pty, Ltd 2004-2016.
|
|
|
|
This example ....
|
|
===============================================================================================*/
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
#include <commctrl.h>
|
|
#include <stdio.h>
|
|
#include <math.h>
|
|
|
|
#include "resource.h"
|
|
|
|
#include "../../api/inc/fmod.h"
|
|
#include "../../api/inc/fmod.hpp"
|
|
#include "../../api/inc/fmod_errors.h"
|
|
|
|
#define TITLE "DSP Plugin Viewer Example. Copyright (c), Firelight Technologies Pty, Ltd 2004-2016."
|
|
#define GRAPHICWINDOW_WIDTH 256
|
|
#define GRAPHICWINDOW_HEIGHT 116
|
|
#define IDC_ACTIVEBUTTON 0x8801
|
|
#define IDC_REMOVEBUTTON 0x8802
|
|
#define IDC_CONFIGBUTTON 0x8803
|
|
|
|
/*
|
|
Structures
|
|
*/
|
|
struct Plugin;
|
|
struct PluginParam
|
|
{
|
|
Plugin *plugin;
|
|
int index;
|
|
HWND sliderhwnd;
|
|
HWND namehwnd;
|
|
HWND valuehwnd;
|
|
WNDPROC oldtrackbarproc;
|
|
int dragging;
|
|
float min, max;
|
|
};
|
|
|
|
struct Plugin
|
|
{
|
|
Plugin *next; // linked list node.
|
|
Plugin *prev; // linked list node.
|
|
FMOD::DSP *dsp;
|
|
HWND hwnd;
|
|
HWND activehwnd;
|
|
HWND removehwnd;
|
|
HWND confighwnd; // button
|
|
HWND configguihwnd;
|
|
WNDPROC oldpluginproc;
|
|
int numparams;
|
|
int windowwidth;
|
|
int windowheight;
|
|
int configwidth;
|
|
int configheight;
|
|
bool configactive;
|
|
PluginParam *param; // hopefully there are no more than 64 parameters in a plugin!
|
|
};
|
|
|
|
#define SLIDERHEIGHT 20
|
|
|
|
/*
|
|
Globals
|
|
*/
|
|
HWND gMainHwnd = 0;
|
|
HWND gPluginHwnd = 0;
|
|
HINSTANCE gHinstance = 0;
|
|
FMOD::System *gSystem = 0;
|
|
FMOD::Sound *gSound = 0;
|
|
FMOD::Channel *gChannel = 0;
|
|
FMOD::Sound *gSoundRecord = 0;
|
|
FMOD::Channel *gChannelRecord = 0;
|
|
int gPluginWindowHeight = 5;
|
|
int gPluginWindowWidth = 0;
|
|
WNDPROC gOldProgressProc = 0;
|
|
Plugin gPluginHead;
|
|
BITMAPINFO gGraphicWindowBitmap;
|
|
RGBQUAD gGraphicWindowBitmapData[GRAPHICWINDOW_WIDTH * GRAPHICWINDOW_HEIGHT];
|
|
|
|
|
|
void ERRCHECK(FMOD_RESULT result)
|
|
{
|
|
if (result != FMOD_OK)
|
|
{
|
|
char errstring[1024];
|
|
|
|
sprintf(errstring, "FMOD error! (%d) %s", result, FMOD_ErrorString(result));
|
|
|
|
MessageBox( NULL, errstring, "FMOD error!", MB_ICONHAND|MB_OK|MB_SYSTEMMODAL);
|
|
}
|
|
}
|
|
|
|
LRESULT CALLBACK FMOD_PluginInstanceProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
LRESULT CALLBACK FMOD_TrackbarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
LRESULT CALLBACK FMOD_ProgressWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
LRESULT CALLBACK FMOD_PluginWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
void PlotSpectrum(HDC hdc, int winx, int winy, bool uselog)
|
|
{
|
|
FMOD_RESULT result;
|
|
int count, count2, numchannels;
|
|
float spectrum[8][512];
|
|
float max;
|
|
int x, y;
|
|
HRESULT hr;
|
|
|
|
#define calcoffset(_x, _y) (GRAPHICWINDOW_WIDTH * (_y)) + (_x)
|
|
|
|
result = gSystem->getSoftwareFormat(0, 0, &numchannels, 0, 0, 0);
|
|
if (result != FMOD_OK)
|
|
{
|
|
return;
|
|
}
|
|
|
|
/*
|
|
Draw a black square with grey lines through it.
|
|
*/
|
|
memset(gGraphicWindowBitmapData, 0, GRAPHICWINDOW_WIDTH * GRAPHICWINDOW_HEIGHT * sizeof(RGBQUAD));
|
|
|
|
for (x=0; x < GRAPHICWINDOW_WIDTH; x++)
|
|
{
|
|
RGBQUAD *pixel;
|
|
|
|
for (y = 0; y < 30; y++)
|
|
{
|
|
pixel = &gGraphicWindowBitmapData[calcoffset(x, GRAPHICWINDOW_HEIGHT * y / 30)];
|
|
pixel->rgbRed = 0x40;
|
|
pixel->rgbGreen = 0x40;
|
|
pixel->rgbBlue = 0x40;
|
|
}
|
|
}
|
|
for (x=0; x < GRAPHICWINDOW_WIDTH; x+=64)
|
|
{
|
|
RGBQUAD *pixel;
|
|
|
|
for (y = 0; y < GRAPHICWINDOW_HEIGHT; y++)
|
|
{
|
|
pixel = &gGraphicWindowBitmapData[calcoffset(x, y)];
|
|
pixel->rgbRed = 0x40;
|
|
pixel->rgbGreen = 0x40;
|
|
pixel->rgbBlue = 0x40;
|
|
}
|
|
}
|
|
|
|
max = 0;
|
|
count = 0;
|
|
|
|
for (count = 0; count < numchannels; count++)
|
|
{
|
|
result = gSystem->getSpectrum(spectrum[count], 512, count, FMOD_DSP_FFT_WINDOW_TRIANGLE); /* returns an array of 512 floats */
|
|
if (result != FMOD_OK)
|
|
{
|
|
return;
|
|
}
|
|
|
|
{
|
|
for (count2=0; count2 < 512; count2++)
|
|
{
|
|
if (spectrum[count][count2] > max)
|
|
{
|
|
max = spectrum[count][count2];
|
|
}
|
|
}
|
|
}
|
|
|
|
if (max > 0.0001f)
|
|
{
|
|
/*
|
|
Spectrum graphic is 256 entries wide, and the spectrum is 512 entries.
|
|
The upper band of frequencies at 44khz is pretty boring (ie 11-22khz), so we are only
|
|
going to display the first 256 frequencies, or (0-11khz)
|
|
*/
|
|
for (x = 0; x < 512; x++)
|
|
{
|
|
RGBQUAD *pixel;
|
|
float val, db;
|
|
|
|
val = spectrum[count][x];
|
|
|
|
if (uselog)
|
|
{
|
|
/*
|
|
1.0 = 0db
|
|
0.5 = -6db
|
|
0.25 = -12db
|
|
0.125 = -24db
|
|
|
|
*/
|
|
db = 10.0f * (float)log10(val) * 2.0f;
|
|
|
|
val = db;
|
|
if (val < -150)
|
|
{
|
|
val = -150;
|
|
}
|
|
|
|
val /= -150.0f;
|
|
val = 1.0f - val;
|
|
|
|
y = (int)(val * (float)GRAPHICWINDOW_HEIGHT);
|
|
}
|
|
else
|
|
{
|
|
y = (int)(val / max * (float)GRAPHICWINDOW_HEIGHT);
|
|
}
|
|
|
|
if (y >= GRAPHICWINDOW_HEIGHT)
|
|
{
|
|
y = GRAPHICWINDOW_HEIGHT - 1;
|
|
}
|
|
|
|
for (count2 = 0; count2 < y; count2++)
|
|
{
|
|
int r,g,b;
|
|
|
|
pixel = &gGraphicWindowBitmapData[calcoffset(x * GRAPHICWINDOW_WIDTH / 512, count2)];
|
|
|
|
r = (count2 << 1);
|
|
g = 0xFF - (count2 << 1);
|
|
b = 0x1F;
|
|
|
|
pixel->rgbRed = r > 255 ? 255 : r;
|
|
pixel->rgbGreen = g > 255 ? 255 : g;
|
|
pixel->rgbBlue = b > 255 ? 255 : b;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
hr = SetDIBitsToDevice(
|
|
hdc, // Target device HDC
|
|
winx,
|
|
winy,
|
|
GRAPHICWINDOW_WIDTH, // Destination width
|
|
GRAPHICWINDOW_HEIGHT, // Destination height
|
|
0, // X source position
|
|
0, // Adjusted Y source position
|
|
(UINT)0, // Start scan line
|
|
gGraphicWindowBitmap.bmiHeader.biHeight, // Scan lines present
|
|
gGraphicWindowBitmapData, // Image data
|
|
&gGraphicWindowBitmap, // DIB header
|
|
DIB_RGB_COLORS); // Type of palette
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
void PlotOscilliscope(HDC hdc, int winx, int winy)
|
|
{
|
|
int channel, count, count2, numchannels;
|
|
float xoff, step;
|
|
float *src;
|
|
static float OscBuffer[GRAPHICWINDOW_WIDTH];
|
|
|
|
memset(gGraphicWindowBitmapData, 0, GRAPHICWINDOW_WIDTH * GRAPHICWINDOW_HEIGHT * sizeof(RGBQUAD));
|
|
|
|
gSystem->getSoftwareFormat(0, 0, &numchannels, 0, 0, 0);
|
|
|
|
for (channel = 0; channel < numchannels; channel++)
|
|
{
|
|
gSystem->getWaveData(OscBuffer, GRAPHICWINDOW_WIDTH, channel);
|
|
|
|
/*
|
|
xoff is the x position that is scaled lookup of the dsp block according to the graphical
|
|
window size.
|
|
*/
|
|
xoff = 0;
|
|
step = 1;
|
|
|
|
src = OscBuffer;
|
|
for (count=0; count < GRAPHICWINDOW_WIDTH; count++)
|
|
{
|
|
RGBQUAD *pixel;
|
|
int x, y, y2;
|
|
|
|
#define calcoffset2(_x, _y) (GRAPHICWINDOW_WIDTH * _y) + _x
|
|
|
|
x = (int)xoff;
|
|
y = (int)((src[x] + 1.0f) / 2.0f * (float)GRAPHICWINDOW_HEIGHT);
|
|
y2 = (int)((src[x+(int)step] + 1.0f) / 2.0f * (float)GRAPHICWINDOW_HEIGHT);
|
|
|
|
y = y < 0 ? 0 : y >= GRAPHICWINDOW_HEIGHT ? GRAPHICWINDOW_HEIGHT-1 : y;
|
|
y2 = y2 < 0 ? 0 : y2 >= GRAPHICWINDOW_HEIGHT ? GRAPHICWINDOW_HEIGHT-1 : y2;
|
|
|
|
if (y > y2)
|
|
{
|
|
int tmp = y;
|
|
y = y2;
|
|
y2 = tmp;
|
|
}
|
|
|
|
for (count2=y; count2<= y2; count2++)
|
|
{
|
|
pixel = &gGraphicWindowBitmapData[calcoffset2(count, count2)];
|
|
pixel->rgbRed = 0xff;
|
|
pixel->rgbGreen = 0xff;
|
|
pixel->rgbBlue = 0xaf;
|
|
}
|
|
|
|
xoff += step;
|
|
}
|
|
}
|
|
|
|
SetDIBitsToDevice(
|
|
hdc, // Target device HDC
|
|
winx,
|
|
winy,
|
|
GRAPHICWINDOW_WIDTH, // Destination width
|
|
GRAPHICWINDOW_HEIGHT, // Destination height
|
|
0, // X source position
|
|
0, // Adjusted Y source position
|
|
(UINT)0, // Start scan line
|
|
gGraphicWindowBitmap.bmiHeader.biHeight, // Scan lines present
|
|
gGraphicWindowBitmapData, // Image data
|
|
&gGraphicWindowBitmap, // DIB header
|
|
DIB_RGB_COLORS); // Type of palette
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT RefreshPluginList()
|
|
{
|
|
RECT rect;
|
|
SCROLLINFO scrollinfo;
|
|
Plugin *plugin;
|
|
|
|
gPluginWindowWidth = 0;
|
|
gPluginWindowHeight = 5;
|
|
|
|
GetWindowRect(gPluginHwnd, &rect);
|
|
InvalidateRect(gPluginHwnd, &rect, TRUE);
|
|
|
|
/*
|
|
Now re-add using new list.
|
|
*/
|
|
plugin = gPluginHead.next;
|
|
while (plugin != &gPluginHead)
|
|
{
|
|
MoveWindow(plugin->hwnd, 5,
|
|
gPluginWindowHeight,
|
|
plugin->configwidth > plugin->windowwidth ? plugin->configwidth : plugin->windowwidth,
|
|
plugin->windowheight + (plugin->configactive ? plugin->configheight : 0),
|
|
TRUE);
|
|
|
|
gPluginWindowHeight += plugin->windowheight;
|
|
if (plugin->windowwidth > gPluginWindowWidth)
|
|
{
|
|
gPluginWindowWidth = plugin->windowwidth;
|
|
}
|
|
|
|
if (plugin->configactive)
|
|
{
|
|
gPluginWindowHeight += 5; /* gap below sliders and gui */
|
|
gPluginWindowHeight += plugin->configheight;
|
|
if (plugin->configwidth + 5 > gPluginWindowWidth)
|
|
{
|
|
gPluginWindowWidth = plugin->configwidth;
|
|
}
|
|
}
|
|
|
|
gPluginWindowHeight += 5; /* gap below plugin */
|
|
|
|
plugin = plugin->next;
|
|
}
|
|
|
|
memset(&scrollinfo, 0, sizeof(SCROLLINFO));
|
|
scrollinfo.cbSize = sizeof(SCROLLINFO);
|
|
scrollinfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
scrollinfo.nMin = 0;
|
|
scrollinfo.nMax = gPluginWindowHeight;
|
|
scrollinfo.nPage = rect.bottom / 2;
|
|
scrollinfo.nPos = 0;
|
|
SetScrollInfo(gPluginHwnd, SB_VERT, &scrollinfo, TRUE);
|
|
|
|
memset(&scrollinfo, 0, sizeof(SCROLLINFO));
|
|
scrollinfo.cbSize = sizeof(SCROLLINFO);
|
|
scrollinfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
scrollinfo.nMin = 0;
|
|
scrollinfo.nMax = gPluginWindowWidth;
|
|
scrollinfo.nPage = (rect.right - rect.left) - 35;
|
|
scrollinfo.nPos = 0;
|
|
SetScrollInfo(gPluginHwnd, SB_HORZ, &scrollinfo, TRUE);
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT RemovePlugin(Plugin *plugin)
|
|
{
|
|
FMOD_RESULT result;
|
|
|
|
if (plugin->hwnd)
|
|
{
|
|
DestroyWindow(plugin->hwnd);
|
|
}
|
|
|
|
plugin->next->prev = plugin->prev;
|
|
plugin->prev->next = plugin->next;
|
|
|
|
result = plugin->dsp->release();
|
|
ERRCHECK(result);
|
|
|
|
RefreshPluginList();
|
|
|
|
delete [] plugin->param;
|
|
delete plugin;
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
FMOD_RESULT AddPlugin(char *name, char *displayname)
|
|
{
|
|
FMOD_RESULT result;
|
|
FMOD_PLUGINTYPE plugintype;
|
|
Plugin *plugin;
|
|
unsigned int handle;
|
|
|
|
result = gSystem->loadPlugin(name, &handle);
|
|
if (result != FMOD_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
result = gSystem->getPluginInfo(handle, &plugintype, 0,0,0);
|
|
if (result != FMOD_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
if (plugintype != FMOD_PLUGINTYPE_DSP)
|
|
{
|
|
gSystem->unloadPlugin(handle);
|
|
return FMOD_ERR_PLUGIN;
|
|
}
|
|
|
|
plugin = new Plugin;
|
|
if (!plugin)
|
|
{
|
|
return FMOD_ERR_MEMORY;
|
|
}
|
|
|
|
memset(plugin, 0, sizeof(Plugin));
|
|
|
|
result = gSystem->createDSPByPlugin(handle, &plugin->dsp);
|
|
if (result != FMOD_OK)
|
|
{
|
|
return result;
|
|
}
|
|
|
|
/*
|
|
Add to end of circular linked list.
|
|
*/
|
|
plugin->prev = gPluginHead.prev;
|
|
gPluginHead.prev->next = plugin;
|
|
gPluginHead.prev = plugin;
|
|
plugin->next = &gPluginHead;
|
|
|
|
/*
|
|
Add the plugin dialogue to the plugin window
|
|
*/
|
|
{
|
|
RECT rect;
|
|
SCROLLINFO scrollinfo;
|
|
char name[256], s[256];
|
|
unsigned int version = 0;
|
|
int count2;
|
|
|
|
GetWindowRect(gPluginHwnd, &rect);
|
|
|
|
plugin->dsp->getInfo(name, &version, 0, &plugin->configwidth, &plugin->configheight);
|
|
plugin->dsp->getNumParameters(&plugin->numparams);
|
|
|
|
sprintf(s, "%s %1x.%2x", name, version >> 16, version & 0xFFFF);
|
|
|
|
plugin->windowheight = ((plugin->numparams + 1) * (SLIDERHEIGHT + 5)) + 10;
|
|
plugin->windowwidth = (rect.right - rect.left) - 35;
|
|
plugin->hwnd = CreateWindow("STATIC", s, WS_BORDER | WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE, 5, gPluginWindowHeight, plugin->windowwidth, plugin->windowheight, gPluginHwnd, NULL, 0, 0);
|
|
plugin->removehwnd = CreateWindow("BUTTON", "Remove", WS_CHILD | WS_VISIBLE, plugin->windowwidth - 105, 5, 100, 20, plugin->hwnd, (HMENU)IDC_REMOVEBUTTON, 0, 0);
|
|
plugin->confighwnd = CreateWindow("BUTTON", "Config", WS_CHILD | WS_VISIBLE, plugin->windowwidth - 210, 5, 100, 20, plugin->hwnd, (HMENU)IDC_CONFIGBUTTON, 0, 0);
|
|
plugin->activehwnd = CreateWindow("BUTTON", "Active", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, plugin->windowwidth - 315, 5, 100, 20, plugin->hwnd, (HMENU)IDC_ACTIVEBUTTON, 0, 0);
|
|
plugin->configactive = false;
|
|
|
|
SetWindowLongPtr(plugin->hwnd, GWLP_USERDATA, (LONG_PTR)plugin);
|
|
plugin->oldpluginproc = (WNDPROC)GetWindowLongPtr(plugin->hwnd, GWLP_WNDPROC);
|
|
SetWindowLongPtr(plugin->hwnd, GWLP_WNDPROC, (LONG_PTR)FMOD_PluginInstanceProc);
|
|
|
|
plugin->param = new PluginParam[plugin->numparams];
|
|
memset(plugin->param, 0, sizeof(PluginParam) * plugin->numparams);
|
|
|
|
/*
|
|
Now add sliders for each plugin
|
|
*/
|
|
for (count2 = 0; count2 < plugin->numparams; count2++)
|
|
{
|
|
PluginParam *param = &plugin->param[count2];
|
|
char paramname[32], label[32], valuestr[32];
|
|
float value, scale;
|
|
int x = 0, sliderwidth;
|
|
|
|
plugin->dsp->getParameterInfo(count2, paramname, label, 0, 0, ¶m->min, ¶m->max);
|
|
plugin->dsp->getParameter(count2, &value, valuestr, 32);
|
|
|
|
sliderwidth = (rect.right - rect.left) - 350;
|
|
|
|
param->plugin = plugin;
|
|
param->index = count2;
|
|
scale = sliderwidth / fabsf(param->max - param->min);
|
|
|
|
sprintf(s, "%s %s", valuestr, label);
|
|
x = 5;
|
|
param->namehwnd = CreateWindow("STATIC", paramname, WS_CHILD | WS_VISIBLE, x, 30 + (count2 * (SLIDERHEIGHT + 5)), 150-5, SLIDERHEIGHT, plugin->hwnd, NULL, 0, 0);
|
|
x += 145;
|
|
param->sliderhwnd = CreateWindow(TRACKBAR_CLASS, "", WS_CHILD | WS_VISIBLE, x, 30 + (count2 * (SLIDERHEIGHT + 5)), sliderwidth, SLIDERHEIGHT, plugin->hwnd, NULL, 0, 0);
|
|
x += sliderwidth;
|
|
param->valuehwnd = CreateWindow("STATIC", s, WS_CHILD | WS_VISIBLE, x, 30 + (count2 * (SLIDERHEIGHT + 5)), 150-5, SLIDERHEIGHT, plugin->hwnd, NULL, 0, 0);
|
|
/*
|
|
Subclass the position slider so we can get the mouse messages and process them there
|
|
*/
|
|
SetWindowLongPtr(param->sliderhwnd, GWLP_USERDATA, (LONG_PTR)param);
|
|
param->oldtrackbarproc = (WNDPROC)GetWindowLongPtr(param->sliderhwnd, GWLP_WNDPROC);
|
|
SetWindowLongPtr(param->sliderhwnd, GWLP_WNDPROC, (LONG_PTR)FMOD_TrackbarProc);
|
|
|
|
SendMessage(param->sliderhwnd, TBM_SETRANGE, (WPARAM)TRUE, (LPARAM)MAKELONG(0, sliderwidth));
|
|
SendMessage(param->sliderhwnd, TBM_SETPAGESIZE, (WPARAM)0, (LPARAM)scale);
|
|
SendMessage(param->sliderhwnd, TBM_SETPOS, (WPARAM)TRUE, (LPARAM)( (value - param->min) / (param->max - param->min) * sliderwidth ));
|
|
|
|
}
|
|
|
|
gPluginWindowHeight += (plugin->windowheight + 5);
|
|
|
|
|
|
memset(&scrollinfo, 0, sizeof(SCROLLINFO));
|
|
scrollinfo.cbSize = sizeof(SCROLLINFO);
|
|
scrollinfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
scrollinfo.nMin = 0;
|
|
scrollinfo.nMax = gPluginWindowHeight- 30;
|
|
scrollinfo.nPage = rect.bottom / 2;
|
|
SetScrollInfo(gPluginHwnd, SB_VERT, &scrollinfo, TRUE);
|
|
|
|
memset(&scrollinfo, 0, sizeof(SCROLLINFO));
|
|
scrollinfo.cbSize = sizeof(SCROLLINFO);
|
|
scrollinfo.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
|
|
scrollinfo.nMin = 0;
|
|
scrollinfo.nMax = gPluginWindowWidth;
|
|
scrollinfo.nPage = (rect.right - rect.left) - 35;
|
|
SetScrollInfo(gPluginHwnd, SB_HORZ, &scrollinfo, TRUE);
|
|
}
|
|
|
|
return FMOD_OK;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
LRESULT CALLBACK FMOD_ProgressWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (message)
|
|
{
|
|
case WM_LBUTTONDOWN:
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
FMOD_RESULT result;
|
|
RECT r;
|
|
int width, xpos = LOWORD(lParam); // horizontal position of cursor
|
|
unsigned int length;
|
|
|
|
if (message == WM_MOUSEMOVE && wParam != MK_LBUTTON)
|
|
{
|
|
break;
|
|
}
|
|
|
|
GetWindowRect(hwnd, &r);
|
|
width = r.right - r.left;
|
|
|
|
result = gSound->getLength(&length, FMOD_TIMEUNIT_MODORDER);
|
|
if (result != FMOD_OK)
|
|
{
|
|
gSound->getLength(&length, FMOD_TIMEUNIT_MS);
|
|
}
|
|
|
|
result = gChannel->setPosition((unsigned int)((float)length / (float)width * (float)xpos), FMOD_TIMEUNIT_MODORDER);
|
|
if (result != FMOD_OK)
|
|
{
|
|
gChannel->setPosition((unsigned int)((float)length / (float)width * (float)xpos), FMOD_TIMEUNIT_MS);
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
|
|
return (long)CallWindowProc(gOldProgressProc, hwnd, message, wParam, lParam);
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
LRESULT CALLBACK FMOD_PluginInstanceProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WNDPROC oldpluginproc;
|
|
|
|
Plugin *plugin = (Plugin *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
|
|
oldpluginproc = plugin->oldpluginproc;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_ACTIVEBUTTON:
|
|
{
|
|
if (Button_GetCheck(plugin->activehwnd))
|
|
{
|
|
gSystem->addDSP(plugin->dsp, 0);
|
|
}
|
|
else if (!Button_GetCheck(plugin->activehwnd))
|
|
{
|
|
plugin->dsp->remove();
|
|
}
|
|
break;
|
|
}
|
|
case IDC_REMOVEBUTTON:
|
|
{
|
|
RemovePlugin(plugin);
|
|
break;
|
|
}
|
|
case IDC_CONFIGBUTTON:
|
|
{
|
|
if (plugin->dsp)
|
|
{
|
|
if (plugin->configactive)
|
|
{
|
|
plugin->dsp->showConfigDialog(hwnd, false);
|
|
DestroyWindow(plugin->configguihwnd);
|
|
|
|
plugin->configactive = false;
|
|
RefreshPluginList();
|
|
|
|
plugin->configguihwnd = 0;
|
|
}
|
|
else
|
|
{
|
|
plugin->configactive = true;
|
|
RefreshPluginList();
|
|
plugin->configguihwnd = CreateWindow("STATIC",
|
|
"",
|
|
WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE,
|
|
5,
|
|
plugin->windowheight,
|
|
plugin->configwidth,
|
|
plugin->configheight,
|
|
plugin->hwnd,
|
|
NULL,
|
|
0,
|
|
0);
|
|
plugin->dsp->showConfigDialog(plugin->configguihwnd, true);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
|
|
return CallWindowProc(oldpluginproc, hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
LRESULT CALLBACK FMOD_TrackbarProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
PluginParam *param = (PluginParam *)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
|
bool update = false;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_KEYUP:
|
|
case WM_KEYDOWN:
|
|
{
|
|
update = true;
|
|
break;
|
|
}
|
|
case WM_LBUTTONDOWN:
|
|
{
|
|
param->dragging = TRUE;
|
|
update = true;
|
|
break;
|
|
}
|
|
case WM_LBUTTONUP:
|
|
{
|
|
param->dragging = FALSE;
|
|
break;
|
|
}
|
|
case WM_MOUSEMOVE:
|
|
{
|
|
if (param->dragging)
|
|
{
|
|
update = true;
|
|
}
|
|
break;
|
|
}
|
|
};
|
|
|
|
if (update)
|
|
{
|
|
RECT rect;
|
|
int pos = (int)SendMessage(hwnd, TBM_GETPOS, 0, 0);
|
|
float value;
|
|
char valuestr[32];
|
|
char label[32];
|
|
char s[256];
|
|
int sliderwidth;
|
|
|
|
GetWindowRect(hwnd, &rect);
|
|
|
|
sliderwidth = rect.right - rect.left;
|
|
|
|
value = (float)pos + 0.5f;
|
|
value /= sliderwidth;
|
|
value *= (param->max - param->min);
|
|
value += param->min;
|
|
|
|
param->plugin->dsp->getParameterInfo(param->index, 0, label, 0, 0, 0, 0);
|
|
param->plugin->dsp->setParameter(param->index, value);
|
|
param->plugin->dsp->getParameter(param->index, 0, valuestr, 32);
|
|
|
|
sprintf(s, "%s %s", valuestr, label);
|
|
|
|
SendMessage(param->valuehwnd, WM_SETTEXT, 0, (LPARAM)s);
|
|
}
|
|
|
|
return CallWindowProc(param->oldtrackbarproc, hwnd, msg, wParam, lParam);
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
LRESULT CALLBACK FMOD_PluginWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
switch (msg)
|
|
{
|
|
case WM_HSCROLL:
|
|
{
|
|
int lineWidth = 1;
|
|
|
|
switch (LOWORD(wParam))
|
|
{
|
|
int OldPos, NewPos;
|
|
|
|
case SB_PAGEDOWN:
|
|
case SB_LINEDOWN:
|
|
OldPos = GetScrollPos (hwnd, SB_HORZ);
|
|
SetScrollPos (hwnd, SB_HORZ, (OldPos+1), TRUE);
|
|
NewPos = GetScrollPos (hwnd, SB_HORZ);
|
|
ScrollWindow (hwnd, (OldPos-NewPos)*lineWidth, 0, NULL, NULL);
|
|
break;
|
|
case SB_PAGEUP:
|
|
case SB_LINEUP:
|
|
OldPos = GetScrollPos (hwnd, SB_HORZ);
|
|
SetScrollPos (hwnd, SB_HORZ, (OldPos-1), TRUE);
|
|
NewPos = GetScrollPos (hwnd, SB_HORZ);
|
|
ScrollWindow (hwnd, (OldPos-NewPos)*lineWidth, 0, NULL, NULL);
|
|
break;
|
|
case SB_THUMBPOSITION:
|
|
case SB_THUMBTRACK:
|
|
OldPos = GetScrollPos (hwnd, SB_HORZ);
|
|
NewPos = HIWORD (wParam);
|
|
SetScrollPos (hwnd, SB_HORZ, NewPos, TRUE);
|
|
ScrollWindow (hwnd, (OldPos-NewPos)*lineWidth, 0, NULL, NULL);
|
|
break;
|
|
} ;
|
|
break;
|
|
}
|
|
case WM_VSCROLL:
|
|
{
|
|
int lineHeight = 1;
|
|
|
|
switch (LOWORD(wParam))
|
|
{
|
|
int OldPos, NewPos;
|
|
|
|
case SB_PAGEDOWN:
|
|
case SB_LINEDOWN:
|
|
OldPos = GetScrollPos (hwnd, SB_VERT);
|
|
SetScrollPos (hwnd, SB_VERT, (OldPos+1), TRUE);
|
|
NewPos = GetScrollPos (hwnd, SB_VERT);
|
|
ScrollWindow (hwnd, 0,(OldPos-NewPos)*lineHeight, NULL, NULL);
|
|
break;
|
|
case SB_PAGEUP:
|
|
case SB_LINEUP:
|
|
OldPos = GetScrollPos (hwnd, SB_VERT);
|
|
SetScrollPos (hwnd, SB_VERT, (OldPos-1), TRUE);
|
|
NewPos = GetScrollPos (hwnd, SB_VERT);
|
|
ScrollWindow (hwnd, 0,(OldPos-NewPos)*lineHeight, NULL, NULL);
|
|
break;
|
|
case SB_THUMBPOSITION:
|
|
case SB_THUMBTRACK:
|
|
OldPos = GetScrollPos (hwnd, SB_VERT);
|
|
NewPos = HIWORD (wParam);
|
|
SetScrollPos (hwnd, SB_VERT, NewPos, TRUE);
|
|
ScrollWindow (hwnd, 0, (OldPos-NewPos)*lineHeight, NULL, NULL);
|
|
break;
|
|
} ;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return DefWindowProc (hwnd, msg, wParam, lParam) ;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
#ifdef _WIN64
|
|
INT_PTR
|
|
#else
|
|
BOOL
|
|
#endif
|
|
CALLBACK FMOD_DlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
#ifdef _WIN64
|
|
static UINT_PTR timerid = 0;
|
|
#else
|
|
static int timerid = 0;
|
|
#endif
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
/*
|
|
SET UP A PAINT TIMER FOR INTERFACE
|
|
*/
|
|
timerid = SetTimer(hwnd, 0, 10, (TIMERPROC)0);
|
|
if (!timerid)
|
|
{
|
|
MessageBox( NULL, "Too many timers in use", "Error", MB_ICONHAND|MB_OK|MB_SYSTEMMODAL);
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
Set up the child plugin window
|
|
*/
|
|
{
|
|
RECT recordrect;
|
|
RECT rect;
|
|
WNDCLASS wc;
|
|
char szWindowClass[] = { TEXT("Plugin Window") };
|
|
|
|
memset(&wc, 0, sizeof(WNDCLASS));
|
|
wc.style = CS_HREDRAW | CS_VREDRAW;
|
|
wc.lpfnWndProc = (WNDPROC)FMOD_PluginWindowProc;
|
|
wc.hInstance = gHinstance;
|
|
wc.hIcon = 0;
|
|
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
|
wc.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
|
|
wc.lpszMenuName = 0;
|
|
wc.lpszClassName = szWindowClass;
|
|
|
|
RegisterClass(&wc);
|
|
|
|
GetWindowRect(hwnd, &rect);
|
|
GetWindowRect(GetDlgItem(hwnd, IDC_STATIC_RECORD), &recordrect);
|
|
|
|
gPluginHwnd = CreateWindowEx(WS_EX_CLIENTEDGE, szWindowClass, "", WS_CHILD | WS_VSCROLL | WS_HSCROLL | WS_CLIPSIBLINGS | WS_VISIBLE, 5, recordrect.bottom, rect.right - rect.left - 25, (rect.bottom - rect.top) - recordrect.bottom - 65, hwnd, 0, 0, 0);
|
|
}
|
|
|
|
gPluginHead.next = &gPluginHead;
|
|
gPluginHead.prev = &gPluginHead;
|
|
|
|
gOldProgressProc = (WNDPROC)GetWindowLongPtr(GetDlgItem(hwnd, IDC_PROGRESS1), GWLP_WNDPROC);
|
|
SetWindowLongPtr(GetDlgItem(hwnd, IDC_PROGRESS1), GWLP_WNDPROC, (LONG)&FMOD_ProgressWindowProc);
|
|
|
|
return TRUE;
|
|
}
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDC_OPENBUTTON:
|
|
{
|
|
OPENFILENAME ofn; /* common dialog box structure */
|
|
char szDirName[MAX_PATH]; /* directory string */
|
|
char szFile[20481]; /* filename string */
|
|
char szFileTitle[4096]; /* filename string */
|
|
|
|
/*
|
|
Obtain the system directory name and store it in szDirName.
|
|
*/
|
|
GetSystemDirectory(szDirName, sizeof(szDirName));
|
|
|
|
/*
|
|
Place the terminating null character in the szFile.
|
|
*/
|
|
szFile[0] = '\0';
|
|
szFileTitle[0] = '\0';
|
|
|
|
/*
|
|
Set the members of the OPENFILENAME structure.
|
|
*/
|
|
memset(&ofn, 0, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hwnd;
|
|
ofn.lpstrTitle = "Open\0";
|
|
ofn.lpstrFilter = "All audio files (*.*)\0*.*\0\0";
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.nMaxFile = 20480; /* Huge value allows many files to be multi-selected */
|
|
ofn.lpstrFileTitle = szFileTitle;
|
|
ofn.nMaxFileTitle = 2048;
|
|
ofn.lpstrInitialDir = ".\0";
|
|
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST;
|
|
|
|
/*
|
|
Display the Open dialog box.
|
|
*/
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
FMOD_RESULT result;
|
|
|
|
if (gSound)
|
|
{
|
|
if (gChannel)
|
|
{
|
|
gChannel->stop();
|
|
gChannel = 0;
|
|
SendMessage(GetDlgItem(hwnd, IDC_PLAY), WM_SETTEXT, 0, (LPARAM)"Play");
|
|
}
|
|
gSound->release();
|
|
}
|
|
result = gSystem->createStream(ofn.lpstrFile, FMOD_2D | FMOD_SOFTWARE, 0, &gSound);
|
|
ERRCHECK(result);
|
|
|
|
SendMessage(GetDlgItem(hwnd, IDC_EDIT1), WM_SETTEXT, 0, (LPARAM)ofn.lpstrFile);
|
|
}
|
|
break;
|
|
}
|
|
case IDC_PLAY:
|
|
{
|
|
bool isplaying = false;;
|
|
|
|
if (gChannel)
|
|
{
|
|
gChannel->isPlaying(&isplaying);
|
|
}
|
|
|
|
if (isplaying || !gSound)
|
|
{
|
|
if (gChannel)
|
|
{
|
|
gChannel->stop();
|
|
gChannel = 0;
|
|
}
|
|
SendMessage(GetDlgItem(hwnd, IDC_PLAY), WM_SETTEXT, 0, (LPARAM)"Play");
|
|
}
|
|
else
|
|
{
|
|
gSystem->playSound(FMOD_CHANNEL_FREE, gSound, false, &gChannel);
|
|
SendMessage(GetDlgItem(hwnd, IDC_PLAY), WM_SETTEXT, 0, (LPARAM)"Stop");
|
|
}
|
|
break;
|
|
}
|
|
case IDC_PAUSE:
|
|
{
|
|
if (gChannel)
|
|
{
|
|
bool paused;
|
|
|
|
gChannel->getPaused(&paused);
|
|
if (paused)
|
|
{
|
|
gChannel->setPaused(false);
|
|
SendMessage(GetDlgItem(hwnd, IDC_PAUSE), WM_SETTEXT, 0, (LPARAM)"Pause");
|
|
}
|
|
else
|
|
{
|
|
gChannel->setPaused(true);
|
|
SendMessage(GetDlgItem(hwnd, IDC_PAUSE), WM_SETTEXT, 0, (LPARAM)"UnPause");
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case IDC_RECORD:
|
|
{
|
|
if (!gSoundRecord)
|
|
{
|
|
FMOD_RESULT result;
|
|
FMOD_OUTPUTTYPE output;
|
|
FMOD_CREATESOUNDEXINFO exinfo;
|
|
|
|
FMOD_MODE mode = FMOD_2D | FMOD_OPENUSER;
|
|
|
|
mode |= FMOD_LOOP_NORMAL;
|
|
mode |= FMOD_SOFTWARE;
|
|
|
|
#define USERLENGTH (44100 * 5)
|
|
|
|
memset(&exinfo, 0, sizeof(FMOD_CREATESOUNDEXINFO));
|
|
exinfo.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
|
|
exinfo.length = USERLENGTH * 2 * sizeof(short);
|
|
exinfo.numchannels = 2;
|
|
exinfo.defaultfrequency = 44100;
|
|
exinfo.format = FMOD_SOUND_FORMAT_PCM16;
|
|
|
|
result = gSystem->createSound(0, mode, &exinfo, &gSoundRecord);
|
|
ERRCHECK(result);
|
|
|
|
result = gSystem->recordStart(0, gSoundRecord, true);
|
|
ERRCHECK(result);
|
|
|
|
gSystem->getOutput(&output);
|
|
if (output != FMOD_OUTPUTTYPE_ASIO)
|
|
{
|
|
Sleep(100);
|
|
}
|
|
|
|
result = gSystem->playSound(FMOD_CHANNEL_FREE, gSoundRecord, false, &gChannelRecord);
|
|
ERRCHECK(result);
|
|
|
|
SendMessage(GetDlgItem(hwnd, IDC_RECORD), WM_SETTEXT, 0, (LPARAM)"Stop Recording");
|
|
}
|
|
else
|
|
{
|
|
gSystem->recordStop(0);
|
|
|
|
gChannelRecord->stop();
|
|
gChannelRecord = 0;
|
|
gSoundRecord->release();
|
|
gSoundRecord = 0;
|
|
|
|
SendMessage(GetDlgItem(hwnd, IDC_RECORD), WM_SETTEXT, 0, (LPARAM)"Record");
|
|
}
|
|
break;
|
|
}
|
|
case IDC_ADDPLUGIN:
|
|
{
|
|
OPENFILENAME ofn; /* common dialog box structure */
|
|
char szDirName[MAX_PATH]; /* directory string */
|
|
char szFile[20481]; /* filename string */
|
|
char szFileTitle[4096]; /* filename string */
|
|
|
|
/*
|
|
Obtain the system directory name and store it in szDirName.
|
|
*/
|
|
GetSystemDirectory(szDirName, sizeof(szDirName));
|
|
|
|
/*
|
|
Place the terminating null character in the szFile.
|
|
*/
|
|
szFile[0] = '\0';
|
|
szFileTitle[0] = '\0';
|
|
|
|
/*
|
|
Set the members of the OPENFILENAME structure.
|
|
*/
|
|
memset(&ofn, 0, sizeof(ofn));
|
|
ofn.lStructSize = sizeof(OPENFILENAME);
|
|
ofn.hwndOwner = hwnd;
|
|
ofn.lpstrTitle = "Open\0";
|
|
ofn.lpstrFilter = "FMOD Plugins (dsp*.dll)\0dsp*.dll\0VST Plugins (*.dll)\0*.dll\0All files (*.*)\0*.*\0\0";
|
|
ofn.lpstrCustomFilter = NULL;
|
|
ofn.nFilterIndex = 1;
|
|
ofn.lpstrFile = szFile;
|
|
ofn.nMaxFile = 20480; /* Huge value allows many files to be multi-selected */
|
|
ofn.lpstrFileTitle = szFileTitle;
|
|
ofn.nMaxFileTitle = 2048;
|
|
ofn.lpstrInitialDir = "..\\..\\api\\plugins\0";
|
|
ofn.Flags = OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_ALLOWMULTISELECT;
|
|
|
|
/*
|
|
Display the Open dialog box.
|
|
*/
|
|
if (GetOpenFileName(&ofn))
|
|
{
|
|
char *path = ofn.lpstrFile;
|
|
char *fname = ofn.lpstrFile;
|
|
char name[256];
|
|
|
|
/*
|
|
Single file
|
|
*/
|
|
if (ofn.nFileOffset)
|
|
{
|
|
/*
|
|
Skip to the first filename
|
|
*/
|
|
fname +=ofn.nFileOffset;
|
|
*(fname-1) = 0; /* clear the backslash before the filename so the loop below handles it */
|
|
}
|
|
/*
|
|
Multiple files
|
|
*/
|
|
else
|
|
{
|
|
while (*fname++); /* search to the first filename */
|
|
}
|
|
|
|
do
|
|
{
|
|
FMOD_RESULT result;
|
|
|
|
/*
|
|
Put path in name
|
|
*/
|
|
sprintf(name, "%s%s%s", path, "\\", fname);
|
|
|
|
/*
|
|
Open the file.
|
|
*/
|
|
result = AddPlugin(name, fname);
|
|
ERRCHECK(result);
|
|
|
|
while (*fname++);
|
|
|
|
Sleep(1);
|
|
|
|
} while (*fname);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case WM_CLOSE:
|
|
{
|
|
FMOD_RESULT result;
|
|
|
|
KillTimer(hwnd, timerid);
|
|
|
|
/*
|
|
The timer doesnt die immediately, sleep for a bit to let it die so we dont free streams then the timer tries to access them
|
|
*/
|
|
Sleep(200);
|
|
|
|
/*
|
|
Shutdown FMOD
|
|
*/
|
|
if (gSound)
|
|
{
|
|
result = gSound->release();
|
|
ERRCHECK(result);
|
|
}
|
|
if (gSystem)
|
|
{
|
|
result = gSystem->close();
|
|
ERRCHECK(result);
|
|
|
|
result = gSystem->release();
|
|
ERRCHECK(result);
|
|
}
|
|
|
|
EndDialog(hwnd,0);
|
|
PostQuitMessage(0);
|
|
return TRUE;
|
|
}
|
|
|
|
case WM_TIMER :
|
|
{
|
|
HDC hdc = GetDC(hwnd);
|
|
RECT rect;
|
|
|
|
GetWindowRect(GetDlgItem(gMainHwnd,IDC_STATIC_ANALYZER), &rect);
|
|
|
|
gSystem->update();
|
|
|
|
PlotSpectrum(hdc, (((rect.right - rect.left) / 4) - (GRAPHICWINDOW_WIDTH / 2)),
|
|
(((rect.bottom - rect.top) / 2) - (GRAPHICWINDOW_HEIGHT / 2)), true);
|
|
PlotOscilliscope(hdc, ((((rect.right - rect.left) / 4) * 3) - (GRAPHICWINDOW_WIDTH / 2)),
|
|
(((rect.bottom - rect.top) / 2) - (GRAPHICWINDOW_HEIGHT / 2)));
|
|
|
|
if (gChannel)
|
|
{
|
|
FMOD_RESULT result;
|
|
unsigned int currtime, length;
|
|
bool playing;
|
|
|
|
result = gChannel->getPosition(&currtime, FMOD_TIMEUNIT_MODORDER);
|
|
if (result != FMOD_OK)
|
|
{
|
|
gChannel->getPosition(&currtime, FMOD_TIMEUNIT_MS);
|
|
}
|
|
|
|
result = gSound->getLength(&length, FMOD_TIMEUNIT_MODORDER);
|
|
if (result != FMOD_OK)
|
|
{
|
|
gSound->getLength(&length, FMOD_TIMEUNIT_MS);
|
|
}
|
|
|
|
SendMessage(GetDlgItem(gMainHwnd,IDC_PROGRESS1), PBM_SETRANGE, 0, MAKELPARAM(0, 1000) );
|
|
SendMessage(GetDlgItem(gMainHwnd,IDC_PROGRESS1), PBM_SETPOS, (WPARAM)((float)currtime / (float)length * 1000.0f), 0);
|
|
|
|
gChannel->isPlaying(&playing);
|
|
if (!playing)
|
|
{
|
|
gChannel = 0;
|
|
SendMessage(GetDlgItem(hwnd, IDC_PLAY), WM_SETTEXT, 0, (LPARAM)"Play");
|
|
}
|
|
}
|
|
|
|
ReleaseDC(hwnd, hdc);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
#ifdef _WIN64
|
|
INT_PTR
|
|
#else
|
|
BOOL
|
|
#endif
|
|
CALLBACK FMOD_OutputSelectProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
static int selected = 0;
|
|
|
|
switch (msg)
|
|
{
|
|
case WM_INITDIALOG:
|
|
{
|
|
Button_SetCheck(GetDlgItem(hwnd,IDC_DSOUND), TRUE);
|
|
return TRUE;
|
|
}
|
|
case WM_COMMAND:
|
|
{
|
|
switch (LOWORD(wParam))
|
|
{
|
|
case IDOK:
|
|
{
|
|
if (Button_GetCheck(GetDlgItem(hwnd,IDC_DSOUND)))
|
|
{
|
|
selected = 0;
|
|
}
|
|
if (Button_GetCheck(GetDlgItem(hwnd,IDC_WINMM)))
|
|
{
|
|
selected = 1;
|
|
}
|
|
if (Button_GetCheck(GetDlgItem(hwnd,IDC_ASIO)))
|
|
{
|
|
selected = 2;
|
|
}
|
|
|
|
EndDialog(hwnd, selected);
|
|
break;
|
|
}
|
|
case IDCANCEL:
|
|
{
|
|
EndDialog(hwnd, -1);
|
|
PostQuitMessage(0);
|
|
break;
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
case WM_CLOSE:
|
|
{
|
|
EndDialog(hwnd, -1);
|
|
PostQuitMessage(0);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/*
|
|
[
|
|
[DESCRIPTION]
|
|
|
|
[PARAMETERS]
|
|
|
|
[RETURN_VALUE]
|
|
|
|
[REMARKS]
|
|
|
|
[SEE_ALSO]
|
|
]
|
|
*/
|
|
int Initialize(HINSTANCE hinst, LPSTR lpCmdLine)
|
|
{
|
|
FMOD_RESULT result;
|
|
unsigned int version;
|
|
#ifdef _WIN64
|
|
INT_PTR retval;
|
|
#else
|
|
int retval;
|
|
#endif
|
|
|
|
/*
|
|
Initialise FMOD
|
|
*/
|
|
|
|
result = FMOD::Memory_Initialize(malloc(10 * 1024*1024), 10 * 1024*1024, 0, 0, 0);
|
|
ERRCHECK(result);
|
|
|
|
result = FMOD::System_Create(&gSystem);
|
|
ERRCHECK(result);
|
|
|
|
result = gSystem->getVersion(&version);
|
|
ERRCHECK(result);
|
|
|
|
if (version < FMOD_VERSION)
|
|
{
|
|
MessageBox(GetForegroundWindow(), "INCORRECT DLL VERSION!!", "FMOD ERROR", MB_OK);
|
|
}
|
|
|
|
#ifdef _WIN64
|
|
result = gSystem->setPluginPath("../../api/plugins/64bit");
|
|
#else
|
|
result = gSystem->setPluginPath("../../api/plugins");
|
|
#endif
|
|
ERRCHECK(result);
|
|
|
|
/*
|
|
Display selection dialog
|
|
*/
|
|
retval = DialogBox(hinst, MAKEINTRESOURCE(IDD_OUTPUTSELECT), GetDesktopWindow(), FMOD_OutputSelectProc);
|
|
if (retval < 0)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
switch (retval)
|
|
{
|
|
case 0:
|
|
{
|
|
gSystem->setOutput(FMOD_OUTPUTTYPE_DSOUND);
|
|
break;
|
|
}
|
|
case 1:
|
|
{
|
|
gSystem->setOutput(FMOD_OUTPUTTYPE_WINMM);
|
|
break;
|
|
}
|
|
case 2:
|
|
{
|
|
gSystem->setOutput(FMOD_OUTPUTTYPE_ASIO);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
Set the output rate to 44100 instead of the default 48000, because some winamp plugins wont work unless they are 44100.
|
|
*/
|
|
result = gSystem->setSoftwareFormat(44100, FMOD_SOUND_FORMAT_PCM16, 0, 0, FMOD_DSP_RESAMPLER_LINEAR);
|
|
ERRCHECK(result);
|
|
|
|
/*
|
|
Initialize FMOD.
|
|
*/
|
|
result = gSystem->init(32, FMOD_INIT_NORMAL, 0);
|
|
ERRCHECK(result);
|
|
if (result != FMOD_OK)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
/*
|
|
Create window and graphics
|
|
*/
|
|
gMainHwnd = CreateDialog(hinst, MAKEINTRESOURCE(IDD_DIALOG), GetDesktopWindow(), FMOD_DlgProc);
|
|
|
|
ShowWindow(gMainHwnd, SW_SHOW);
|
|
|
|
SetWindowText(gMainHwnd, TITLE);
|
|
|
|
// make the header
|
|
ZeroMemory( &gGraphicWindowBitmap, sizeof( BITMAPINFO ) );
|
|
gGraphicWindowBitmap.bmiHeader.biSize = sizeof( gGraphicWindowBitmap.bmiHeader );
|
|
gGraphicWindowBitmap.bmiHeader.biWidth = GRAPHICWINDOW_WIDTH;
|
|
gGraphicWindowBitmap.bmiHeader.biHeight = GRAPHICWINDOW_HEIGHT;
|
|
gGraphicWindowBitmap.bmiHeader.biPlanes = 1;
|
|
gGraphicWindowBitmap.bmiHeader.biBitCount = 32;
|
|
gGraphicWindowBitmap.bmiHeader.biCompression = BI_RGB;
|
|
gGraphicWindowBitmap.bmiHeader.biSizeImage = 0;
|
|
gGraphicWindowBitmap.bmiHeader.biXPelsPerMeter = 0;
|
|
gGraphicWindowBitmap.bmiHeader.biYPelsPerMeter = 0;
|
|
gGraphicWindowBitmap.bmiHeader.biClrUsed = 0;
|
|
gGraphicWindowBitmap.bmiHeader.biClrImportant = 0;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
|
{
|
|
MSG msg;
|
|
|
|
gHinstance = hInstance;
|
|
|
|
/*
|
|
Create interface and start message loop
|
|
*/
|
|
if (!Initialize(hInstance, lpCmdLine)) return FALSE;
|
|
|
|
while (GetMessage( &msg, 0, 0, 0 ))
|
|
{
|
|
TranslateMessage( &msg );
|
|
DispatchMessage( &msg );
|
|
}
|
|
|
|
return (int)msg.wParam;
|
|
}
|