Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Accumulate GUS frames accross each voice instead of per-sample (#2696) #2698

Merged
merged 2 commits into from Jul 23, 2023

Conversation

kcgen
Copy link
Member

@kcgen kcgen commented Jul 22, 2023

Previously when rendering frames in the GUS, we iterated one sample at a time, gathering the next panned sample from each voice into the resulting frame before moving onto the next frame (and again, gathering the next sample from all the voices).

         start
          i=0,     i=1,    i=2, .. for N frames
           |        |       |
           V        V       V
voice 1  [v1s0]   [v1s1]   ...
voice 2 +[v2s0]  +[v2s1]   ...
voice 3 +[v3s0]  +[v3s1]   ...
...
output = {summed-s0, summed-s1, summed-s2 ... }

Rendering samples from the GUS changes its state, and in the case of Duke 3D, the above approach doesn't traverse all of the available samples in all the populated voices before a state change halts one or more of the voices, resulting in essentially a truncated sequence.

This change switches back to how the original SVN and X GUS rendering loops work, which is to gather samples per-voice first, summing all of the samples across an array. This ensures that we gather all the requested samples from each voice before moving onto the next voice.

start
i=1 ->  voice 1   [v1s0]   [v1s1]   ... for N frames
i=2,    voice 2  +[v2s0]  +[v2s1]   ... for N frames
i=3,    voice 3  +[v3s0]  +[v3s1]   ... for N frames
...
output = {summed-s0, summed-s1, summed-s2 ... }

The sub-millisecond rendering prior to port and register writes is still in place, as is the use of the mixer's floating-point compressor.

Fixes #2696 ; thanks for reporting @x73rmin8r!

@kcgen kcgen added regression We broke something 😊 audio Audio related issues or enhancements labels Jul 22, 2023
@kcgen kcgen requested a review from johnnovak July 22, 2023 23:38
@kcgen kcgen self-assigned this Jul 22, 2023
src/hardware/gus.cpp Outdated Show resolved Hide resolved
src/hardware/gus.cpp Outdated Show resolved Hide resolved
src/hardware/gus.cpp Outdated Show resolved Hide resolved
src/hardware/gus.cpp Outdated Show resolved Hide resolved
src/hardware/gus.cpp Outdated Show resolved Hide resolved
@johnnovak
Copy link
Member

Nice quick fix @kcgen , will test shortly with a few demos and mod players as well 👍🏻

Previously when rendering frames in the GUS, we iterated one sample
at a time, gathering the next panned sample from each voice into the
resulting frame before moving onto the next frame (and again,
gathering the next sample from all the voices).

          start
          i=0,     i=1,    i=2, .. for N frames
           |        |       |
           V        V       V
voice 1  [v1s0]   [v1s1]   ...
voice 2 +[v2s0]  +[v2s1]   ...
voice 3 +[v3s0]  +[v3s1]   ...
...
output = {summed-s0, summed-s1, summed-s2 ... }

Rendering samples from the GUS changes its state, and in the case of
Duke 3D, the above approach doesn't traverse all of the available
samples in all the populated voices before a state change halts one or
more of the voices, resulting in essentially a truncated sequence.

This change switches back to how the original SVN and X GUS rendering
loops work, which is to gather samples per-voice first, summing all
of the samples across an array. This ensures that we gather all the
requested samples from each voice before moving onto the next voice.

start
i=1 ->  voice 1   [v1s0]   [v1s1]   ... for N frames
i=2,    voice 2  +[v2s0]  +[v2s1]   ... for N frames
i=3,    voice 3  +[v3s0]  +[v3s1]   ... for N frames
...
output = {summed-s0, summed-s1, summed-s2 ... }

The sub-millisecond rendering prior to port and register writes is
still in place, as is the use of the mixer's floating-point
compressor.
Copy link
Member

@johnnovak johnnovak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The issue in Duke3D is now gone. I've also tried FastTracker II, CapaMod and a few demos—all good 🎉 Feel free to merge @kcgen once you've addressed those minor issues.

@kcgen
Copy link
Member Author

kcgen commented Jul 23, 2023

The issue in Duke3D is now gone. I've also tried FastTracker II, CapaMod and a few demos—all good tada Feel free to merge @kcgen once you've addressed those minor issues.

Thanks for the bisect, review, and test feedback @johnnovak !

@kcgen kcgen merged commit 5d88159 into main Jul 23, 2023
51 checks passed
@kcgen kcgen deleted the kc/gus-voice-samples-1 branch July 23, 2023 01:21
@johnnovak
Copy link
Member

The issue in Duke3D is now gone. I've also tried FastTracker II, CapaMod and a few demos—all good tada Feel free to merge @kcgen once you've addressed those minor issues.

Thanks for the bisect, review, and test feedback @johnnovak !

Nice one! You're back and you're solving issues in a swift manner on day 1! 🚀 😎 🤘🏻

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
audio Audio related issues or enhancements regression We broke something 😊
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Gravis Ultrasound sound effects fuzzy/crackly in DUKE3D when set to 44kHz
2 participants