Recent

Author Topic: Game Boy Sound Format Player Library  (Read 1764 times)

Gigatron

  • Sr. Member
  • ****
  • Posts: 421
  • Amiga Rulez !!
    • Gigatron Shader Network Demo
Game Boy Sound Format Player Library
« on: February 19, 2026, 08:50:28 pm »
Hi

In the same idea of ASAP here GameBoy Sound Format Player Library;
Module extension is : .gbs
One module is included , you can download gbs files here ;
https://ftp.modland.com/pub/modules/Gameboy%20Sound%20System/

Source From : https://github.com/arnaud-neny/rePlayer/tree/main/source/Replays/GBSPlay

Copyright included in GBSPlay.pas file , and here ;
gbsplay - A Gameboy sound player

(C) 2003-2025 by Tobias Diedrich <ranma+gbsplay@tdiedrich.de>
                 Christian Garbs <mitch@cgarbs.de>
                 Maximilian Rehkopf <otakon@gmx.net>
                 Vegard Nossum <vegardno@ifi.uio.no>
                 Lisa Riedler <dev@riedler.wien>

Source Code licensed under GNU GPL v1 or, at your option, any later version.

Have Fun

Regards Gigatron,



« Last Edit: February 19, 2026, 09:25:38 pm by Gigatron »
Coding faster than Light !

Boleeman

  • Hero Member
  • *****
  • Posts: 1158
Re: Game Boy Sound Format Player Library
« Reply #1 on: February 20, 2026, 07:17:22 pm »
Gigatron, nice player.
Here is a version with a TFileListbox, where you can click on a filename to play it.


Gigatron, I was wondering if one could possibly have a progress bar showing how far the song has played for non-repeat mode.

rePlayer/GBSPlay/ReplayGBSPlay.cpp had a sound duration so could it possibly be put into the dll ?

In ReplayGBSPlay.cpp there was:

 m_currentDuration = (uint64_t(GetDurationMs()) * kSampleRate) / 1000;

and

 m_currentPosition = 0;
                m_currentDuration = (uint64_t(m_loops[m_subsongIndex].length) * kSampleRate) / 1000;






Regards Boleeman.



« Last Edit: February 20, 2026, 11:39:00 pm by Boleeman »

Gigatron

  • Sr. Member
  • ****
  • Posts: 421
  • Amiga Rulez !!
    • Gigatron Shader Network Demo
Re: Game Boy Sound Format Player Library
« Reply #2 on: February 20, 2026, 08:54:57 pm »
Nice work

I am going to  see that to try implementing song duration to this .dll ;

** Edit; Sorry we can not get song or subsongs duration(gb emulation )  but can set default               duration like 3.00 minutes.

Another way is fill a big buffer of wave sample during 3 minutes and play this buffer and use
progress bar, like Sidmon special version.

Regards

Gtr
« Last Edit: February 20, 2026, 10:29:21 pm by Gigatron »
Coding faster than Light !

Boleeman

  • Hero Member
  • *****
  • Posts: 1158
Re: Game Boy Sound Format Player Library
« Reply #3 on: February 20, 2026, 10:55:10 pm »
Ah, thanks Gigatron for looking at it.

I tried recompiling the GBSPlay c++ code with Visual Studio 2026 and with MinGW64 (could not get GBS_Load to work), add progressbar with default = 3 minutes (simulated progress),  as well looking for silence. All unsuccessful in doing an accurate track of the play progress.

I also looked at rePlayer (C++ version) and it seems the duration does not work either, when playing a song.
All songs are 2.30 in duration in the playlist and % did not seem to work in that c++ player when playing songs.
In the player controls section it has a duration out of 2.30 like 0.16/2.30


Still very happy with playing the GBS songs with your Lazarus bindings GBS player. Nice !


Regards Boleeman.

Also I came across https://github.com/SuperDisk/hUGETracker  which is a music composition suite for the Nintendo Game Boy and is written in Lazarus (uses SDL2)


Thanks Thausand for your void update_displaytime.
« Last Edit: February 20, 2026, 11:39:41 pm by Boleeman »

Thausand

  • Hero Member
  • *****
  • Posts: 560
Re: Game Boy Sound Format Player Library
« Reply #4 on: February 20, 2026, 11:26:02 pm »
I not know if help, player.c:
Code: C  [Select][+][-]
  1. void update_displaytime(struct displaytime *time, const struct gbs_status *status)
  2. {
  3.         long played = status->ticks / GBHW_CLOCK;
  4.         long total = status->subsong_len / 1024;
  5.  
  6.         time->played_min = played / 60;
  7.         time->played_sec = played % 60;
  8.  
  9.         if (total != 0) {
  10.                 time->total_min = total / 60;
  11.                 time->total_sec = total % 60;
  12.         } else {
  13.                 time->total_min = 99;
  14.                 time->total_sec = 99;
  15.         }
  16. }

gbhw.h
Code: C  [Select][+][-]
  1. #define GBHW_CLOCK 4194304
A docile goblin always follow HERMES.md

Gigatron

  • Sr. Member
  • ****
  • Posts: 421
  • Amiga Rulez !!
    • Gigatron Shader Network Demo
Re: Game Boy Sound Format Player Library
« Reply #5 on: February 20, 2026, 11:47:02 pm »
It's not simple to get subsongs durations cause( gb emulation ).
Replayer set defaut value to 2.30 minutes to play each songs , the only alien way is
detecting silence after the subsong is finished ... this will work if subsong finish to play
with silence. If the subsong Loop inifinite time then use default duration like Replayer 2.30Min

I will try to read the code in .c again again ! I hate this langage ;
To have someting like this in picture; But someting was wrong the programe take 15 seconds to start ... maybe scanning silence take much more cpu time.. will see that.

Regards
Coding faster than Light !

Boleeman

  • Hero Member
  • *****
  • Posts: 1158
Re: Game Boy Sound Format Player Library
« Reply #6 on: February 21, 2026, 12:02:31 am »
Thanks Gigatron.

I am stumbling in C++, but I still thought I would give it a go.
Your C++ knowledge is probably much better than mine. I dabbled in CSharp for graphics, but C++ music code is still quite difficult for me (I feel like I am just stumbling around).

Perhaps someone on the Lazarus forum with good c++ knowledge could possibly help?

Thanks for giving it a go GigaTron (and Thausand).

Looking at your previous screenshot, could songs 0, 8, 9 and 10 be set for no loop mode? whereas the 2.30 duration songs are set as endless loops?
« Last Edit: February 21, 2026, 12:11:12 am by Boleeman »

Gigatron

  • Sr. Member
  • ****
  • Posts: 421
  • Amiga Rulez !!
    • Gigatron Shader Network Demo
Re: Game Boy Sound Format Player Library
« Reply #7 on: February 21, 2026, 12:11:39 am »
Yes , sometimes it's very complex :)

Here is the latest code and .dll , set the defaut duration with spinedit like Replayer.


Regards
Coding faster than Light !

Gigatron

  • Sr. Member
  • ****
  • Posts: 421
  • Amiga Rulez !!
    • Gigatron Shader Network Demo
Re: Game Boy Sound Format Player Library
« Reply #8 on: February 21, 2026, 12:34:54 am »
Thanks Gigatron.

I am stumbling in C++, but I still thought I would give it a go.
Your C++ knowledge is probably much better than mine. I dabbled in CSharp for graphics, but C++ music code is still quite difficult for me (I feel like I am just stumbling around).

Perhaps someone on the Lazarus forum with good c++ knowledge could possibly help?

Thanks for giving it a go GigaTron (and Thausand).

Looking at your previous screenshot, could songs 0, 8, 9 and 10 be set for no loop mode? whereas the 2.30 duration songs are set as endless loops?

You mean like this ? The program stil slow more seconds to start because it's trying to find silence .

Let me some days to find the solution ;

Regards
Coding faster than Light !

Boleeman

  • Hero Member
  • *****
  • Posts: 1158
Re: Game Boy Sound Format Player Library
« Reply #9 on: February 21, 2026, 12:53:03 am »
Yes that was what I was thinking.

Ah found metadata/switch in the song file that tells the decoder to loop, so for the looped songs if we somehow unset that loop switch we can possibly get the duration for a single play?

The ReplayGBSPlay::SetupMetadata shows that it stores m_loops and sizeof(LoopInfo)) and the kDefaultSongDuration (for no loop play) in the metadata of the gbs song file as well as the number of songs.
For the looped play it uses this to set the duration length and the loops:
 len = (len * 1000) / 1024;
 m_loops = settings->loops = { 0, uint32_t(len) };

   
Code: Pascal  [Select][+][-]
  1.  void ReplayGBSPlay::SetupMetadata(CommandBuffer metadata)
  2.         {
  3.             auto numSongs = gbs_get_status(m_gbs)->songs;
  4.             auto settings = metadata.Find<Settings>();
  5.             if (settings && settings->numSongs == numSongs)
  6.             {
  7.                 for (uint32_t i = 0; i < numSongs; i++)
  8.                     m_loops[i] = settings->loops[i].GetFixed();
  9.                 m_currentDuration = (uint64_t(GetDurationMs()) * kSampleRate) / 1000;
  10.             }
  11.             else
  12.             {
  13.                 auto value = settings ? settings->value : 0;
  14.                 settings = metadata.Create<Settings>(sizeof(Settings) + numSongs * sizeof(LoopInfo));
  15.                 settings->value = value;
  16.                 settings->numSongs = numSongs;
  17.                 for (uint16_t i = 0; i < numSongs; i++)
  18.                 {
  19.                     SetSubsong(i);
  20.      
  21.                     uint64_t len = gbs_get_status(m_gbs)->subsong_len;
  22.                     if (len == 0)
  23.                         len = kDefaultSongDuration;
  24.                     else
  25.                         len = (len * 1000) / 1024;
  26.                     m_loops[i] = settings->loops[i] = { 0, uint32_t(len) };
  27.                 }
  28.                 SetSubsong(0);
  29.             }
  30.         }
  31.  

In ReplayGBSPlay.cpp I thought of m_loops in:

            numSamples = currentPosition < currentDuration ? uint32_t(currentDuration - currentPosition) : 0;
            if (numSamples == 0)
            {
                m_currentPosition = 0;
                m_currentDuration = (uint64_t(m_loops[m_subsongIndex].length) * kSampleRate) / 1000;

With m_loops set by a fixed loops array:

Code: Pascal  [Select][+][-]
  1. if (settings)
  2.         {
  3.             for (uint16_t i = 0; i < settings->numSongs; i++)
  4.                m_loops[i] = settings->loops[i].GetFixed();
  5.             m_currentDuration = (uint64_t(GetDurationMs()) * kSampleRate) / 1000;
  6.         }

Also in ReplayGBSPlay::ResetPlayback there is uint64_t(GetDurationMs()) in here so could GetDurationMs be used for the progress bar?

void ReplayGBSPlay::ResetPlayback()
    {
        gbs_init(m_gbs, m_subsongIndex);
        m_surround.Reset();
        m_currentPosition = 0;
        m_currentDuration = (uint64_t(GetDurationMs()) * kSampleRate) / 1000;
        m_bufPos = kMaxSamples;
    }


Lastly the 15 seconds to start could it be possibly due to the wait time for the creation of Data Buffer m_bufDataCopy in auto buffer?
auto buf = m_bufDataCopy + currrentPos * 2
« Last Edit: February 21, 2026, 02:28:18 am by Boleeman »

Thausand

  • Hero Member
  • *****
  • Posts: 560
Re: Game Boy Sound Format Player Library
« Reply #10 on: February 21, 2026, 01:01:51 am »
I have make small more investigate. Default subsong_len (timeout) is set 120 (this is override and have suggest subsong_len is not set or not calculate correct: is difficult because have need and add cpu instruction cycle and that is depend on code).

loop mode can set use gbs_set_loop_mode (default off)

can set length for subsong timeout use gbs_configure. I have try understand what all parameter value do (subsong_timeout, silence_timeout, subsong_gap, fadeout) but is no clear for me how/when work exact.

I have think Gigatron have more better idea and have check if samples is silence then is end of song. Ii not know if can help for check channel volume status.
« Last Edit: February 21, 2026, 01:14:52 am by Thausand »
A docile goblin always follow HERMES.md

Boleeman

  • Hero Member
  • *****
  • Posts: 1158
Re: Game Boy Sound Format Player Library
« Reply #11 on: February 21, 2026, 01:14:00 am »
Yes Thausand I saw that gbs_set_loop_mode could be set in the C++ replayer via a command button to no loop and endless song and playlist loop so I think for the progressbar  we need the duration time for no loop?

I also noticed if you set replayer to no loop to total duration still stays at 2.30 rather than going to the no loop song duration time.


Yes I think you are on the right track (possibly subsong_gap, silence_timeout) for the 15 seconds silence:
subsong_timeout, silence_timeout, subsong_gap, fadeout
« Last Edit: February 21, 2026, 02:29:06 am by Boleeman »

Gigatron

  • Sr. Member
  • ****
  • Posts: 421
  • Amiga Rulez !!
    • Gigatron Shader Network Demo
Re: Game Boy Sound Format Player Library
« Reply #12 on: February 21, 2026, 02:30:42 am »
Ok

Program start time < 5 sec , this is because it's scan if silents occured after song finished or not
if not then use default duration. I am working on the final stage .. so be patient ;
Don't forget gbs emulate Z80 chip.

Regards

« Last Edit: February 21, 2026, 02:35:01 am by Gigatron »
Coding faster than Light !

Boleeman

  • Hero Member
  • *****
  • Posts: 1158
Re: Game Boy Sound Format Player Library
« Reply #13 on: February 21, 2026, 02:39:33 am »
Thanks for the previous update GigaTron.

I also saw in the C++ rePlayer settings.ini there is ReplayKSSSilence=5 so possibly that is why "Program start time < 5 sec"

Interesting.

Bye for now. Time for lunch.
« Last Edit: February 21, 2026, 02:41:04 am by Boleeman »

Gigatron

  • Sr. Member
  • ****
  • Posts: 421
  • Amiga Rulez !!
    • Gigatron Shader Network Demo
Re: Game Boy Sound Format Player Library
« Reply #14 on: February 21, 2026, 12:44:41 pm »
Hi

Reading the source file for now; like i said i hate C & C++ , but i understand those langage.

Thank you @Boleeman and @Thausand for your contibution.

Regards GTR
Coding faster than Light !

 

TinyPortal © 2005-2018