• Welcome to Theos PowerBasic Museum 2017.

BassBox

Started by Patrice Terrier, October 08, 2007, 10:57:44 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Patrice Terrier

#60
Charles ? ? ?

Then here is my new suggestion

See new constants: BB_GDIPLUS, BB_OPENGL, BB_DIRECTX and how to use them in the BB_INIT message.
See also the new RenderTo member in the BBPLUGIN structure.


MACRO CONST = MACRO

CONST BB_INIT    = %WM_CREATE
CONST BB_PLAY    = %WM_PAINT
CONST BB_DESTROY = %WM_DESTROY

CONST BB_GDIPLUS = 0            '// GDImage GDIPLUS compatible mode
CONST BB_OPENGL  = 1            '// OpenGL mode
CONST BB_DIRECTX = 2            '// DirectX mode (for future extension)

CONST BB_SUCCESS = 0
CONST BB_ERROR   = -1

TYPE BBPLUGIN
    Msg          AS LONG        '// The plugin's message (see above constant list)
    ParentWindow AS LONG        '// The parent window handle
    DC           AS LONG        '// The parent window DC (while in play mode)
    RC           AS LONG        '// The parent OpenGL RC (while in play mode)
    LeftPeak     AS WORD        '// The left audio channel peak value (while in play mode)
    RightPeak    AS WORD        '// The right audio channel peak value (while in play mode)
    Title        AS ASCIIZ * 32 '// Plugin's name or title.
    Author       AS ASCIIZ * 32 '// Plugin's author name
    Version      AS DWORD       '// LOWRD major, HIWRD minor
    RenderTo     AS LONG        '// BB_GDIPLUS, BB_OPENGL, BB DIRECTX
END TYPE

'// Use a dedicated "bbp" DLL extension: MyPlugin.bbp to ease the plugin's detection
'// Use a generic "BBPLUGIN" folder that would store all the bbp plugins,
'// each one could have its own embedded subfolders inside of "BBPLUGIN" to store local resources.

'// The main exported plugin's function would be bbProc, like this:
FUNCTION bbProc ALIAS "bbProc" (BYREF BB AS BBPLUGIN) EXPORT AS LONG
    LOCAL nRet AS LONG
    nRet = BB_SUCCESS
    SELECT CASE LONG BB.Msg
    CASE BB_INIT
         '// Do your code initialisation there
         BB.Title    = "My BB plugin"
         BB.Author   = "My Name"
         BB.Version  = MAKDWRD(1, 0) '// Version 1.0"
         BB.RenderTo = BB_OPENGL     '// or BB_GDIPLUS, or BB_DIRECTX
    CASE BB_PLAY
         '// Draw the scene using BB.LeftPeak and BB.RightPeak
    CASE BB_DESTROY
         '// Free up your resources there
    CASE ELSE
        nRet = BB_ERROR
    END SELECT
    FUNCTION = nRet
END FUNCTION



About FFT and audiogram, let me think of it (this would be more related to the WAVE API being used to grab audio sounds)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#61
Petr,

QuoteExactly. I know it could take some time, but I have music organised in subfolders under one "Music" folder, so this way I could throw directory on BassBox, and then do some coding while listening to music with no more care

Then I did it...  ;D

Now you can drag a complete folder!

BassBox detects recursively all embedded audio files and adds them to its hidden play list.


FUNCTION DetectAudio (BYVAL FullName$, BYVAL hList AS LONG) AS LONG
    LOCAL szFileName AS ASCIIZ * %MAX_PATH
    LOCAL sDetect AS STRING
    LOCAL nCount AS LONG
    IF LEN(FullName$) THEN
       CALL zSplitN (FullName$, PathName$, FilterName$)
       sDetect = DIR$(FullName$, 39) ' %NORMAL + %READONLY + %HIDDEN + %SYSTEM + %ARCHIVE
       DO WHILE LEN(sDetect)
          szFileName = LCASE$(PathName$ + sDetect)
          IF BassCheckExtension(szFileName) THEN
             IF ListAdd(hList, szFileName) > -1 THEN INCR nCount
          END IF
          sDetect = DIR$
       LOOP
    END IF
    FUNCTION = nCount
END FUNCTION

FUNCTION RecursiveSearch(szFileName AS ASCIIZ, BYVAL hList AS LONG) AS LONG
    LOCAL nCount AS LONG
    REDIM DirName$(0)
    Path$ = RTRIM$(szFileName, $Anti) + $Anti
    DirName$(0) = Path$
    CALL ReadDirs(Path$, DirName$())
    FOR K& = LBOUND(DirName$) TO UBOUND(DirName$)
        nCount = nCount + DetectAudio(DirName$(K&) + "*.*", hList)
    NEXT
    FUNCTION = nCount
END FUNCTION

SUB ReadDirs(BYVAL Path$, DirName$())
    LOCAL fd    AS WIN32_FIND_DATA
    LOCAL hFind AS LONG, zPath AS ASCIIZ * %MAX_PATH
    zPath = Path$ + "*"
    hFind = FindFirstFile(zPath, fd)
    IF hFind <> %INVALID_HANDLE_VALUE THEN
       DO
          IF (fd.dwFileAttributes AND 16) THEN       ' If directory bit (16) is set
             IF (ASC(fd.cFileName) = 46) = 0 THEN    ' Not . or ..
                N& = MAX&(UBOUND(DirName$) + 1, 1)
                REDIM PRESERVE DirName$(N&)
                DirName$(N&) = Path$ + RTRIM$(fd.cFileName, CHR$(0)) + $Anti
              ' We have a subdir, call function again to find others
              ' Each recursive call gets its own place on the stack
                CALL ReadDirs(DirName$(N&), DirName$())
             END IF
          END IF
       LOOP WHILE FindNextFile(hFind, fd)
       CALL FindClose(hFind)
    END IF
END SUB



    CASE %WM_DROPFILES '// Drag & drop
         nFilesDropped = DragQueryFile(wParam, -1, "", 0)
         szFileName = ""
         nCount = 0
         IF nFilesDropped > 0 THEN
             hList = zGetMainItem(%ID_PlayList)
             CALL ListDeleteAll(hList)
             FOR K = 0 TO nFilesDropped - 1
                 CALL DragQueryFile(wParam, K, szFileName, %MAX_PATH)
                 szFileName = LCASE$(szFileName)
                 IF BassCheckExtension(szFileName) THEN
                    IF ListAdd(hList, szFileName) > -1 THEN INCR nCount
                 ELSE
                    nCount = nCount + RecursiveSearch(szFileName, hList) ' <-------- Recursive search is done there   
                 END IF
             NEXT
         END IF


The new LastPatch.zip is attached below
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

Hi Patrice,

thanks a lot lot lot.
It works perfectly, except situation when I get GPF :(

It is weird, sometimes I throw folder and can go through all tracks, but sometimes ( with same folder ) it will GPF when clicking next button.

But it is quite rare, I cannot isolate section in which it occurs now :(. I suspect BassChannelPlay, but not sure.


Thanks,
Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

Make sure that the overall length of the full path name doesn't exceed %MAX_LENGTH, I don't check this.
If this occures try to convert to short name (but perhaps it is something else).

Anyway you have the full source code, thus try to check what could be wrong with your CZ config ;)
I am unable to reproduce it there, but I don't have many embedded subfolders.
Also try to enlarge the stack in case there is huge recursivity.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

#64
Thanks for the tips,

when I will find solution I will post here :)
Fact is that I cannot replicate it now, maybe it was somehow influenced by apps running before.


Petr
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Patrice Terrier

#65
Here is the plugin version.

As you can imagine I have done many changes in it, so please check it thoroughly ;)

All plugins must be stored in the "BBPugin\" child folder.

Each plugin must be named "PLUG001.dll", "PLUG002.dll", "PLUG003.dll", etc.
in sequence.

Use the provided examples as template to write your own.

If have done a few cosmetic to the interface as well:
- New system buttons
- Animated moving blue led, just to show that the player is active.
- The Play button, flashes at startup to let the user know he could play already the default audio (BassBox.mp3).


Petr,

I have given the title of "Mikado" to your plugin, but of course feel free to change it  8)



And here is the new BBP API:

FUNCTION BBP_ProcHandle(BYVAL hProc AS DWORD, BYVAL RW AS LONG) AS DWORD
    STATIC WasHproc AS DWORD
    IF RW THEN WasHproc = hProc
    FUNCTION = WasHproc
END FUNCTION

'// Detached plugin
SUB BBP_Detached(BYREF hLibModule AS DWORD)
    LOCAL BBP AS BBPLUGIN
    IF hLibModule THEN
       BBP.Msg = %BBP_DESTROY
       BBP.ParentWindow = zGetMainItem(%ID_OpenGL)
       CALL BBP_Plugin(BBP)
       CALL BBP_ProcHandle(0, 1): CALL FreeLibrary(hLibModule): hLibModule = 0
    END IF
END SUB

'// Load/unload plugin DLL to/from memory
SUB BBP_LoadPlugin(zPlugin AS ASCIIZ)
    STATIC hLibModule AS DWORD
    LOCAL hProc AS DWORD, sLastPlugin AS STRING
    IF LEN(zPlugin) AND zPlugin <> sLastPlugin THEN
       IF zsExist(zPlugin) THEN
          CALL BBP_Detached(hLibModule)
          hLibModule = LoadLibrary(zPlugin)
          IF hLibModule THEN
             hProc = GetProcAddress(hLibModule, "BBProc")
             IF hProc THEN
                CALL BBP_ProcHandle(hProc, 1)
                sLastPlugin = zPlugin
             END IF
          END IF
       END IF
    ELSEIF LEN(zPlugin) = 0 THEN
       CALL BBP_Detached(hLibModule)
    END IF
END SUB

'// Send/recept message to/from plugin
FUNCTION BBP_Plugin(BYREF BBP AS BBPLUGIN) AS LONG
    LOCAL hProc AS DWORD, nRet AS LONG
    nRet = %BBP_ERROR
    IF glRC THEN
       hProc = BBP_ProcHandle(0, 0): IF hProc THEN CALL DWORD hProc USING BBP_Plugin(BBP) TO nRet
    END IF
    FUNCTION = nRet
END FUNCTION

'// Return full qualified path to the plugin folder
FUNCTION BBP_Path() AS STRING
    FUNCTION = zsExePath() + $BBP_PLUGIN_FOLDER
END FUNCTION
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

#66
BassBox plugin version

updated with a new plugin from Charles Pegge:

PolyHedra
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

Hi Patrice,

thanks for new version,
looks nice !

Mikado name is ok :D

I still have some work to do, but I have idea what to create when I will have time ;)


Petr

AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Charles Pegge


Thanks Patrice! I am going to try converting my  Viewer6 code into a compatible plugin. Then there will be lighting, keyboard and mouse interactions available. It will be feasible to support the plugins as a syncronised project.

Under some conditions, GPFs occur. It does not happen very often, so I have not been able to reproduce the crashes yet but they occur when dragging individual music files onto BassBox, maybe from different folders.

Patrice Terrier

#69
Ian Luck's BASS.dll,
is probably the best audio lib available world-wide, however it could GPF when it encounters an audio file corrupted or using a mismatched header.

This also could occured with some small wave files, like those being used by the OS.

For example, try with the small wave files attached below.

And here is what is detected by the VISUAL STUDIO debuger:

>   00000002()   
   Bass.dll!1000109f()    
   [Les frames ci-dessous sont peut-être incorrects et/ou manquants, aucun symbole chargé pour Bass.dll]   
   kernel32.dll!76fa6c6d()    
   kernel32.dll!76fa6c63()    
   ntdll.dll!777a0dfd()    
   ntdll.dll!777a06a0()    
   kernel32.dll!76fc77d4()    
   kernel32.dll!76fa9f16()    
   Bass.dll!1001d149()    
   msvcrt.dll!773ef471()    
   msvcrt.dll!773ef450()    
   kernel32.dll!76fc3833()    
   ntdll.dll!7777a9bd()    

I could check for small WAVE file and ignore them, or perhaps add a small latency between each audio file, just to make sure that there is enough time to free up resources.

What do you think?
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Charles Pegge

Most of the pieces, I have been trying this evening are ogg files, but the point of failure cannot be predicted - once in the middle of playing one file, without drag and drop. But I hope a pattern will eventually emerge. I dont mind extra music listening duties.

Patrice Terrier

I think I have found a solution for the problem of playing very small wave files.

Instead of using BASS_StreamFree I am using BASS_ChannelStop, and the small wave files do not cause anymore a GPF.
This occures most of the time when dragging a whole hard disk, for example "C:\" (including the OS folder that do have many small wave files)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Patrice Terrier

Below is the patch that solves the GPF problem that could occure when playing small wave files.

...
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Kent Sarikaya

I really love the new player. Being able to drop folders, have quick access to various plugins and of course all the effects and equalization. Patrice, since this is very close to being an ulitmate player... it would be nice to have presets for the equalizer too. I was playing with it today and tried to set it to how I have my equalizer set in my sound card. When I did this, I got distortion, even though I turned off the eq on my sound card. Did anyone else have this sort of problem?

Charles Pegge

I've tried my best to crash BassBox but that patch seems to have fixed the GPF problem Patrice. It might have been trying to play a stream that had ceased to exist, so stopping it first makes sense.