• 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 3 Guests are viewing this topic.

Charles Pegge

#300
Wonderful Patrice!

Now to visualise the CD collection.


I've updated 'Cartesian'. The fft samples now move away and fade into the distance. I think it works well with quiet or ambient music.

Kent Sarikaya

THanks guys nice updates.

Charles, it  would be nice to have a toggle to switch from classic to new version for cartesian... or over time switch automatically between the 2.
I love the new look, don't get me wrong... but I also like the original look too. So I miss it also.

I guess the next problem to solve it plugin organization on the player. I guess another row could be added or a pop menu for each plugin artist.

- plgns    - plgns     - plgns
|            |             |
o PT        o PS       o CP

Patrice Terrier

I forgot to say about the new CD-Audio feature, that you are not limited to play only .cda, but of course any CD or DVD using embedded subfolders and any kind of supported BassBox audio file.

And by the way, it could work the same with USB key.

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

Petr Schreiber

#303
Hi,

thanks for new release.
I tried the player for the first time with CDs, and it worked great!
Only which it could not play was one CD which is supposed to be CD Plus (?).
The "music tower" can play it as it would be normal audio CD, but BassBox not. But this in only one CD from all I have of this type, so not much problem :)


Thanks,
Petr

P.S. Charles - new version looks very nice !
AMD Sempron 3400+ | 1GB RAM @ 533MHz | GeForce 6200 / GeForce 9500GT | 32bit Windows XP SP3

psch.thinbasic.com

Charles Pegge



The first of the soundscape plugins -A glacial landscape. This terrain needs no texture! It works best with harmonically rich pieces. I have been playing Mike Oldfields 'Songs of Distant Earth' to test it.

There is an art to synthesising textures that dont pixelate - I am learning slowly.

I have just started using USB flash drives for backup. For a fiver, I can store all my programes in less then a tenth of one of these.

PS: Kent, I will try to incorporate the original Cartesian with the new one. A forward gear somewhere.

Kent Sarikaya

Soundscape is really cool. Of course I went with playing the opposite of mellow and made it spike all over the place.
Then I went with The Chamber... and it was very nice as you said.
Great idea for a plugin!

Patrice Terrier

BassBox version 1.00f from december, 16, 2007

Allows you to use an unlimited number of plugins

See the ZIP file attached to the first post of this thread.

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

Patrice Terrier

#307
I have updated the BassBox 1.00f ZIP file, because I foget to put the new image resources being used to scroll the plugin's check boxes.

They are attached to this post for the guy who downloaded the zip file already
Just put them into the "\BassBox\resource\" folder.

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

Kent Sarikaya

That is a nice elegant solution Patrice, thanks.

Patrice Terrier

I have attached the new BassBox version 1.07a to the first post of this thread.

This version reduces both the memory footprint and CPU usage.
I did also several changes to force BASS.DLL to clean its memory when playing audio in loop mode.
The BBPlugin Init mode has been reworked for better texture management and plugin isolation.
Charles's "Soundscape" has been added to the project.

...

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

Kent Sarikaya

#310
Thanks Patrice, going to download it now.

Looks and runs great, thanks guys. Flipping through the plugins, an idea occurred for a new feature.

That is user set time to flip through the plugins on its own.  So it would take that time, after it elapses switch to the next plugin.
Now for some plugins that might need more time... like soundscape... maybe each plugin can have a mimimum time it needs before it would allow switching.

So maybe soundscape would say 30 seconds before it is allowed to switch.

I know lots of work, but some thoughts that came to me while enjoying the lastest cool version!

Patrice Terrier

#311
BassBox has been updated to version 1.10

A new OSCILLOSCOPE control has been added to monitor the playing audio in real time.

In order to use this feature you must set your multiplex audio card in "Stereo" or "What you hear" mode.

Note: So far i didn't checked it with XP.

The zip is attached to the first post of this thread, and the screen shot has been updated.

For those who like to know what is going on behind the hood, here is the code of the "Monitoring section":


'*****************************************************************************************************
'// Monitoring audio section
'*****************************************************************************************************
%MAXPNAMELEN        = 32           ' max product name length (including NULL)
%CALLBACK_WINDOW    = &H10000      ' dwCallback is a HWND
%HEAP_ZERO_MEMORY   = &H00000008
%MM_WIM_DATA        = &H3C0
%WM_WAVE_INIT       = %WM_USER + 1

TYPE WAVEHDR
    lpData AS ASCIIZ PTR
    dwBufferLength AS DWORD
    dwBytesRecorded AS DWORD
    dwUser AS DWORD
    dwFlags AS DWORD
    dwLoops AS DWORD
    lpNext AS LONG
    Reserved AS DWORD
END TYPE

TYPE WAVEINCAPS
    wMid AS WORD
    wPid AS WORD
    vDriverVersion AS DWORD
    szPname AS ASCIIZ * %MAXPNAMELEN
    dwFormats AS DWORD
    wChannels AS WORD
    wReserved1 AS WORD
END TYPE

TYPE WAVEFORMATEX
    wFormatTag AS WORD
    nChannels AS WORD
    nSamplesPerSec AS DWORD
    nAvgBytesPerSec AS DWORD
    nBlockAlign AS WORD
    wBitsPerSample AS WORD
    cbSize AS WORD
END TYPE

DECLARE FUNCTION waveInGetNumDevs LIB "WINMM.DLL" ALIAS "waveInGetNumDevs" () AS LONG
DECLARE FUNCTION waveInGetDevCaps LIB "WINMM.DLL" ALIAS "waveInGetDevCapsA" (BYVAL uDeviceID AS DWORD, lpCaps AS WAVEINCAPS, BYVAL uSize AS DWORD) AS LONG
DECLARE FUNCTION GetProcessHeap LIB "KERNEL32.DLL" ALIAS "GetProcessHeap" () AS LONG
DECLARE FUNCTION HeapAlloc LIB "KERNEL32.DLL" ALIAS "HeapAlloc" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL dwBytes AS DWORD) AS DWORD
DECLARE FUNCTION HeapFree LIB "KERNEL32.DLL" ALIAS "HeapFree" (BYVAL hHeap AS DWORD, BYVAL dwFlags AS DWORD, BYVAL lpMem AS DWORD) AS LONG
DECLARE FUNCTION waveInStop LIB "WINMM.DLL" ALIAS "waveInStop" (BYVAL hWaveIn AS DWORD) AS LONG
DECLARE FUNCTION waveInReset LIB "WINMM.DLL" ALIAS "waveInReset" (BYVAL hWaveIn AS DWORD) AS LONG
DECLARE FUNCTION waveInUnprepareHeader LIB "WINMM.DLL" ALIAS "waveInUnprepareHeader" (BYVAL hWaveIn AS DWORD, lpWaveInHdr AS WAVEHDR, BYVAL uSize AS DWORD) AS LONG
DECLARE FUNCTION waveInClose LIB "WINMM.DLL" ALIAS "waveInClose" (BYVAL hWaveIn AS DWORD) AS LONG
DECLARE FUNCTION waveInOpen LIB "WINMM.DLL" ALIAS "waveInOpen" (lphWaveIn AS DWORD, BYVAL uDeviceID AS DWORD, lpFormat AS WAVEFORMATEX, BYVAL dwCallback AS DWORD, BYVAL dwInstance AS DWORD, BYVAL dwFlags AS DWORD) AS LONG
DECLARE FUNCTION waveInPrepareHeader LIB "WINMM.DLL" ALIAS "waveInPrepareHeader" (BYVAL hWaveIn AS DWORD, lpWaveInHdr AS WAVEHDR, BYVAL uSize AS DWORD) AS LONG
DECLARE FUNCTION waveInAddBuffer LIB "WINMM.DLL" ALIAS "waveInAddBuffer" (BYVAL hWaveIn AS DWORD, lpWaveInHdr AS WAVEHDR, BYVAL uSize AS DWORD) AS LONG
DECLARE FUNCTION waveInStart LIB "WINMM.DLL" ALIAS "waveInStart" (BYVAL hWaveIn AS DWORD) AS LONG

%NUMBUF = 16

FUNCTION zPaintCapture(BYVAL hWnd AS LONG, BYVAL hDC AS LONG, BYVAL Action AS LONG) AS LONG
    'LOCAL rc AS RECT
    LOCAL hDCTemp, hPaintBitmap AS LONG
   
    'CALL GetClientRect(hWnd, rc)
    IF Action THEN
     ' Create OFF screen bitmap to avoid flickering and allow smooth display
     ' ---------------------------------------------------------------------
       IF zGetPaintBitmap(hWnd) THEN
          FUNCTION = zGetPaintDC(hWnd)
       ELSE
          hDCTemp = CreateCompatibleDC(hDC)
          hPaintBitmap = zCreateDIBSection(hDC, 128, 63, 32)
          CALL SelectObject(hDCTemp, hPaintBitmap)
          CALL zSetProperty(hWnd, %FORM_PaintDC, hDCTemp)
          CALL zSetProperty(hWnd, %FORM_PaintBitmap, hPaintBitmap)
          FUNCTION = hDCTemp
       END IF
    ELSE
     ' End of OFF screen drawing, fast BitBlt to the target display Window
     ' -------------------------------------------------------------------
     ' Draw final result to the target window
       CALL BitBlt(hDC, 0, 0, 128, 63, zGetPaintDC(hWnd), 0, 0, %SRCCOPY)
    END IF

END FUNCTION

SUB DrawWave(BYVAL hWnd AS LONG, BYVAL pInteger AS INTEGER PTR)
    LOCAL rc AS RECT
    LOCAL x, y, x1, y1, C, nVol, hDC, graphics AS LONG
    LOCAL hDCView, UseColor, YFactor, n64, n127, nPlaying AS LONG
    LOCAL UseGain AS SINGLE
    STATIC nTick, nDelay, xPos, WasVol AS LONG, WasGain AS SINGLE

    INCR nTick: IF nTick > 1 THEN nTick = 0: EXIT SUB '// To reduce the CPU usage.

    CALL GetClientRect(hWnd, rc)

    YFactor = 1074 ' &H0FFFF \ (rc.nBottom - 2)
    hDCView = GetDC(hWnd)

    hDC = zPaintCapture(hWnd, hDCView, 1)
    CALL GdipCreateFromHDC(hDC, graphics)

       n64 = rc.nBottom \ 2: n127 = rc.nBottom - 1
       CALL zsGdipFillRect(graphics, 0, 0, rc.nRight, rc.nBottom, zColorARGB(255, 0) )
       CALL zsGdipLine(graphics, 0, n64 + 1, rc.nRight, n64 + 1, zColorARGB(255, RGB(48,48,32)) )
       nPlaying = 0
       IF IsWindowVisible(GetDlgItem(zMainWindow(0), %ID_BTN_Play)) = 0 THEN

          nVol = zGetTrackValue(zGetMainItem(%ID_TRACK_VOL))
          IF WasGain = 0 THEN WasVol = -1
          IF nVol <> WasVol THEN '// This to save a few CPU cycles and avoid SQR computation
             UseGain = 1         '// when it is not required.
             IF nVol < 50 THEN
                UseGain = MAX(9 * (SQR((100 - nVol) / 50) * 1.8 - 2), 1.0)
             ELSEIF nVol > 60 THEN
                UseGain = MAX(SQR((110 - nVol) / 50), 0.1)
             END IF
             WasGain = UseGain
          ELSE
             UseGain = WasGain
          END IF
          WasVol = nVol
         
          FOR x = 0 TO 127' 0 TO 255
              y = (rc.nBottom - (((@pInteger * UseGain) + &H7FFF) \ YFactor))
              IF nPlaying = 0 THEN
                 IF ABS(y) > 3 THEN nPlaying = -1
              END IF
              IF x THEN
                 C = 32 - CLNG(y * 0.5) ' (32 / rc.nBottom))
                 CALL zsGdipLine(graphics, x1, y1, x, y, zColorARGB(255, LevelColr(C)) )
              END IF
              x1 = x: y1 = y
              FOR C = 1 TO 2: INCR pInteger: NEXT
          NEXT
       END IF
     
       IF nPlaying THEN UseColor = &H303030 ELSE UseColor = &H600000&
       CALL zsGdipLine(graphics, xPos, 0, xPos, n64, zColorARGB(255, UseColor) )
       CALL zsGdipLine(graphics, xPos, n64 + 2, xPos, rc.nBottom, zColorARGB(255, UseColor) )
     
       IF nDelay = 0 THEN INCR xPos: IF xPos > rc.nRight THEN xPos = 0
       INCR nDelay: IF nDelay = 4 THEN nDelay = 0
     
       CALL zPaintCapture(hWnd, hDCView, 0)

    CALL GdipDeleteGraphics(graphics)
    CALL ReleaseDC(hWnd, hDCView)
     
END SUB

FUNCTION AudioProc (BYVAL hWnd AS LONG, BYVAL wMsg AS LONG, BYVAL wParam AS LONG, BYVAL lParam AS LONG) AS LONG

    LOCAL K, hResource AS LONG, pWaveHdr AS WAVEHDR PTR
    STATIC gWaveBuf() AS WAVEHDR, gHwi AS LONG

    SELECT CASE LONG wMsg

    CASE %WM_WAVE_INIT
         LOCAL wic AS WAVEINCAPS
         LOCAL wfx AS WAVEFORMATEX
         LOCAL nRet, nDev AS LONG
         nDev = WaveInGetNumDevs()
         nRet = 22 ' "No suitable device found"
         FOR K = nDev - 1 TO 0 STEP -1
             IF WaveInGetDevCaps(K, wic, LEN(WAVEINCAPS)) = 0 THEN
                IF INSTR(LCASE$(wic.szPname), "micro") = 0 THEN ' We don't want the microphone
                   wfx.nChannels       = 2
                   wfx.nSamplesPerSec  = 44100
                   wfx.wFormatTag      = 1                      ' %WAVE_FORMAT_PCM
                   wfx.wBitsPerSample  = 16
                   wfx.nBlockAlign     = wfx.nChannels * wfx.wBitsPerSample \ 8
                   wfx.nAvgBytesPerSec = wfx.nSamplesPerSec * wfx.nBlockAlign
                   wfx.cbSize          = 0
                   nRet = waveInOpen(gHwi, K, wfx, hWnd, hWnd, %CALLBACK_WINDOW)
                   IF nRet = 0 THEN EXIT FOR
                ELSE
                   nRet = 22 ' "No suitable device found"
                END IF
             END IF
         NEXT

         IF nRet = 0 THEN
            REDIM gWaveBuf(%NUMBUF)
            FOR K = 1 TO %NUMBUF
                gWaveBuf(K).lpData = HeapAlloc(GetProcessHeap(), %HEAP_ZERO_MEMORY, 1024)
                IF gWaveBuf(K).lpData THEN
                   gWaveBuf(K).dwBufferLength = 512 ' 1024
                ELSE
                   nRet = 1003 ' "Unable to complete this function"
                   EXIT FOR
                END IF
            NEXT
            IF nRet = 0 THEN
               FOR K = 1 TO %NUMBUF
                   nRet = waveInPrepareHeader(gHwi, gWaveBuf(K), LEN(WAVEHDR))
                   IF nRet THEN
                      EXIT FOR
                   ELSE
                      nRet = WaveInAddBuffer(gHwi, gWaveBuf(K), LEN(WAVEHDR))
                      IF nRet THEN EXIT FOR
                   END IF
               NEXT
               IF nRet = 0 THEN
                  nRet = WaveInStart(gHwi)
               END IF
            END IF
         END IF
         IF nRet THEN gHwi = 0

         FUNCTION = nRet
         EXIT FUNCTION
         
    CASE %MM_WIM_DATA
         ' We have data
         pWaveHdr = lParam

         CALL DrawWave(hWnd, @pWaveHdr.lpData)
           
         ' Put the buffer back to be reused
         IF WaveInPrepareHeader(gHwi, BYVAL pWaveHdr, LEN(WAVEHDR)) = 0 THEN
            CALL WaveInAddBuffer(gHwi, BYVAL pWaveHdr, LEN(WAVEHDR))
         END IF

         EXIT FUNCTION
   
    CASE %WM_DESTROY
       ' Deallocate system resources
'        // Clear paint resources
         hResource = zGetPaintBitmap(hWnd)
         CALL zDeleteObject(hResource): CALL zSetProperty(hWnd, %FORM_PaintBitmap, hResource)
'        // Delete DC
         hResource = zGetPaintDC(hWnd)
         IF hResource THEN CALL DeleteDC(hResource): hResource = 0: CALL zSetProperty(hWnd, %FORM_PaintDC, hResource)

         IF gHwi THEN
            CALL WaveInStop(gHwi)
            CALL WaveInReset(gHwi)
            FOR K = 1 TO %NUMBUF
                CALL waveinUnprepareHeader(gHwi, gWaveBuf(K), SIZEOF(WAVEHDR))
            NEXT
            CALL WaveInClose(gHwi)
           
          ' DeallocBuffers
            FOR K = 1 TO %NUMBUF
                IF gWaveBuf(K).lpData THEN
                   CALL HeapFree(GetProcessHeap(), %HEAP_ZERO_MEMORY, gWaveBuf(K).lpData)
                END IF
            NEXT
           
         END IF

    END SELECT

    FUNCTION = DefWindowProc(hWnd, wMsg, wParam, lParam)
END FUNCTION

FUNCTION zOscillo(BYVAL hParent AS LONG, BYVAL x AS LONG, BYVAL y AS LONG, BYVAL W AS LONG, BYVAL H AS LONG, BYVAL ID AS LONG) AS LONG
   
    LOCAL wc     AS WndClassEx
    LOCAL zClass AS ASCIIZ * 16
    LOCAL IsInitialized, hWnd AS LONG

    zClass = "ZOSCILLO"
    wc.cbSize = SIZEOF(wc)
    IsInitialized = GetClassInfoEx(zsInstance, zClass, wc)
    IF IsInitialized    = 0 THEN
       wc.cbSize        = SIZEOF(wc)
       wc.style         = 0
       wc.lpfnWndProc   = CODEPTR(AudioProc)
       wc.cbClsExtra    = 0
       wc.cbWndExtra    = %EXTEND_EXTRA * 4
       wc.hInstance     = zsInstance
       wc.hIcon         = %NULL
       wc.hCursor       = %NULL
       wc.hbrBackground = %NULL
       wc.lpszMenuName  = %NULL
       wc.lpszClassName = VARPTR(zClass)
       wc.hIconSm       = %NULL
       IF RegisterClassEx(wc) THEN IsInitialized = -1
    END IF
    IF IsInitialized THEN
       hWnd = CreateWindowEx(0, zClass, "", %WS_CHILD OR %WS_VISIBLE, x, y, W, H, hParent, ID, zsInstance, BYVAL %NULL)
       IF hWnd THEN
          IF AudioProc(hWnd, %WM_WAVE_INIT, 0, 0) = 0 THEN
             FUNCTION = hWnd
          ELSE
             CALL DestroyWindow(hWnd)
          END IF
       END IF
    END IF

END FUNCTION


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

Petr Schreiber

Hi Patrice,

very nice! Really smooth, really live!

It runs on XPs without any touch to sound or soundcard settings.


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

psch.thinbasic.com

Kent Sarikaya

It is working, but I am not getting anywhere near an active wave as you have in your screenshot Patrice. I just get a slight vibration to a horizontal line. I only have a built in audio chip on my motherboard at the moment. No nice creative labs card. That is probably it. From the screenshot it looks very nice. The leds on the sides work fine however.

Also one other thing... when I switch plugins from 1 to 2 to 3 to 4, the music stutters when changing plugins, but the later ones don't. Has anyone had a similar problem?

Patrice Terrier

#314
Kent

In order to monitor audio in real time and draw the oscilloscope, BassBox uses WaveInGetDevCaps to detect the record device, if none is available then you will see a flat line instead of what is shown on the screen shot.

This means you must set your audio card in multiplex mode "stereo" or "what you hear" or "Wave out mix" mode.

What I could do, is to check first if there is any available Wave device capture, and if none then keep the previous display i had in older version.

When you refer to plugins, please use their name not the number, because the order may vary from one computer to the other. For example some plugins may have been desactivated or missing or some of us can have plugins that haven't been made public.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com