• Welcome to Theos PowerBasic Museum 2017.

News:

Attachments are only available to registered users.
Please register using your full, real name.

Main Menu

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.

Kent Sarikaya

Wow, that is cool, plug-ins, simple click and change visual effects, very cool job guys.
Charles, loved seeing your cool dome structures visualization too!

Patrice Terrier

#31
BassBox now has a 10-band equalizer!

VISTA screenshot:


The Equalizer setup is saved/restored from registry using this couple of new functions:

' Returns a registry string
FUNCTION zsGetReg ALIAS "zsGetReg" (BYVAL hLocation AS DWORD, zSubKeys AS ASCIIZ, zValueName AS ASCIIZ) EXPORT AS STRING
    LOCAL hKey AS DWORD, zRegVal AS ASCIIZ * %MAX_PATH, dwType AS DWORD, dwSize AS DWORD
    IF hLocation = 0 THEN hLocation = %HKEY_CURRENT_USER
    IF (RegOpenKeyEx(hLocation, TRIM$(zSubKeys, $Anti), 0, %KEY_READ, hKey) = 0) THEN
       dwType = %REG_SZ
     ' Set length of buffer...
       dwSize = SIZEOF(zRegVal)
       CALL RegQueryValueEx(hKey, zValueName, 0, dwType, zRegVal, dwSize)
       CALL RegCloseKey(hKey)
    END IF
    FUNCTION = zRegVal
END FUNCTION

' Saves a string value to the registry, returns nonzero if successful
FUNCTION zsSetReg ALIAS "zsSetReg" (BYVAL hLocation AS DWORD, zSubKeys AS ASCIIZ, zRegName AS ASCIIZ, zRegVal AS ASCIIZ) EXPORT AS LONG
    LOCAL hKey AS DWORD, dwType AS DWORD, dwSize AS DWORD
    nRet& = 0
    IF hLocation = 0 THEN hLocation = %HKEY_CURRENT_USER
    IF RegCreateKeyEx(hLocation, TRIM$(zSubKeys, $Anti), 0, "", 0, %KEY_WRITE, BYVAL %Null, hKey, BYVAL %Null) = 0 THEN
     ' Set length of data...
       dwSize = LEN(zRegVal)
       dwType = %REG_SZ
       IF RegSetValueEx(hKey, zRegName, 0, dwType, zRegVal, dwSize) = 0 THEN nRet& = %True
       RegCloseKey hKey
    END IF
    FUNCTION = nRet&
END FUNCTION



As you can see, when you master "low level SDK programming" there is nothing you can't do with an interface, imagination is your limit. ;D

And you know what?... finaly I think, I start to like VISTA  :o

...

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

Petr Schreiber

#32
:)

New equalizer works perfectly, nice to see how different setup can totally change sound of songs.
In combination with "Flanger" effects it is easy to create terrible sound of old VHS movie :)


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

psch.thinbasic.com

Patrice Terrier

#33
I have added ID3 TAG support (version 1.0 et 1.1)



'// So far this version decodes only ID3 TAG Version 1.0 et 1.1
FUNCTION BassGetID3TAG(zFileName AS ASCIIZ) AS LONG
    LOCAL So, nSuccess, hFile AS LONG, sComment, sTrack, sFileName, sB, sTag AS STRING
    LOCAL sTitle, sArtist, sAlbum, sYear, sType AS STRING

    nSuccess = 0
    CALL ShowWindow(zGetMainItem(%ID_TAG_TITLE), %SW_HIDE)
    CALL ShowWindow(zGetMainItem(%ID_TAG_ALBUM), %SW_HIDE)
    CALL ShowWindow(zGetMainItem(%ID_TAG_ARTIST), %SW_HIDE)
    CALL ShowWindow(zGetMainItem(%ID_TAG_TYPE), %SW_HIDE)
    CALL ShowWindow(zGetMainItem(%ID_TAG_EMPTY), %SW_HIDE)
    IF zsFOpen(zFileName, 0, 2, hFile) = 0 THEN
       CALL zSplitN (zFileName, "", sFileName)
       So = INSTR(-1, sFileName, $Dot)
       IF So THEN sFileName = LEFT$(sFileName, So)
       sTag = SPACE$(128)
       IF zsFGetAt(hFile, zsFlof(hFile) - 128, sTag) = 0 THEN
          IF LEFT$(sTag, 3) = "TAG" THEN
             REDIM sTagItem(1 TO 7) AS STRING
             sB = CHR$(32,0)
             sTag = RIGHT$(sTag, 125)
             sTitle = TRIM$(MID$(sTag, 1, 30), ANY sB)
             IF UCASE$(sTitle) = LEFT$(UCASE$(sFileName), LEN(sTitle)) THEN sTitle = sFileName

             sArtist = RTRIM$(MID$(sTag, 31, 30), ANY sB)
             IF UCASE$(sArtist) = "ARTIST" THEN sArtist = ""

             sAlbum = RTRIM$(MID$(sTag, 61, 30), ANY sB)
             IF UCASE$(sAlbum) = "TITLE" THEN sAlbum = ""

             sYear = RTRIM$(MID$(sTag, 91, 4), ANY sB)
             
             sComment = MID$(sTag, 95, 30)
             IF ASC(sComment, 29) = 0 THEN
                sTrack = LTRIM$(STR$(ASC(MID$(sComment, 30, 1))))
                IF ASC(sTrack) > 0 THEN sTrack = "#" + sTrack
                sComment = LEFT$(sComment, 28)
             END IF
             sComment = RTRIM$(sComment, ANY sB)
             
             sType = PARSE$("Blues,Classic Rock,Country,Dance,Disco,Funk,Grunge,Hip-Hop,Jazz,Metal,New Age,Oldies," + _
                            "Other,Pop,R&B,Rap,Reggae,Rock,Techno,Industrial,Alternative,Ska,Death Metal,Pranks," + _
                            "Soundtrack,Euro-Techno,Ambient,Trip-Hop,Vocal,Jazz+Funk,Fusion,Trance,Classical," + _
                            "Instrumental,Acid,House,Game,Sound Clip,Gospel,Noise,Alternative Rock,Bass,Soul," + _
                            "Punk,Space,Meditative,Instrumental Pop,Instrumental Rock,Ethnic,Gothic,Darkwave," + _
                            "Techno-Industrial,Electronic,Pop-Folk,Eurodance,Dream,Southern Rock,Comedy,Cult," + _
                            "Gangsta,Top 40,Christian Rap,Pop/Funk,Jungle,Native US,Cabaret,New Wave,Psychadelic," + _
                            "Rave,Showtunes,Trailer,Lo-Fi,Tribal,Acid Punk,Acid Jazz,Polka,Retro,Musical,Rock & Roll," + _
                            "Hard Rock,Folk,Folk-Rock,National Folk,Swing,Fast Fusion,Bebob,Latin,Revival,Celtic," + _
                            "Bluegrass,Avantgarde,Gothic Rock,Progressive Rock,Psychedelic Rock,Symphonic Rock," + _
                            "Slow Rock,Big Band,Chorus,Easy Listening,Acoustic,Humour,Speech,Chanson,Opera,Chamber Music," + _
                            "Sonata,Symphony,Booty Bass,Primus,Porn Groove,Satire,Slow Jam,Club,Tango,Samba,Folklore," + _
                            "Ballad,Power Ballad,Rhytmic Soul,Freestyle,Duet,Punk Rock,Drum Solo,Acapella,Euro-House," + _
                            "Dance Hall,Goa,Drum & Bass,Club-House,Hardcore,Terror,Indie,BritPop,Negerpunk,Polsk Punk," + _
                            "Beat,Christian Gangsta Rap,Heavy Metal,Black Metal,Crossover,Contemporary Christian," + _
                            "Christian Rock,Merengue,Salsa,Trash Metal,Anime,Jpop,Synthpop", ASC(sTag, 125) + 1)                       
             
             sTag = ""
             nSuccess = -1
          END IF
       END IF
       CALL zsFClose(hfile)
    END IF
   
    IF nSuccess THEN
       zSetCTLText(zGetMainItem(%ID_TAG_TITLE), (UCASE$(sTitle)))
       IF LEN(sYear) THEN sYear = " (" + sYear + ")"
       zSetCTLText(zGetMainItem(%ID_TAG_ALBUM), (TRIM$(sAlbum + sYear)))
       zSetCTLText(zGetMainItem(%ID_TAG_ARTIST), (sArtist))
       zSetCTLText(zGetMainItem(%ID_TAG_TYPE), (sType))
       CALL ShowWindow(zGetMainItem(%ID_TAG_TITLE), %SW_SHOW)
       CALL ShowWindow(zGetMainItem(%ID_TAG_ALBUM), %SW_SHOW)
       CALL ShowWindow(zGetMainItem(%ID_TAG_ARTIST), %SW_SHOW)
       CALL ShowWindow(zGetMainItem(%ID_TAG_TYPE), %SW_SHOW)
    ELSE
       CALL zSetCTLText(zGetMainItem(%ID_TAG_EMPTY), (UCASE$(sFileName)))
       CALL ShowWindow(zGetMainItem(%ID_TAG_EMPTY), %SW_SHOW)
    END IF

    FUNCTION = nSuccess

END FUNCTION


The latest ZIP is attached under this message

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

Petr Schreiber

Thanks,

works great over here :)


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

psch.thinbasic.com

Patrice Terrier

#35
Charles, (and others as well)

You asked for it...

This new version is able to play WMA audio files (it requires the provided BassWma.dll) and WMA audio support must already be available (it comes along with Windows Media Player).
If you don't plan to use Windows Media Player and only want the audio CODEC then use this redistribution file:
wmfdist.exe

Note: I have also added the BassTags.dll to decode ID3 TAG for all the supported audio files.
So far: mp1, mp2, mp3, wav, ogg, aif, wma.

There is also a new Bass.dll file that is smaller than the previous one, because it uses the Windows built-in mp3 support that is free.
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Charles Pegge

Thanks Patrice, It's looking (and sounding) very good!

If you are using Media Player infrastructure, can it also support MIDI or does that come by a different route?

As well as Midi, one particular interest I have at the moment is in real-time wave synthesis, which computes sounds in frame-based time slices and inserts them into a looping audio buffer. Ideal for computer games because they do not need to be distributed with sound files, and this technique also enables ambient sound generation without repetition. There does not seem to be much about this on the web. While I am not averse to reinventing the wheel it would be nice to see if there are any other synth projects like this in the public domain.




Kent Sarikaya

Charles you might be interested in this: http://supercollider.sourceforge.net/videos?MoodleSessionscsite=9c6ea0afe3e166d5500a5bf08586bfc2
I have not used it, but the program is now 10 years old and opensource.

Thanks Patrice, each patch just gets better and better!

Charles Pegge

Thanks Kent, interesting project, but the examples, well let's just say they are meagre, which suggests a lack of progress over ten years. I think many Video games use minimalist composition very effectively, but there are real musicians behind that.

At the moment I am trying to understand how the wave audio buffers work. I seem to be getting very large delays in the callback generated when a buffer is empty and needs topping up. But the Wave generation side is working fine.

Patrice Terrier

#39
Little variation on the same theme...

See attached CrystalPsource.zip

(I am doing that one, to post it on CrystalXP)
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

Thanks Patrice,

now it looks even more futuristic :)


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

psch.thinbasic.com

Kent Sarikaya

Oh, I really like this version. Very very nice looking and sleek!! Excellent Patrice, you keep surpassing yourself!!!

Charles Pegge


Real Panache. I'd love to develop some choreographed forms for this. Can we implement a simple plug-in along the lines we discussed earlier?

One thing you will need to check . I think there is a memory leak - In XP it will crash after a substantial number of replays. >10 maybe.

Patrice Terrier

#43
Charles

I found myself a problem with the BASS.dll free mp3 version, may be it is the same.
Thus I switched back to the plain version that I have attached to this message for your conveniance.


QuoteCan we implement a simple plug-in along the lines we discussed earlier?
Sure, please go ahead, I would like very much to add more plug-in effects.

By the way I have a question about using glGenTexture()
I am unsure of the best place to use glDeleteTexture() with it, could you give me some insight?

I am doing this myself to create textures:


FUNCTION ZI_SetGLTextureFromFile ALIAS "ZI_SetGLTextureFromFile" (zFullName AS ASCIIZ) EXPORT AS LONG
    DIM Texture(0) AS LONG, Ret AS LONG
    REDIM PixelArray(0) AS BYTE
    IF ZI_CreateGLTextureFromFile(zFullName, xSize&, ySize&, PixelArray()) THEN
       CALL glGenTextures(1, Texture(0)): Ret = glGetError
       IF Ret& = 0 THEN CALL glBindTexture(%GL_TEXTURE_2D, Texture(0)): Ret = glGetError

       IF Ret& = 0 THEN CALL glTexParameteri(%GL_TEXTURE_2D, %GL_TEXTURE_MAG_FILTER, %GL_LINEAR): Ret = glGetError
       IF Ret& = 0 THEN CALL glTexParameteri(%GL_TEXTURE_2D, %GL_TEXTURE_MIN_FILTER, %GL_LINEAR): Ret = glGetError

       IF Ret& = 0 THEN CALL glTexImage2D(%GL_TEXTURE_2D, 0, 3, xSize&, ySize&, 0, %GL_RGB, %GL_UNSIGNED_BYTE, PixelArray(0)): Ret = glGetError

       FUNCTION  = Ret&
    END IF
END FUNCTION


FUNCTION ZI_CreateGLTextureFromFile ALIAS "ZI_CreateGLTextureFromFile" (zFullPath AS ASCIIZ, xSize AS LONG, ySize AS LONG, PixelArray() AS BYTE) EXPORT AS LONG

    LOCAL bi AS MYBITMAPINFO
    LOCAL pBits AS BYTE PTR
    LOCAL hIC AS LONG, hTmpDC AS LONG, hBitmap AS LONG

    xSize = 0: ySize = 0
    CALL ZI_GetImageSizeFromFile(zFullPath, bmW&, bmH&)
    DIM P(1 TO 11) AS LONG
    P(1)= 2: P(2) = 4: P(3) = 8: P(4) = 16: P(5) = 32: P(6) = 64: P(7) = 128: P(8)= 256: P(9) = 512: P(10) = 1024: P(11) = 2048
    FOR K& = UBOUND(P) TO LBOUND(P) STEP -1
        IF xSize = 0 AND bmW& > P(K&) - 1 THEN xSize = P(K&)
        IF ySize = 0 AND bmH& > P(K&) - 1 THEN ySize = P(K&)
    NEXT
    IF DoNotSquareTexture(0,0) THEN
       CALL DoNotSquareTexture(0, 1)
    ELSE
       xSize = MAX&(xSize, ySize): ySize = xSize
    END IF

    hBitmap = ZI_FitImageFromFile(zFullPath, xSize, ySize)
    IF hBitmap THEN
       hIC = zDisplayDC()
       hTmpDC = CreateCompatibleDC(hIC)
       CALL SelectObject(hTmpDC, hBitmap)

       bi.bmiHeader.biSize        = SIZEOF(bi.bmiHeader)
       bi.bmiHeader.biWidth       = xSize
       bi.bmiHeader.biHeight      = ySize
       bi.bmiHeader.biPlanes      = 1
       bi.bmiHeader.biBitCount    = 24
       bi.bmiHeader.biCompression = %BI_RGB
       REDIM PixelArray(0 TO xSize * ySize * 3 - 1) AS BYTE
       IF GetDIBits(hTmpDC, hBitmap, 0, ySize, PixelArray(0), BYVAL VarPtr(bi), %DIB_RGB_COLORS) THEN
       '  Perform Red and Green permutation
          pBits = VARPTR(PixelArray(0))
          FOR K& = (xSize * ySize) TO 1 STEP - 1
              R? = @pBits[2]: @pBits[2] = @pBits[0]: @pBits[0] = R?: pBits = pBits + 3
          NEXT

          FUNCTION = -1

       END IF
       CALL DeleteDC(hIC)
       CALL DeleteDC(hTmpDC)
       CALL DeleteObject(hBitmap)
    END IF

END FUNCTION


If I want to replace an existing texture by a new one where is the best place to put the glDeleteTexture() to avoid memory leak?
Patrice Terrier
GDImage (advanced graphic addon)
http://www.zapsolution.com

Petr Schreiber

#44
Hi Patrice,

I think you should use it like that:
Quote
FUNCTION ZI_SetGLTextureFromFile ALIAS "ZI_SetGLTextureFromFile" (zFullName AS ASCIIZ) EXPORT AS LONG
    DIM Texture(0) AS LONG, Ret AS LONG
    REDIM PixelArray(0) AS BYTE
    IF ZI_CreateGLTextureFromFile(zFullName, xSize&, ySize&, PixelArray()) THEN
       CALL glDeleteTextures(1, Texture(0))
       CALL glGenTextures(1, Texture(0)): Ret = glGetError
       IF Ret& = 0 THEN CALL glBindTexture(%GL_TEXTURE_2D, Texture(0)): Ret = glGetError

       IF Ret& = 0 THEN CALL glTexParameteri(%GL_TEXTURE_2D, %GL_TEXTURE_MAG_FILTER, %GL_LINEAR): Ret = glGetError
       IF Ret& = 0 THEN CALL glTexParameteri(%GL_TEXTURE_2D, %GL_TEXTURE_MIN_FILTER, %GL_LINEAR): Ret = glGetError

       IF Ret& = 0 THEN CALL glTexImage2D(%GL_TEXTURE_2D, 0, 3, xSize&, ySize&, 0, %GL_RGB, %GL_UNSIGNED_BYTE, PixelArray(0)): Ret = glGetError

       FUNCTION  = Ret&
    END IF
END FUNCTION

... and then when you destroy window of course.

In case there is not texture yet in Texture() global array, glDeleteTextures will simply do nothing according to specification:
Quote
glDeleteTextures silently ignores 0's and names that do not
correspond to   existing textures.
... so you do not have to take care of deleting textures only when there are some.


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

psch.thinbasic.com