jkotlinski / lsdpack

Standalone LSDj recorder+player
GNU General Public License v2.0
116 stars 18 forks source link

Support LSDj 9.2.0+ #19

Open jkotlinski opened 3 years ago

jkotlinski commented 3 years ago

Interrupts and sample playback changed. Basically nothing works anymore.

binarycounter commented 10 months ago

Heyo! Thanks for making LSDj and this tool! I'd love to get 9.2.0+ support working to include music in a SGB demo.

I made a quick change to lsdpack.cpp and some libgambatte files to basically replace the LCD Interrupt handler with a Timer interrupt handler, changing otherwise nothing.

I've then recorded a 9.3.3 tune in DMG mode (because CGB has double speed timers, halving the song tempo in the player) and built the example boot.s.

Sample / wavetable playback is a bit scratchy (player.s probably needs to be updated with improved wave swap routine) but otherwise the song seems to play fine. If i can get the wave channel playing nicely, would you be interested in a pull request?

jkotlinski commented 10 months ago

Yes, I would welcome any help. I have been too busy lately.

Getting sample and wave playback to work well is the difficult part. Let me know if you have any questions how it works.

To keep in mind: even if it is troublesome, I am sure some would appreciate keeping support of old versions (especially v4).

sön 5 nov. 2023 kl. 02:07 skrev BinaryCounter @.***>:

Heyo! Thanks for making LSDj and this tool! I'd love to get 9.2.0+ support working to include music in a SGB demo.

I made a quick change to lsdpack.cpp and some libgambatte files to basically replace the LCD Interrupt handler with a Timer interrupt handler, changing otherwise nothing.

I've then recorded a 9.3.3 tune in DMG mode (because CGB has double speed timers, halving the song tempo in the player) and built the example boot.s.

Sample / wavetable playback is a bit scratchy (player.s probably needs to be updated with improved wave swap routine) but otherwise the song seems to play fine. If i can get the wave channel playing nicely, would you be interested in a pull request?

— Reply to this email directly, view it on GitHub https://github.com/jkotlinski/lsdpack/issues/19#issuecomment-1793597748, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAY34O2ZHC3VXAL27VQZPMDYC3RDPAVCNFSM4YV7O5R2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZZGM2TSNZXGQ4A . You are receiving this because you authored the thread.Message ID: @.***>

binarycounter commented 10 months ago

Awesome, thank you. I have forked the repository and pushed my changes of lsdpack. Will pull request later once i think it's finished.

The way I am currently handling compatibility with older versions is to check the version number in the GB header of the ROM and decide which interrupts to capture based on that, with optional command-line flags to override the auto-detection. I have not tested v4 specifically, but compatibility should remain identical with previous lsdpack versions, unless someone edited the ROM header (then they would need to use the command-line flag to force <9.1.C mode). Note: I moved setting the interrupt handler inside load_gb to be able to do it on a per-ROM basis, so you could mix old and new versions.

Sample playback is actually not that bad, I'm just noticing more crackling as the player swaps out the wave. Looking at recordings it seems like newer LSDj versions have a much more graceful way of swapping waves, which doesn't cause such a noticable audio spike. Definitely seeing some differences stepping through the code. It seems faster overall (putting the data on the stack and then pop-sliding it). I will investigate later. If you have any pointers of where I should be looking at, please let me know.

The test file i'm currently using ends up being 328k big, so I'd love to also look into compression like you mentioned. A few days ago I've experimented with implementing a LZ77/78 style compression scheme (for another playback routine) that works on a command basis rather than byte basis . Rather than needing to compress and decompress the data, it relies on the routine's loop and referencing commands to deduplicate data, so other than some pointer manipulation it's fairly light on the CPU. I got decent results there, and will look into getting it working for this too.

Sorry for the long read :)

jkotlinski commented 10 months ago

For the sample playback. The biggest change i remember for sample playback, was to make it driven by timer rather than LCD interrupt. The timer is reset in every vertical blank. For best playback quality, the timer must trigger with a very stable rate, without any delays or hiccups. Also, the sample playback interrupt handler has changed. It is not compatible between new and old versions.

sön 5 nov. 2023 kl. 17:12 skrev BinaryCounter @.***>:

Awesome, thank you. I have forked https://github.com/binarycounter/lsdpack the repository and pushed my changes of lsdpack. Will pull request later once i think it's finished.

The way I am currently handling compatibility with older versions is to check the version number in the GB header of the ROM and decide which interrupts to capture based on that, with optional command-line flags to override the auto-detection. I have not tested v4 specifically, but compatibility should remain identical with previous lsdpack versions, unless someone edited the ROM header (then they would need to use the command-line flag to force <9.1.C mode). Note: I moved setting the interrupt handler inside load_gb to be able to do it on a per-ROM basis, so you could mix old and new versions.

Sample playback is actually not that bad, I'm just noticing more crackling as the player swaps out the wave. Looking at recordings it seems like newer LSDj versions have a much more graceful way of swapping waves, which doesn't cause such a noticable audio spike. Definitely seeing some differences stepping through the code. It seems faster overall (putting the data on the stack and then pop-sliding it). I will investigate later. If you have any pointers of where I should be looking at, please let me know.

The test file i'm currently using ends up being 328k big, so I'd love to also look into compression like you mentioned https://github.com/jkotlinski/lsdpack/issues/12. A few days ago I've experimented with implementing a LZ77/78 style compression scheme (for another playback routine) that works on a command basis rather than byte basis . Rather than needing to compress and decompress the data, it relies on the routine's loop and referencing commands to deduplicate data, so other than some pointer manipulation it's fairly light on the CPU. I got decent results there, and will look into getting it working for this too.

Sorry for the long read :)

— Reply to this email directly, view it on GitHub https://github.com/jkotlinski/lsdpack/issues/19#issuecomment-1793779360, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAY34O7CB5M7A3SXQ5VTXNTYC63GJAVCNFSM4YV7O5R2U5DIOJSWCZC7NNSXTN2JONZXKZKDN5WW2ZLOOQ5TCNZZGM3TOOJTGYYA . You are receiving this because you authored the thread.Message ID: @.***>