Author Topic: BassBox Plugin 64-bit  (Read 991 times)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1992
    • zapsolution
BassBox Plugin 64-bit
« on: September 19, 2024, 06:23:34 pm »
The purpose of this VS2022 application is to switch easily from one plugin to another to check the OpenGL FPO effects transposed to 64-bit.
Most of them inherit from the original 32-bit version written long ago in PowerBASIC.



To navigate from one plugin to another move the cursor to the left or right edge of the window, and click on the auto/hide arrow.

Use drag & drop to play a specific audio file, and see how the effects interact with it.

Here is the BBP API to use to communicate with the plugin DLL.
See in the WM_TIMER message the gl_DrawScene() code using BBP_RenderOpenGL to pass the wimdata pointer to the DLL.

Code: [Select]
#pragma once
typedef ULONGLONG QWORD;

const int BBP_RENDER       = 1;       // Render the scene.
const int BBP_CREATE       = 2;       // Retrieve Title, Name, Version, Render mode.
const int BBP_INIT         = 3;       // Init the OpenGL.
const int BBP_SIZE         = 4;       // The size of the control has changed.
const int BBP_KEYBOARD     = 5;       // All keyborad message.
const int BBP_MOUSE        = 6;       // All mouse messages.
const int BBP_DESTROY      = 7;       // Free Up resources.
const int BBP_NEWSOUND     = 8;       // We are playing a new sound file.

const int BBP_GDIPLUS      = 0;       // GDImage GDIPLUS compatible mode.
const int BBP_OPENGL       = 1;       // OpenGL mode.
const int BBP_DIRECTX      = 2;       // DirectX mode (for future extension).

const int BBP_SUCCESS      = 0;
const int BBP_ERROR        = -1;

typedef struct {
    UINT msg;                   // The plugin's message (see above constant list).
    HWND parent;                // The parent window handle.
    HDC dc;                     // The parent window DC (while in play mode).
    HGLRC rc;                   // The parent OpenGL RC (while in play mode).
    WORD lpeak;                 // The left audio channel peak value (while in play mode).
    WORD rpeak;                 // The right audio channel peak value (while in play mode).
    char title[32];             // Plugin's name or title.
    char author[64];            // Plugin's author name.
    DWORD version;              // LOWRD major, HIWRD minor.
    long renderto;              // BBP_GDIPLUS, BBP_OPENGL, BBP_DIRECTX.
    long backargb;              // Default ARGB color background.
    float* fftdata;             // dword pointer to the FFT() as single array.
    WORD fftsize;               // Size of the FFT array.

    UINT winmsg;                // True Windows message.
    WPARAM wparam;              // wParam
    LPARAM lparam;              // lParam

    short* wimdata;             // dword pointer to the wave MM_WIM_DATA.
    QWORD medialength;          // Media length.
    QWORD mediapos;             // Media pos.

    char reserved[50];          // Reserved for future extension.
} BBPLUGIN;

static FARPROC BBP_ProcHandle(IN FARPROC hProc, IN long RW) {
    static FARPROC WasHproc;
    if (RW) WasHproc = hProc;
    return WasHproc;
}

static long BBP_Plugin(OUT BBPLUGIN &BBP) {
    long nRet = BBP_ERROR;
    if (IsWindow(gP.hGL)) {
        HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
        if (glRC) {
            long_proc (BBPLUGIN*);
            zProc hProc = (zProc) BBP_ProcHandle(0, 0);
            if (hProc) { nRet = hProc(&BBP); }
        }
    }
    return nRet;
}

static WCHAR* BBP_ActivePlugin(IN WCHAR* sPluginName, IN long RW) {
    static WCHAR sWasPluginName[MAX_PATH];
    if (RW) { wcscopy(sWasPluginName, sPluginName); }
    return sWasPluginName;
}

static void MarqueeUpdate() {
    WCHAR drive[_MAX_DRIVE]; ClearMemory(drive, sizeof(drive));
    WCHAR dir[_MAX_DIR]; ClearMemory(dir, sizeof(dir));
    WCHAR fname[_MAX_FNAME]; ClearMemory(fname, sizeof(fname));
    WCHAR ext[_MAX_EXT]; ClearMemory(ext, sizeof(ext));
    wsplitpath(gB.audiofile, drive, dir, fname, ext);
    ClearMemory(gP.plugintitle, sizeof(gP.plugintitle));
    wcscopy(gP.plugintitle, gP.title, MAX_PATH * 2);
    Add_Str(gP.plugintitle, gP.version);
    Add_Str(gP.plugintitle, L" by "); Add_Str(gP.plugintitle, gP.author);
    Add_Str(gP.plugintitle, L", playing \""); Add_Str(gP.plugintitle, fname); Add_Str(gP.plugintitle, ext); Add_Str(gP.plugintitle, L"\"");
    ZD_SetObjectText(ID_COPYRIGHT, gP.plugintitle);
}

static void BBP_Reset() {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    BBP.msg = BBP_CREATE;
    BBP_Plugin(BBP);

    ClearMemory(gP.title, sizeof(gP.title));
    wcscopy(gP.title, cswconv(BBP.title), strSize(gP.title));// C string to WCHAR
    ClearMemory(gP.author, sizeof(gP.author));
    wcscopy(gP.author, cswconv(BBP.author), strSize(gP.author));// C string to WCHAR

    BYTE majorVersion = (BYTE)(BBP.version & 0xFF);
    BYTE minorVersion = (BYTE)((BBP.version >> 8) & 0xFF);
    ClearMemory(gP.version, sizeof(gP.version));
    swprintf(gP.version, strSize(gP.version), L" (%d.%d)", majorVersion, minorVersion);

    MarqueeUpdate();

    //BBProc(BBP);
    if (BBP.renderto == BBP_OPENGL) {

        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
        glDisable(GL_DEPTH_TEST);
        glDisable(GL_LIGHT0);
        glDisable(GL_LIGHT1);
        glDisable(GL_LIGHT2);
        glDisable(GL_LIGHT3);
        glDisable(GL_LIGHT4);
        glDisable(GL_LIGHT5);
        glDisable(GL_LIGHT6);
        glDisable(GL_LIGHT7);
        glDisable(GL_LIGHTING);
        glDisable(GL_COLOR_MATERIAL);
        glDisable(GL_ALPHA_TEST);
        glDisable(GL_NORMALIZE);

        glDisable(GL_LINE_SMOOTH);

        glGetError();

    }
}

//long BBProc (OUT BBPLUGIN &BBP);
static void BBP_Detached(IN HWND hWnd, OUT HMODULE &hLib) {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    if (hLib) {
        BBP.msg = BBP_DESTROY;
        BBP.parent = hWnd;
        BBP_Plugin(BBP);
        //BBProc(BBP);

        // use brute force to delete any existing texture
        long Tmax = 64;
        long* DT = new long[Tmax]; memset(DT, 0, Tmax);
        for (long K = 0; K < Tmax; K++) { DT[K] = K; }
        glDeleteTextures(Tmax, (GLuint*)&DT[0]);
        delete[] DT;

        BBP_ProcHandle(0, 1); FreeLibrary(hLib); hLib = 0;
    }
}

static void BBP_ResizeOpenGL() {
    if (IsWindow(gP.hGL)) {
        BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
        BBP.msg          = BBP_SIZE;
        BBP.parent       = gP.hGL;
        BBP_Plugin(BBP);
        //BBProc(BBP);
    }
}

// Load/unload plugin DLL to/from memory
static long BBP_LoadPlugin(IN HWND hWnd, IN WCHAR* zPlugin) {
    long nDone = BBP_ERROR;
    long nLen = lstrlen(zPlugin);
    if ((nLen) && (_wcsicmp(zPlugin, BBP_ActivePlugin(0,0)) != 0)) {
        if (FileExist(zPlugin)) {
            if (gP.hLib) BBP_Detached(hWnd, gP.hLib);
            gP.hLib = LoadLibrary(zPlugin);
            if (gP.hLib) {
                FARPROC hProc = GetProcAddress(gP.hLib, "BBProc");
                if (hProc) {
                    BBP_ProcHandle(hProc, 1);
                    BBP_ActivePlugin(zPlugin, 1);
                    // Reset plugin to default
                    BBP_Reset();
                    nDone = BBP_SUCCESS;
                }
            }
        }
    } else if (nLen == 0) {
        if (gP.hLib) BBP_Detached(hWnd, gP.hLib);
    }
    return nDone;
}

static long BBP_AttachPlugin(WCHAR* zPlugin) {
    gP.pluginloaded = 0;
    if (IsWindow(gP.hGL)) {
        if (BBP_LoadPlugin(gP.hGL, zPlugin) == BBP_SUCCESS) {
            gP.pluginloaded = -1;
            BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
            BBP.msg          = BBP_INIT;
            BBP.parent       = gP.hGL;
            BBP.dc           = (HDC) ZI_GetProperty(gP.hGL, ZI_GLDC);
            BBP.rc           = (HGLRC) ZI_GetProperty(gP.hGL, ZI_GLRC);
            BBP.backargb     = 0;
            BBP_Plugin(BBP);

            //if (IsWindowVisible(gP.hGL)) { SetMetadataText(ID_VIDEO_SIZE, gB.plugintitle); }

            BBP.msg          = BBP_SIZE;
            BBP_Plugin(BBP);

            wcscopy(gP.bin.lastplugin, zPlugin);

            gP.pluginloaded = -1;
        }
    }
    return gP.pluginloaded;
}

static void BBP_RenderOpenGL(IN DWORD nLevel, IN short* pInt) {

    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));

    HDC glDC = (HDC) (ZI_GetProperty(gP.hGL, ZI_GLDC));
    HGLRC glRC = (HGLRC) (ZI_GetProperty(gP.hGL, ZI_GLRC));
    if (glRC) {

        BBP.msg          = BBP_RENDER;
        BBP.parent       = gP.hGL;
        BBP.dc           = glDC;
        BBP.rc           = glRC;
        BBP.lpeak        = SolvePeak(LOWORD(nLevel), 128);
        BBP.rpeak        = SolvePeak(HIWORD(nLevel), 128);
        BBP.backargb     = 0;
        BBP.fftdata      = (float*) BassChannelGetData();
        BBP.fftsize      = 256;
        BBP.medialength  = gB.medialength;
        BBP.mediapos     = gB.mediapos;
        BBP.wimdata      = pInt;

        BBP_Plugin(BBP);
        //BBProc(BBP);

        // Refresh display
        SwapBuffers(glDC);

        InvalidateRect(gP.hGL, NULL, 0);
        UpdateWindow(gP.hGL);
    }
    ReleaseDC(gP.hGL, glDC);
}

static void BBP_NewSound() {
    BBPLUGIN BBP; ClearMemory(&BBP, sizeof(BBP));
    BBP.msg = BBP_NEWSOUND;
    BBP_Plugin(BBP);
}

If you are familiar with OpenGL programming, the VS2022 source code of each plugin is also attached in the Plugins_dll.7z

« Last Edit: October 09, 2024, 05:50:22 pm by Patrice Terrier »
Patrice
(Always working with the latest Windows version available...)

Patrice Terrier

  • Administrator
  • *****
  • Posts: 1992
    • zapsolution
Re: BassBox Plugin 64-bit
« Reply #1 on: October 09, 2024, 05:52:33 pm »
The whole project has been updated with new plugins.
Patrice
(Always working with the latest Windows version available...)