home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************************
- * *
- * EQUALIZER.CPP: The main program, the core of this application *
- * *
- * Copyright (C) 2000 Andrei Grecu *
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- * This program is distributed in the hope that it will be useful, *
- * but WITHOUT ANY WARRANTY; without even the implied warranty of *
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
- * GNU General Public License for more details. *
- * *
- * You should have received a copy of the GNU General Public License *
- * along with this program; if not, write to the Free Software *
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *
- * *
- * If you have questions, bug reports regarding my code please contact me at: *
- * andrei.grecu@aon.at *
- * *
- * Home page: *
- * http://members.aon.at/grxpage/index.htm *
- * *
- **********************************************************************************/
-
- #include "precomp.h"
- #include "resource.h"
- #include "commctrl.h"
- #include "process.h"
-
- #include "misc.h"
- #include "fdt.h"
- #include "sound.h"
-
- #define MAX_LOADSTRING 100
-
- #define WM_TASKBARICON (WM_USER + 1)
-
- extern HANDLE hEvent;
- extern DWORD REC_FREQ;
- extern DWORD REC_BASEBUFSIZE;
- extern BYTE REC_CHANNELS;
-
- // Global Variables:
- HINSTANCE hInst; // current instance
- TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
- TCHAR szWindowClass[MAX_LOADSTRING]; // The title bar text
- HWND hWnd;
-
- // Handles of the Sliders
- LPHWND LSliders;
- LPHWND RSliders;
- LPHWND LVolumeDesc;
- LPHWND LFreqDesc;
- WORD NumSliders = 32 + 1; // number of sliders - **can be changed**
- HFONT ControlFont;
- HICON AppIcon;
-
- // Values of the Sliders
- LPDOUBLE LSlidersVal;
- LPDOUBLE RSlidersVal;
- DOUBLE LMaster, RMaster;
-
- LONG ProcessTimer = FALSE;
- BOOL EQonTaskBar = FALSE;
-
- // Position of RTEQ on desktop
- DWORD APPXPOS, APPYPOS, APPWIDTH, APPHEIGHT;
-
- // FFT vars
- DWORD REC_PERIOD = 2048; // sample block size - must be a power of 2
- // a higher value means better quality, but
- // more processor load **can be changed**
-
- DOUBLE DYNAMIC_RANGE_SCALE = 0.25; // The scale factor in %, can take
- // any value in range of double
- // **can be changed**
-
- // The program priority the higher, the better the sound, but the
- // worse the system responds. **can be changed**
- DWORD PROGRAM_PRIORITY = NORMAL_PRIORITY_CLASS;
-
- // Dynamic equalizing options
- BOOL DynamicEqualizing, BlurEQImpact;
- COEF DYNAMIC_TRESHOLD;
-
- // Equalizing variables
- LPSHORT *lpsrc;
- LPCOEF *lpdest;
- LPCOEF *lpLScale;
- LPCOEF lpRScale;
- LPSHORT *lpbuf_src;
-
- // Dynamic equalizing variables
- LPCOEF lpCorrLScale;
- LPCOEF *lpNLScale;
- LPCOEF lpChannelNorm;
-
- LPDWORD lpchannel_startfreq, lpchannel_bandwidth, lpchannel_halffreq;
- LPCOEF lptsrc, lpimpact, lpspectrum_power;
-
- // Equalizing variables
- LPCOEF lpweight;
-
- // EQ Thread variables
- BOOL EQThreadValid;
- HANDLE hEQThread;
-
- ATOM RTEQTrackBarRegisterClass(HINSTANCE hInstance);
- LRESULT CALLBACK Preferences(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
-
- // Foward declarations of functions included in this code module:
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- void InitEqualizer(void);
- void DestroyEqualizer(void);
- void LoadEqualizer(void);
- void SaveEqualizer(void);
- void GetStartValues(void);
- void SetStartValues(void);
-
- void PerformChannel(UINT channel);
- void ChannelAlgorithms(WORD channel, WORD period);
- RECT GetChannelPos(RECT src, DWORD i);
- double EqFunc(LONG i);
- DOUBLE EqVal(INT Val);
-
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM);
-
- LPVOID AllocMemory(DWORD dwsize);
- LPVOID AllocChannels(DWORD dwsize);
- #define FreeMemory(ptr) GlobalFree((HGLOBAL)ptr)
- void FreeChannels(LPVOID *ptr);
- LPVOID AllocChannels_Time(DWORD dwdepth, DWORD dwsize);
- void FreeChannels_Time(LPVOID **ptr, DWORD dwdepth);
-
- void SetControlFont(HFONT *ControlFont, DWORD width);
- void InsertMenuItemEasy(HMENU hMenu, DWORD dwInsertAfter, DWORD dwType, DWORD dwId, LPCSTR lpStr);
- void TaskbarIcon(DWORD dwAction);
- DWORD WINAPI EQThread(void);
-
- BOOL nopaint = FALSE;
-
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- LPSTR lpCmdLine,
- int nCmdShow)
- {
- MSG msg;
- HACCEL hAccelTable;
-
- // Initialize global strings
- LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
- LoadString(hInstance, IDC_EQUALIZER, szWindowClass, MAX_LOADSTRING);
- MyRegisterClass(hInstance);
- RTEQTrackBarRegisterClass(hInstance);
-
- // Perform application initialization:
- if (!InitInstance (hInstance, nCmdShow))
- {
- return FALSE;
- }
-
- hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_EQUALIZER);
-
-
- // Remains from priority options
- // SetPriorityClass(GetCurrentProcess(), PROGRAM_PRIORITY);
-
- // Main message loop:
- while (GetMessage(&msg, NULL, 0, 0)) {
-
- if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- }
-
- return msg.wParam;
- }
-
- void PerformChannel(UINT channel) {
-
- DWORD i;
-
- LPSHORT src = lpsrc[channel * 2];
- LPSHORT src2 = lpsrc[channel * 2 + 1];
- LPDOUBLE dest = lpdest[channel * 2];
- LPDOUBLE dest2 = lpdest[channel * 2 + 1];
- LPSHORT buf_src = lpbuf_src[channel * 2];
- LPSHORT buf_src2 = lpbuf_src[channel * 2 + 1];
-
- // Perform the first frequency block
- CopyMemory(&buf_src[REC_PERIOD / 2], src, (REC_PERIOD / 2) * 2);
- FDT(buf_src, dest2);
- ChannelAlgorithms(channel, 1);
- IFDT(dest2, src2);
- CopyMemory(buf_src, &src[REC_PERIOD / 2], (REC_PERIOD / 2) * 2);
-
- // Perform the second frequency block
- FDT(src, dest);
- ChannelAlgorithms(channel, 0);
- IFDT(dest, src);
-
- CopyMemory(&src[REC_PERIOD / 2], src, REC_PERIOD*2);
-
- // Mixing first and second frequency block
- for(i = 0; i < REC_PERIOD; i++) {
- if(i < REC_PERIOD / 2) {
- src[i] = (SHORT)((1 - lpweight[i]) * buf_src2[i] + lpweight[i] * src2[i]);
- }
- else {
- src[i] = (SHORT)((1 - lpweight[i]) * src[i] + lpweight[i] * src2[i]);
- }
- }
-
- CopyMemory(buf_src2, &src[REC_PERIOD], (REC_PERIOD / 2) * 2);
-
- }
-
- void ChannelAlgorithms(WORD channel, WORD period) {
-
- DWORD i;
-
- LPDOUBLE dest = lpdest[channel * 2 + period];
- LPDOUBLE *lpScale = lpLScale;
- DOUBLE Master = LMaster;
-
- // The algorithm for the equalizer: scaling the frequency coefficients
- /*dest[0] *= lpScale[0] * Master;
- for(i = 1; i < REC_PERIOD / 2; i++) dest[i] *= lpScale[i * 2] * Master;
- for(i = 0; i < REC_PERIOD / 2 - 1; i++) dest[i + REC_PERIOD / 2] *= lpScale[(i + 1) * 2] * Master;
- dest[REC_PERIOD - 1] *= lpScale[REC_PERIOD - 1] * Master;*/
- // dest[0] *= Master;
- // for(i = 0; i < REC_PERIOD-1; i++) dest[i + 1] *= lpScale[(DWORD)floor(i / 2) * 2] * Master;
- //dest[0] *= Master;
- //dest[0] *= 0;
- //for(i = 0; i < (DWORD)(32 * ((DOUBLE)REC_PERIOD/REC_FREQ)); i++) dest[i] *= 0;
- /////// for(i = 0; i < REC_PERIOD; i++) dest[i] *= lpScale[(i / 2) * 2] * Master;
- // LPDOUBLE src = (LPDOUBLE) AllocMemory(REC_PERIOD * sizeof(LPDOUBLE));
-
- if(!DynamicEqualizing) {
- // *** Perform normal equalizing
-
- for(i = 0; i < REC_PERIOD; i++) {
- dest[i] *= lpCorrLScale[i];
- }
-
- }
- else {
- // *** Perform dynamic equalizing
-
- // Calculate power spectrum in lptsrc
- // !REC_PERIOD MAY NOT EXHIBIT 65535 (i * i)
- for(i = 0; i < REC_PERIOD; i++) {
- lptsrc[i] = (dest[i] * dest[i]) * (i * i);
- }
-
- // Calculate the power on each channel
- for(i = 1; i < NumSliders; i++) {
- COEF var = 0;
- for(DWORD j = 0; j < lpchannel_bandwidth[i]; j++) {
- var += lptsrc[lpchannel_startfreq[i] + j] * lpNLScale[i][j];
- }
- lpspectrum_power[i] = var / lpChannelNorm[i];
- }
-
- // Calculate impact on the frequency spectrum
- ZeroMemory(lpimpact, REC_PERIOD * sizeof(COEF));
-
- COEF treshold = DYNAMIC_TRESHOLD;
- for(i = 1; i < NumSliders; i++) {
- for(DWORD j = 0; j < lpchannel_bandwidth[i]; j++) {
- DWORD pos = lpchannel_startfreq[i] + j;
- COEF signal_to_spectrum_power = lptsrc[pos] / lpspectrum_power[i];
-
- if(signal_to_spectrum_power < treshold) lpimpact[pos] = 1;//+= (1 - signal_to_spectrum_power / treshold) * lpNLScale[i][j];
- }
- }
-
- if(BlurEQImpact) {
- // Blur the impact across the frequency spectrum
- for(i = 1; i < REC_PERIOD - 1; i++) {
- if(lpimpact[i] > 0) {
- lpimpact[i - 1] += lpimpact[i] / 2;
- if(lpimpact[i - 1] > 1) lpimpact[i - 1] = 1;
- lpimpact[i + 1] += lpimpact[i] / 2;
- if(lpimpact[i + 1] > 1) lpimpact[i + 1] = 1;
- }
- }
- }
-
- // Equalize the sound according to the impact
- for(i = 0; i < REC_PERIOD; i++) {
- if(lpimpact[i] > 0) {
- // Idea:
- // dest[i] = (1 - lpimpact[i]) * dest[i] + lpimpact[i] * dest[i] * lpCorrLScale[i];
- dest[i] = dest[i] * (1 + lpimpact[i] * (lpCorrLScale[i] - 1));
- }
- }
-
- }
-
- // for(i = 0; i < REC_PERIOD; i++) dest[i] *= lpScale[i] * Master;
-
- }
-
- //
- // FUNCTION: MyRegisterClass()
- //
- // PURPOSE: Registers the window class.
- //
- // COMMENTS:
- //
- // This function and its usage is only necessary if you want this code
- // to be compatible with Win32 systems prior to the 'RegisterClassEx'
- // function that was added to Windows 95. It is important to call this function
- // so that the application will get 'well formed' small icons associated
- // with it.
- //
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
-
- wcex.cbSize = sizeof(WNDCLASSEX);
-
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = (WNDPROC)WndProc;
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_EQUALIZER);
- wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcex.hbrBackground = CreateSolidBrush(RGB(192, 192, 192));
- wcex.lpszMenuName = NULL;
- wcex.lpszClassName = szWindowClass;
- wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
-
- AppIcon = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);
-
- return RegisterClassEx(&wcex);
- }
-
- //
- // FUNCTION: InitInstance(HANDLE, int)
- //
- // PURPOSE: Saves instance handle and creates main window
- //
- // COMMENTS:
- //
- // In this function, we save the instance handle in a global variable and
- // create and display the main program window.
- //
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- DWORD i;
- RECT rc, dest;
-
- hInst = hInstance; // Store instance handle in our global variable
-
- // Load the configuration parameters
- LoadEqualizer();
-
- // Create the RTEQ window
- hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,
- APPXPOS, APPYPOS, APPWIDTH, APPHEIGHT, NULL, NULL, hInstance, NULL);
-
- if (!hWnd)
- {
- return FALSE;
- }
-
- // Show splash screen
- HWND hSplashScreen = CreateDialog(hInst, (LPCTSTR)IDD_SPLASHSCREEN, hWnd, (DLGPROC)About);
-
- HMENU hSysMenu = GetSystemMenu(hWnd, FALSE);
-
- InsertMenuItemEasy(hSysMenu, SC_CLOSE, MFT_STRING, IDM_PREFERENCES, "&Preferences...");
- InsertMenuItemEasy(hSysMenu, SC_CLOSE, MFT_SEPARATOR, NULL, NULL);
- InsertMenuItemEasy(hSysMenu, SC_CLOSE, MFT_STRING, IDM_ABOUT, "&About...");
- InsertMenuItemEasy(hSysMenu, SC_CLOSE, MFT_SEPARATOR, NULL, NULL);
-
- // Init the equalizer content
- InitEqualizer();
-
- // Destroy splash screen
- DestroyWindow(hSplashScreen);
-
- return TRUE;
- }
-
- void GetStartValues(void) {
-
- WORD i;
- LONG val;
- char value[10], key[10];
-
- // Read parameters from EQUALIZER.INI
-
- GetPrivateProfileString("DSE_Init",
- "Master",
- "0",
- value,
- 10,
- "EQUALIZER.INI");
-
- val = atoi(value);
-
- // Set the positions of the sliders
- SendMessage(LSliders[0], TBM_SETPOS, TRUE, val);
- SendMessage(RSliders[0], TBM_SETPOS, TRUE, val);
- PostMessage(hWnd, WM_VSCROLL, 0, (LPARAM) LSliders[0]);
-
- for(i = NumSliders - 1; i > 0; i--) {
- GetPrivateProfileString("DSE_Init",
- itoa(i, key, 10),
- "0",
- value,
- 10,
- "EQUALIZER.INI");
- val = atoi(value);
-
- SendMessage(LSliders[i], TBM_SETPOS, TRUE, val);
- SendMessage(RSliders[i], TBM_SETPOS, TRUE, val);
- PostMessage(hWnd, WM_VSCROLL, 0, (LPARAM) LSliders[i]);
- }
-
- }
-
- void SetStartValues(void) {
-
- WORD i;
- INT val;
- char key[10], value[10];
-
- // Write parameters to EQUALIZER.INI
-
- itoa(SendMessage(LSliders[0], TBM_GETPOS, 0, 0), key, 10);
- WritePrivateProfileString("DSE_Init",
- "Master",
- key,
- "EQUALIZER.INI");
-
-
- // Get the positions of the sliders
- for(i = 1; i < NumSliders; i++) {
- val = SendMessage(LSliders[i], TBM_GETPOS, 0, 0);
- itoa(i, key, 10),
- itoa(val, value, 10),
- WritePrivateProfileString("DSE_Init",
- key,
- value,
- "EQUALIZER.INI");
- }
-
- }
-
- void LoadEqualizer(void) {
-
- char value[50];
-
- // Read parameters from EQUALIZER.INI
- REC_FREQ = GetPrivateProfileInt("DSE_Init",
- "REC_FREQ",
- 22050,
- "EQUALIZER.INI");
-
- REC_CHANNELS = GetPrivateProfileInt("DSE_Init",
- "REC_CHANNELS",
- 2,
- "EQUALIZER.INI");
-
- REC_PERIOD = GetPrivateProfileInt("DSE_Init",
- "REC_BLOCKSIZE",
- 2048,
- "EQUALIZER.INI");
-
- GetPrivateProfileString("DSE_Init",
- "REC_BASEBUFSIZE",
- "65536",
- value,
- 10,
- "EQUALIZER.INI");
-
- if((REC_BASEBUFSIZE = atol(value)) < 32768) REC_BASEBUFSIZE = 32768;
-
- //*********************************************************************
-
- GetPrivateProfileString("DSE_Init",
- "DYNAMIC_RANGE_SCALE",
- "0.25",
- value,
- 10,
- "EQUALIZER.INI");
-
- if(!(DYNAMIC_RANGE_SCALE = atof(value))) DYNAMIC_RANGE_SCALE = 0.25;
-
- //*********************************************************************
-
- GetPrivateProfileString("DSE_Init",
- "DYNAMIC_TRESHOLD",
- "0.1",
- value,
- 10,
- "EQUALIZER.INI");
-
- if(!(DYNAMIC_TRESHOLD = atof(value))) DYNAMIC_TRESHOLD = 0.1;
-
- //*********************************************************************
-
- DynamicEqualizing = GetPrivateProfileInt("DSE_Init",
- "DYNAMIC_EQUALIZING",
- 0,
- "EQUALIZER.INI");
-
- BlurEQImpact = GetPrivateProfileInt("DSE_Init",
- "BLUR_EQ_IMPACT",
- 0,
- "EQUALIZER.INI");
-
- NumSliders = GetPrivateProfileInt("DSE_Init",
- "EQ_FREQBANDS",
- 32,
- "EQUALIZER.INI");
- NumSliders++;
-
- GetPrivateProfileString("DSE_Init",
- "PRIORITY",
- "NORMAL_PRIORITY",
- value,
- 50,
- "EQUALIZER.INI");
-
- if(!_stricmp(value, "IDLE_PRIORITY")) {
- PROGRAM_PRIORITY = IDLE_PRIORITY_CLASS;
- }
- else if(!_stricmp(value, "NORMAL_PRIORITY")) {
- PROGRAM_PRIORITY = NORMAL_PRIORITY_CLASS;
- }
- else if(!_stricmp(value, "HIGH_PRIORITY")) {
- PROGRAM_PRIORITY = HIGH_PRIORITY_CLASS;
- }
- else if(!_stricmp(value, "REALTIME_PRIORITY")) {
- PROGRAM_PRIORITY = REALTIME_PRIORITY_CLASS;
- }
- else { // if the user typed something wrong in the INI
- PROGRAM_PRIORITY = NORMAL_PRIORITY_CLASS;
- }
-
- APPXPOS = GetPrivateProfileInt("DSE_Init",
- "window_Xpos",
- 40,
- "EQUALIZER.INI");
-
- APPYPOS = GetPrivateProfileInt("DSE_Init",
- "window_Ypos",
- 40,
- "EQUALIZER.INI");
-
- APPWIDTH = GetPrivateProfileInt("DSE_Init",
- "window_width",
- 500,
- "EQUALIZER.INI");
-
- APPHEIGHT = GetPrivateProfileInt("DSE_Init",
- "window_height",
- 400,
- "EQUALIZER.INI");
-
- }
-
- void SaveEqualizer(void) {
-
- char value[50];
-
- // Write parameters to EQUALIZER.INI
-
- WritePrivateProfileString("DSE_Init",
- "REC_FREQ",
- itoa(REC_FREQ, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "REC_CHANNELS",
- itoa(REC_CHANNELS, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "REC_BLOCKSIZE",
- itoa(REC_PERIOD, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "REC_BASEBUFSIZE",
- itoa(REC_BASEBUFSIZE, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "DYNAMIC_RANGE_SCALE",
- _gcvt(DYNAMIC_RANGE_SCALE, 3, value),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "DYNAMIC_TRESHOLD",
- _gcvt(DYNAMIC_TRESHOLD, 3, value),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "DYNAMIC_EQUALIZING",
- itoa(DynamicEqualizing, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "BLUR_EQ_IMPACT",
- itoa(BlurEQImpact, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "EQ_FREQBANDS",
- itoa(NumSliders - 1, value, 10),
- "EQUALIZER.INI");
-
- switch(PROGRAM_PRIORITY) {
- case IDLE_PRIORITY_CLASS:
- strcpy(value, "IDLE_PRIORITY");
- break;
- case NORMAL_PRIORITY_CLASS:
- strcpy(value, "NORMAL_PRIORITY");
- break;
- case HIGH_PRIORITY_CLASS:
- strcpy(value, "HIGH_PRIORITY");
- break;
- case REALTIME_PRIORITY_CLASS:
- strcpy(value, "REALTIME_PRIORITY");
- break;
- }
-
- WritePrivateProfileString("DSE_Init",
- "PRIORITY",
- value,
- "EQUALIZER.INI");
-
- // Save window position only if the window is not hidden
- if(APPXPOS || APPYPOS || APPWIDTH || APPHEIGHT) {
-
- WritePrivateProfileString("DSE_Init",
- "window_Xpos",
- itoa(APPXPOS, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "window_Ypos",
- itoa(APPYPOS, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "window_width",
- itoa(APPWIDTH, value, 10),
- "EQUALIZER.INI");
-
- WritePrivateProfileString("DSE_Init",
- "window_height",
- itoa(APPHEIGHT, value, 10),
- "EQUALIZER.INI");
- }
-
- }
-
- //
- // FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
- //
- // PURPOSE: Processes messages for the main window.
- //
- // WM_COMMAND - process the application menu
- // WM_PAINT - Paint the main window
- // WM_DESTROY - post a quit message and return
- //
- //
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- int wmId, wmEvent;
- DOUBLE scale, xpos1, xpos2;
- WORD i, j;
- RECT rc;
-
- switch (message)
- {
- case WM_COMMAND:
- message = WM_SYSCOMMAND;
- case WM_SYSCOMMAND:
- wmId = LOWORD(wParam);
- wmEvent = HIWORD(wParam);
- // Parse the menu selections:
- switch (wmId)
- {
- case IDM_ABOUT:
- DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
- break;
- case IDM_PREFERENCES:
- if(DialogBox(hInst, (LPCTSTR)IDD_PREFERENCES, hWnd, (DLGPROC)Preferences)) {
-
- // Apply the preferences: restart RTEQ
-
- ProcessTimer = TRUE;
-
- DestroyEqualizer();
- InitEqualizer();
-
- for(DWORD i = 0; i < NumSliders; i++) {
- SendMessage(hWnd, WM_VSCROLL, NULL, (LPARAM)LSliders[i]);
- }
-
- ProcessTimer = FALSE;
-
- }
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- break;
- case WM_VSCROLL:
- // If a slider was touched
- i = 0;
- while(LSliders[i] != (HWND)lParam && i < NumSliders) i++;
- if(i < NumSliders) {
- LSlidersVal[i] = SendMessage((HWND)lParam, TBM_GETPOS, 0, 0);
-
- DOUBLE Value;
-
- scale = LSlidersVal[i];
- Value = EqVal((INT)scale);
-
- {
- // Determine the Volume in dB
- char ch[10];
-
- if(Value > 0) gcvt(10 * log10(Value), 3, ch);
- else strcpy(ch, "-INF");
- if(!i) strcat(ch, "dB");
-
- //SetWindowText(LVolumeDesc[i], ch);
- SendMessage(LVolumeDesc[i], WM_SETTEXT, 0, (LPARAM)(LPCSTR)ch);
- SendMessage(LVolumeDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
- }
-
- if(i == 0) {
- LMaster = Value;
- }
- else {
-
- // The first half of the channel (linear)
- if(i > 1) {
- for(j = 0; j < lpchannel_halffreq[i]; j++) {
- lpRScale[lpchannel_startfreq[i] + j] = ((COEF)j / lpchannel_halffreq[i]) * Value;
- }
- }
- else {
- for(j = 0; j < lpchannel_halffreq[i]; j++) {
- lpRScale[j] = Value;
- }
- }
-
- // The second half of the channel (linear)
- if(i < NumSliders - 1) {
- for(j = lpchannel_halffreq[i]; j < lpchannel_bandwidth[i]; j++) {
- lpRScale[lpchannel_startfreq[i] + j] = (1 - (((COEF)j - lpchannel_halffreq[i]) / ((COEF)lpchannel_bandwidth[i] - lpchannel_halffreq[i]))) * Value;
- }
- }
- else {
- for(j = lpchannel_halffreq[i]; j < lpchannel_bandwidth[i]; j++) {
- lpRScale[lpchannel_startfreq[i] + j] = Value;
- }
- }
-
- for(j = 0; j < lpchannel_bandwidth[i]; j++) {
- lpLScale[i][j] = lpRScale[lpchannel_startfreq[i] + j];
- }
-
- }
-
- // *** Calculate variables for dynamic equalizing
-
- // Calculate the Scale in a single array
- ZeroMemory(lpCorrLScale, REC_PERIOD * sizeof(DOUBLE));
-
- for(i = 1; i < NumSliders; i++) {
- for(DWORD j = 0; j < lpchannel_bandwidth[i]; j++) {
- lpCorrLScale[lpchannel_startfreq[i] + j] += lpLScale[i][j] * LMaster;
- }
- }
-
- // Calculate a normalized the scale array
-
- for(i = 1; i < NumSliders; i++) {
- COEF norm_var = 0;
- for(DWORD j = 0; j < lpchannel_bandwidth[i]; j++) {
- if(lpLScale[i][lpchannel_halffreq[i]] > 0) {
- lpNLScale[i][j] = lpLScale[i][j] / lpLScale[i][lpchannel_halffreq[i]];
- }
- else {
- lpNLScale[i][j] = 0;
- }
- norm_var += lpNLScale[i][j];
- }
- lpChannelNorm[i] = norm_var;
- }
-
- }
- break;
- case WM_SIZE:
- {
- if(wParam == SIZE_MINIMIZED) {
- TaskbarIcon(NIM_ADD);
-
- ShowWindow(hWnd, SW_HIDE);
-
- EQonTaskBar = TRUE;
- }
-
- // Reorder and resize all sliders
- if((wParam == SIZE_RESTORED || wParam == SIZE_MAXIMIZED) && LSliders) {
-
- if(EQonTaskBar) {
- TaskbarIcon(NIM_DELETE);
-
- ShowWindow(hWnd, SW_SHOW);
-
- EQonTaskBar = FALSE;
- }
-
- for(DWORD i = 0; i < NumSliders; i++) {
- rc.left = 0;
- rc.top = 0;
- rc.right = LOWORD(lParam);
- rc.bottom = HIWORD(lParam);
-
- rc = GetChannelPos(rc, i);
- MoveWindow(LSliders[i],
- rc.left,
- rc.top,
- rc.right,
- rc.bottom,
- FALSE);
-
- MoveWindow(LVolumeDesc[i],
- rc.left,
- rc.top - 20,
- rc.right,
- 20,
- FALSE);
-
- MoveWindow(LFreqDesc[i],
- rc.left,
- rc.top + rc.bottom,
- rc.right,
- 20,
- FALSE);
-
- SetControlFont(&ControlFont, rc.right);
- SendMessage(LVolumeDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
- SendMessage(LFreqDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
-
- HDC hdc = GetDC(LSliders[i]);
- SendMessage(LSliders[i], WM_PAINT, (WPARAM) hdc, 0);
- ReleaseDC(LSliders[i], hdc);
- }
-
- for(i = 0; i < NumSliders; i++) {
- HDC hdc = GetDC(LSliders[i]);
- SendMessage(LSliders[i], WM_PAINT, (WPARAM) hdc, 0);
- ReleaseDC(LSliders[i], hdc);
- }
- HDC hdc = GetDC(hWnd);
- SendMessage(hWnd, WM_ERASEBKGND, (WPARAM) hdc, 0);
- ReleaseDC(hWnd, hdc);
- }
- }
- return(TRUE);
- case WM_DESTROY:
-
- if(EQonTaskBar) {
- // Delete the Icon on the task bar
- TaskbarIcon(NIM_DELETE);
-
- EQonTaskBar = FALSE;
- }
-
- // Calculate the window position on the desktop
- WINDOWPLACEMENT lpwplace;
- GetWindowPlacement(hWnd, &lpwplace);
- if(lpwplace.showCmd != SW_HIDE && lpwplace.showCmd != SW_SHOWMINIMIZED) {
- RECT rc;
- GetWindowRect(hWnd, &rc);
- APPXPOS = rc.left;
- APPYPOS = rc.top;
- APPWIDTH = rc.right - rc.left;
- APPHEIGHT = rc.bottom - rc.top;
- }
- else {
- APPXPOS = APPYPOS = APPWIDTH = APPHEIGHT = 0;
- }
-
- // Save the preferences and free memory
- DestroyEqualizer();
-
- PostQuitMessage(0);
- break;
- case WM_ERASEBKGND:
- /*if(nopaint) { nopaint = FALSE; break; }
- {
- for(i = 0; i < NumSliders; i++) {
- HDC hdc = GetDC(LSliders[i]);
- SendMessage(LSliders[i], WM_PAINT, (WPARAM)hdc, 0);
- ReleaseDC(LSliders[i], hdc);
- SendMessage(LVolumeDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
- SendMessage(LFreqDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
- }
- }*/
- return DefWindowProc(hWnd, message, wParam, lParam);
- //return(1);
-
- case WM_PAINT:
- for(i = 0; i < NumSliders; i++) {
- SendMessage(LVolumeDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
- SendMessage(LFreqDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
- }
- return(DefWindowProc(hWnd, message, wParam, lParam));
-
- case WM_TASKBARICON:
- if(lParam == WM_LBUTTONDOWN || lParam == WM_LBUTTONDBLCLK) {
- // Show the RTEQ window if left clicked
- ShowWindow(hWnd, SW_SHOWNORMAL);
- SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- SetActiveWindow(hWnd);
- SetWindowPos(hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
- }
- else if(lParam == WM_RBUTTONDOWN || lParam == WM_RBUTTONDBLCLK) {
- // Show a menu when right clicked
- HMENU hSysmenu = CreatePopupMenu();
-
- InsertMenuItemEasy(hSysmenu, FALSE, MFT_STRING, SC_CLOSE, "&Close");
- InsertMenuItemEasy(hSysmenu, SC_CLOSE, MFT_STRING, SC_RESTORE, "&Show RTEQ");
- InsertMenuItemEasy(hSysmenu, SC_CLOSE, MFT_STRING, IDM_PREFERENCES, "&Preferences...");
- InsertMenuItemEasy(hSysmenu, SC_CLOSE, MFT_STRING, IDM_ABOUT, "&About...");
- InsertMenuItemEasy(hSysmenu, SC_CLOSE, MFT_SEPARATOR, NULL, NULL);
-
- POINT lpcrPoint;
- GetCursorPos(&lpcrPoint);
- TrackPopupMenu(hSysmenu, TPM_RIGHTALIGN | TPM_TOPALIGN, lpcrPoint.x, lpcrPoint.y, 0, hWnd, 0);
- }
- break;
-
- case WM_NCLBUTTONDOWN:
- if(wParam & HTSYSMENU == HTSYSMENU) nopaint = TRUE;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
-
- // Mesage handler for about box.
- LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
- {
- switch (message)
- {
- case WM_INITDIALOG:
- return TRUE;
-
- case WM_COMMAND:
- if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
- {
- EndDialog(hDlg, LOWORD(wParam));
- return TRUE;
- }
- break;
- }
- return FALSE;
- }
-
- double EqFunc(LONG i) {
-
- double x;
-
- // Calculate the position of a channel in an array
-
- x = (pow(2, (double)i / (NumSliders - 1) * 8) - 1) / (pow(2, 8) - 1);
-
- return(x);
-
- }
-
- // Recalculates the position and the size of the slider
- RECT GetChannelPos(RECT src, DWORD i) {
-
- WORD j, sliders_pro_row;
- RECT rc;
- FLOAT width, height, top;
-
- j = 0;
- do {
- j++;
- width = (FLOAT)((FLOAT)src.right / NumSliders * j);
- } while((width < 15) && (j < NumSliders));
-
- sliders_pro_row = (WORD)ceil((FLOAT)NumSliders / j);
- width = (FLOAT)((FLOAT)src.right / sliders_pro_row);
-
- height = (FLOAT)(src.bottom/* - 20*/) / j;
- top = /*20 + */(FLOAT)(i / sliders_pro_row) * (src.bottom/* - 20*/) / j;
- i %= sliders_pro_row;
-
- rc.left = (LONG)floor(((FLOAT)i * width));
- rc.top = (LONG)top + 20;
- rc.right = (LONG)ceil(width);
- rc.bottom = (LONG)height - 40;
-
- return(rc);
-
- }
-
- // Memory allocating routines
-
- LPVOID AllocMemory(DWORD dwsize) {
-
- LPVOID ptr;
-
- while(!(ptr = GlobalAlloc(GPTR, dwsize))) {
- UINT response;
- TCHAR err[MAX_LOADSTRING];
-
- LoadString(hInst, IDS_ERR_MEMORY, err, MAX_LOADSTRING);
- response = MessageBox(NULL, err, szTitle, MB_APPLMODAL | MB_RETRYCANCEL | MB_ICONEXCLAMATION);
- if(response == IDCANCEL) exit(1);
- };
-
- return(ptr);
-
- }
-
- LPVOID AllocChannels(DWORD dwsize) {
-
- LPVOID *ptr;
- WORD i;
-
- ptr = (LPVOID *) AllocMemory(REC_CHANNELS * 2 * sizeof(LPVOID));
- for(i = 0; i < REC_CHANNELS * 2; i++) {
- ptr[i] = AllocMemory(dwsize);
- }
-
- return(ptr);
-
- }
-
- void FreeChannels(LPVOID *ptr) {
-
- WORD i;
-
- for(i = 0; i < REC_CHANNELS * 2; i++) {
- FreeMemory(ptr[i]);
- }
- FreeMemory(ptr);
-
- }
-
- LPVOID AllocChannels_Time(DWORD dwdepth, DWORD dwsize) {
-
- LPVOID **ptr;
- WORD i, j;
-
- ptr = (LPVOID **) AllocMemory(REC_CHANNELS * 2 * sizeof(LPVOID));
- for(i = 0; i < REC_CHANNELS * 2; i++) {
- ptr[i] = (LPVOID *) AllocMemory(dwdepth * sizeof(LPVOID));
- for(j = 0; j < dwdepth; j++) {
- ptr[i][j] = AllocMemory(dwsize);
- }
- }
-
- return(ptr);
-
- }
-
- void FreeChannels_Time(LPVOID **ptr, DWORD dwdepth) {
-
- WORD i, j;
-
- for(i = 0; i < REC_CHANNELS * 2; i++) {
- for(j = 0; j < dwdepth; j++) {
- FreeMemory((LPVOID *)ptr[i][j]);
- }
- FreeMemory((LPVOID *)ptr[i]);
- }
- FreeMemory((LPVOID *)ptr);
-
- }
-
- void SetControlFont(HFONT *ControlFont, DWORD width) {
-
- DOUBLE abswidth, absheight;
-
- // Create a font according to the slider width
-
- abswidth = (DOUBLE)width / 5; // 5 characters have place
- absheight = abswidth * 2;
- if(absheight > 20) {
- absheight = 20;
- abswidth = 10;
- }
-
- DeleteObject(*ControlFont);
- if(absheight < 12) {
- *ControlFont = CreateFont(-(int)absheight, (int)floor(abswidth), 0, 0,
- FW_THIN, 0, 0, 0,
- DEFAULT_CHARSET,
- OUT_DEFAULT_PRECIS,
- CLIP_DEFAULT_PRECIS,
- DRAFT_QUALITY,
- DEFAULT_PITCH | FF_DONTCARE,
- "Small Fonts");
- }
- else {
- *ControlFont = CreateFont(-(int)absheight, (int)floor(abswidth), 0, 0,
- FW_MEDIUM, 0, 0, 0,
- DEFAULT_CHARSET,
- OUT_DEFAULT_PRECIS,
- CLIP_DEFAULT_PRECIS,
- DRAFT_QUALITY,
- DEFAULT_PITCH | FF_DONTCARE,
- "Arial");
- }
-
- }
-
- DOUBLE EqVal(INT Val)
- {
-
- DOUBLE scale = Val, Value;
-
- // Calculates the scaling of a signal from a slider value
-
- if(scale > 99.9999999 && scale <= 100) Value = 0; // (due to rounding errors)
- else if(scale == 0) Value = 1;
- else {
- scale *= (DOUBLE)(DYNAMIC_RANGE_SCALE);
- if(scale < 0) Value = fabs(scale - 1);
- else Value = (DOUBLE)1 / fabs(scale + 1);
- }
-
- return(Value);
-
- }
-
- void InsertMenuItemEasy(HMENU hMenu, DWORD dwInsertAfter, DWORD dwType, DWORD dwId, LPCSTR lpStr) {
-
- // Inserts a menu item in a menu
-
- MENUITEMINFO mii;
-
- if(dwType == MFT_SEPARATOR) {
-
- mii.cbSize = sizeof(MENUITEMINFO);
- mii.fMask = MIIM_TYPE | MIIM_STATE;
- mii.fType = MFT_SEPARATOR;
- mii.fState = MFS_ENABLED;
- mii.wID = NULL;
- mii.hSubMenu = NULL;
- mii.hbmpChecked = NULL;
- mii.hbmpUnchecked = NULL;
- mii.dwItemData = NULL;
- mii.dwTypeData = NULL;
- mii.cch = NULL;
-
- }
- else {
-
- mii.cbSize = sizeof(MENUITEMINFO);
- mii.fMask = MIIM_TYPE | MIIM_STATE | MIIM_ID;
- mii.fType = MFT_STRING;
- mii.fState = MFS_ENABLED;
- mii.wID = dwId;
- mii.hSubMenu = NULL;
- mii.hbmpChecked = NULL;
- mii.hbmpUnchecked = NULL;
- mii.dwItemData = NULL;
- mii.dwTypeData = (LPSTR)lpStr;
- mii.cch = sizeof(mii.dwTypeData);
-
- }
-
- InsertMenuItem(hMenu, dwInsertAfter, FALSE, &mii);
-
- }
-
- void TaskbarIcon(DWORD dwAction) {
-
- NOTIFYICONDATA Icon;
-
- // Perfroms actions on the task bar icon of RTEQ
-
- Icon.cbSize = sizeof(NOTIFYICONDATA);
- Icon.hWnd = hWnd;
- Icon.uID = 300;
- Icon.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP;
- Icon.uCallbackMessage = WM_TASKBARICON;
- Icon.hIcon = AppIcon;
- strcpy((LPSTR)&Icon.szTip, "RTEQ - Real Time Equalizer");
-
- Shell_NotifyIcon(dwAction, &Icon);
-
- }
-
- void InitEqualizer(void) {
-
- HINSTANCE hInstance = hInst;
-
- // Alloc the handles and variables for the sliders
- LSliders = (LPHWND) AllocMemory(NumSliders * sizeof(HWND));
- RSliders = (LPHWND) AllocMemory(NumSliders * sizeof(HWND));
- LVolumeDesc = (LPHWND) AllocMemory(NumSliders * sizeof(HWND));
- LFreqDesc = (LPHWND) AllocMemory(NumSliders * sizeof(HWND));
- LSlidersVal = (LPDOUBLE) AllocMemory(NumSliders * sizeof(DOUBLE));
- RSlidersVal = (LPDOUBLE) AllocMemory(NumSliders * sizeof(DOUBLE));
-
- // Hide the main window while intializing it
- ShowWindow(hWnd, SW_HIDE);
-
- RECT rc, dest;
-
- // Create sliders
- GetClientRect(hWnd, &rc);
-
- for(DWORD i = 0; i < NumSliders; i++) {
- dest = GetChannelPos(rc, i);
- SetControlFont(&ControlFont, dest.right);
-
- LSliders[i] = CreateWindow(/*"scrollbar",*/ "RTEQTrackBar",/* "msctls_trackbar32",*/
- "",
- WS_VISIBLE | WS_OVERLAPPED | WS_CHILD | TBS_VERT | TBS_NOTICKS | TBS_LEFT | TBS_TOOLTIPS,
- dest.left,
- dest.top,
- dest.right,
- dest.bottom,
- hWnd, (HMENU)i, hInstance, NULL);
-
- LVolumeDesc[i] = CreateWindow("static",
- "",
- WS_VISIBLE | WS_OVERLAPPED | WS_CHILD | SS_CENTER,
- dest.left,
- dest.top - 20,
- dest.right,
- 20,
- hWnd, (HMENU)i, hInstance, NULL);
-
- LFreqDesc[i] = CreateWindow("static",
- "",
- WS_VISIBLE | WS_OVERLAPPED | WS_CHILD | SS_CENTER,
- dest.left,
- dest.bottom + 20,
- dest.right,
- 20,
- hWnd, (HMENU)i, hInstance, NULL);
-
- {
- char ch[10], tch[10];
-
- if(i > 0) {
- DOUBLE Value = (EqFunc(i) + EqFunc(i - 1)) / 2; // Center frequency
-
- Value *= REC_FREQ / 2; // Scale to real frequency (/ 2 because of Nyquist freq)
-
- if(Value < 1000) {
- ltoa((DWORD) Value, ch, 10);
- }
- else {
- ltoa((DWORD)Value / 1000, ch, 10);
- strcat(ch, "K");
- ltoa(((DWORD)Value % 1000), tch, 10);
- tch[1] = '\0';
- strcat(ch, tch);
- }
- }
- else strcpy(ch, "M");
-
- SetWindowText(LFreqDesc[i], ch);
- SendMessage(LVolumeDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
- SendMessage(LFreqDesc[i], WM_SETFONT, (WPARAM)ControlFont, MAKELPARAM(TRUE, 0));
-
- }
-
- //RedrawWindow(LSliders[i], NULL, NULL, RDW_INTERNALPAINT);
- SendMessage(LSliders[i], TBM_SETRANGE, TRUE, MAKELONG(-100, 100));
- LSlidersVal[i] = 1;
- RSlidersVal[i] = 0;
- }
-
- ShowWindow(hWnd, SW_SHOW);
- UpdateWindow(hWnd);
-
- // Load equalizer values
- GetStartValues();
-
- // Initializing buffers for later usage
- lpsrc = (LPSHORT *) AllocChannels(REC_PERIOD * 2 * sizeof(SHORT));
- lpdest = (LPCOEF *) AllocChannels(REC_PERIOD * sizeof(COEF));
- lpbuf_src = (LPSHORT *) AllocChannels(REC_PERIOD * sizeof(SHORT));
- lpRScale = (LPCOEF) AllocMemory(REC_PERIOD * sizeof(COEF));
- lpweight = (LPCOEF) AllocMemory(REC_PERIOD * sizeof(COEF));
- lpimpact = (LPCOEF) AllocMemory(REC_PERIOD * sizeof(COEF));
- lptsrc = (LPCOEF) AllocMemory(REC_PERIOD * sizeof(COEF));
- lpCorrLScale = (LPCOEF) AllocMemory(REC_PERIOD * sizeof(COEF));
- lpspectrum_power= (LPCOEF) AllocMemory(NumSliders * sizeof(COEF));
- lpChannelNorm = (LPCOEF) AllocMemory(NumSliders * sizeof(COEF));
-
- // Initializing variables for dynamic equalizing
- lpchannel_halffreq = (LPDWORD) AllocMemory(NumSliders * sizeof(DWORD));
- for(i = 1; i < NumSliders; i++) {
- COEF begin = EqFunc(i - 1) * REC_PERIOD;
- COEF end = EqFunc(i) * REC_PERIOD;
- lpchannel_halffreq[i] = (end + begin) / 2;
- }
-
- lpchannel_startfreq = (LPDWORD) AllocMemory(NumSliders * sizeof(DWORD));
- for(i = 1; i < NumSliders; i++) {
- if(i == 1) lpchannel_startfreq[i] = 0;
- else lpchannel_startfreq[i] = lpchannel_halffreq[i - 1];
- }
-
- lpchannel_bandwidth = (LPDWORD) AllocMemory(NumSliders * sizeof(DWORD));
- for(i = 1; i < NumSliders; i++) {
- if(i == NumSliders - 1) lpchannel_bandwidth[i] = REC_PERIOD - lpchannel_startfreq[i];
- else lpchannel_bandwidth[i] = lpchannel_halffreq[i + 1] - lpchannel_startfreq[i];
- }
-
- lpLScale = (LPCOEF *) AllocMemory(NumSliders * sizeof(LPCOEF));
- for(i = 1; i < NumSliders; i++) {
- lpLScale[i] = (LPCOEF) AllocMemory(lpchannel_bandwidth[i] * sizeof(COEF));
- }
-
- lpNLScale = (LPCOEF *) AllocMemory(NumSliders * sizeof(LPCOEF));
- for(i = 1; i < NumSliders; i++) {
- lpNLScale[i] = (LPCOEF) AllocMemory(lpchannel_bandwidth[i] * sizeof(COEF));
- }
-
- for(i = 1; i < NumSliders; i++) {
- lpchannel_halffreq[i] -= lpchannel_startfreq[i];
- }
-
- // Initializing variables for normal equalizing
-
- LMaster = 0; RMaster = 0;
-
- for(i = 0; i < REC_PERIOD; i++) {
- lpRScale[i] = 0;
- }
-
- for(i = 1; i < NumSliders; i++) {
- for(DWORD j = 0; j < lpchannel_bandwidth[i]; j++) {
- lpLScale[i][j] = 0;
- }
-
- }
-
- for(i = 0; i < REC_PERIOD; i++) {
- lpweight[i] = (DOUBLE)1 - (cos(2 * pi * i / REC_PERIOD) + 1) / 2;
- }
-
- // Init DirectX input and output
- InitInput();
- InitOutput(hWnd);
-
- // Initializer Discrete Cosine Transform matrix
- gen_DCTmatrix(REC_PERIOD);
-
- // Create the equalizer thread which will perform the equalizing work
- EQThreadValid = TRUE;
- DWORD EQThreadID;
- hEQThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) EQThread, NULL, 0, &EQThreadID);
-
- }
-
- void DestroyEqualizer(void) {
-
- if(EQThreadValid) {
- // Destroy the equalizer thread
- EQThreadValid = FALSE;
- // Wait for thread to terminate (EQThreadValid = TRUE)
- while(EQThreadValid != TRUE);
- EQThreadValid = FALSE;
- CloseHandle(hEQThread);
- }
-
- // Save preferences and equalizer variables
- SaveEqualizer();
- SetStartValues();
-
- // Release DirectX input and output
- DestroyInput();
- DestroyOutput();
-
- destr_DCTmatrix();
-
- // Free the allocated memory
-
- {
- for(DWORD i = 0; i < GlobalSize(LSliders) / sizeof(HWND); i++) {
- DestroyWindow(LSliders[i]);
- DestroyWindow(LVolumeDesc[i]);
- DestroyWindow(LFreqDesc[i]);
- }
-
- ////////////////////////////////////////////////////////////////
-
- for(i = 1; i < GlobalSize(LSliders) / sizeof(HWND); i++) {
- FreeMemory(lpLScale[i]);
- }
- FreeMemory(lpLScale);
-
- for(i = 1; i < GlobalSize(LSliders) / sizeof(HWND); i++) {
- FreeMemory(lpNLScale[i]);
- }
- FreeMemory(lpNLScale);
-
- FreeMemory(lpCorrLScale);
- }
-
- FreeMemory(LSliders);
- FreeMemory(RSliders);
- FreeMemory(LSlidersVal);
- FreeMemory(RSlidersVal);
- FreeMemory(LVolumeDesc);
- FreeMemory(LFreqDesc);
-
- FreeChannels((LPVOID *)lpsrc);
- FreeChannels((LPVOID *)lpdest);
-
- FreeMemory(lpRScale);
- FreeChannels((LPVOID *)lpbuf_src);
- FreeMemory(lpweight);
- FreeMemory(lptsrc);
- FreeMemory(lpimpact);
- FreeMemory(lpspectrum_power);
- FreeMemory(lpChannelNorm);
-
- FreeMemory(lpchannel_startfreq);
- FreeMemory(lpchannel_halffreq);
- FreeMemory(lpchannel_bandwidth);
-
- }
-
- DWORD WINAPI EQThread(void) {
-
- switch(PROGRAM_PRIORITY) {
- case IDLE_PRIORITY_CLASS: SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); break;
- case NORMAL_PRIORITY_CLASS: SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL); break;
- case HIGH_PRIORITY_CLASS: SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); break;
- case REALTIME_PRIORITY_CLASS: SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); break;
- }
-
- // Process the equalizing work
- while(EQThreadValid) {
- if(!ProcessTimer) {
- while(Input(lpsrc[0], lpsrc[2])) {
-
- for(DWORD i = 0; i < REC_CHANNELS; i++) PerformChannel(i);
-
- Output(lpsrc[0], lpsrc[2]);
- if(!EQThreadValid) break;
- }
- while(Output(NULL, NULL)); if(!EQThreadValid) break;
- }
- if(!EQThreadValid) break;
- Sleep(((COEF)REC_PERIOD / REC_FREQ) * 1000 / 2);
- }
-
- EQThreadValid = TRUE;
-
- return(0);
-
- }