Skip to content

Conversation

@illwieckz
Copy link
Member

Implement the builtin sound/null.wav file.

@illwieckz illwieckz changed the title audio: implement the builtin audio/sound.wav file audio: implement the builtin sound/null.wav file Oct 8, 2025
@illwieckz illwieckz changed the title audio: implement the builtin sound/null.wav file Implement the builtin sound/null.wav file Oct 8, 2025
@illwieckz illwieckz changed the title Implement the builtin sound/null.wav file implement the builtin sound/null.wav file Oct 8, 2025
@illwieckz illwieckz changed the title implement the builtin sound/null.wav file Implement the builtin sound/null.wav file Oct 8, 2025
@illwieckz illwieckz force-pushed the illwieckz/builtin-null-wav branch from 1b73d61 to 8dce432 Compare October 8, 2025 03:56
@illwieckz
Copy link
Member Author

One drawback of such implementation is that:

] which sound/null.wav
File not found: "sound/null.wav"

@illwieckz
Copy link
Member Author

illwieckz commented Oct 8, 2025

The good thing in that implementation is that the null samples now only takes 2 bytes in memory when loaded!

Once compiled the code implementing it is probably smaller than the 46 bytes of the “smallest silent WAV file ever” that could be embedded instead.


static int numSoundLoaders = ARRAY_LEN(soundLoaders);

static bool IsNullSample(std::string& filename)
Copy link
Member

Choose a reason for hiding this comment

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

How about simply filename == "sound/null" || filename == "sound/null.wav"? This would be more correct in the case of something like sound/null.notarealextension

Copy link
Member Author

Choose a reason for hiding this comment

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

Hmm, right, someone may look for null.not expecting to load null.not.opus.

So the best would be to look for the basename with known extensions instead.

Copy link
Member Author

Choose a reason for hiding this comment

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

For the moment the code doesn't care for unknown extensions:

]/playMusic sound/ui/heartbeat.plop
Debug: Loading Sample 'sound/ui/heartbeat.plop'
]/playMusic sound/ui/heartbeat1.haha
Debug: Loading Sample 'sound/ui/heartbeat1.haha'

So there may be redesigns to do that are not part of this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

I taken care of not misdetecting non-existent extensions, but actually the existing code is very perfectible and should be revamped at some point (see below).

Also it's funny that the sound/null sample is now the only sound file that fails to load when attempting to load it with an unknown extension.

Copy link
Member

Choose a reason for hiding this comment

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

What's wrong with just filename == "sound/null" || filename == "sound/null.wav"? The loader iteration thing is unnecessarily complex. There is no reason for anyone to ever write sound/null.opus.

Copy link
Member Author

@illwieckz illwieckz Oct 13, 2025

Choose a reason for hiding this comment

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

Well, I prefer to be exhaustive… I did in Sample.cpp without ext check.


AudioData LoadSoundCodec(std::string filename)
{
if (IsNullSample(filename)) {
Copy link
Member

Choose a reason for hiding this comment

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

Nit: I think the more conceptually correct place for this would be in Sample::Load, since in this case we aren't using a codec.

Copy link
Member Author

Choose a reason for hiding this comment

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

The soundExtToLoaderMap_t isn't known from Sample.cpp so testing for the extension would not keep the code self-contained in a single file.

// 16bit mono 8KHz, 1 sample, silence.
unsigned char *null_wav = (unsigned char*) calloc( 1, 2 );
AudioData out { 8000, 2, 1 };
out.rawSamples.assign( null_wav, null_wav + 2 );
Copy link
Member

Choose a reason for hiding this comment

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

out.rawSamples.resize(2) (fills with zeroes) ? The current version does a memory leak. Also why not 8-bit? :-)

Copy link
Member Author

Choose a reason for hiding this comment

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

Also why not 8-bit? :-)

If the engine allows it, why not. I'll try.

Copy link
Member Author

Choose a reason for hiding this comment

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

The engine itself doesn't complain, but when I do:

]/playMusic sound/null

I hear a click noise, likely from the audio subsystem itself when switching the resampling mode or so. That should not happen, but we better do not randomly change the size and keep the things done as usual.

Copy link
Member

Choose a reason for hiding this comment

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

The null_wav memory leak still needs to be fixed. One alternative would be out.rawSamples.resize(2) to fill with two zeroes.

Copy link
Member Author

Choose a reason for hiding this comment

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

Oh lol that's the worst occurrence of ghost code resurfacing on rebase I ever seen!

Reimplemented the .resize(2) way.

@slipher slipher mentioned this pull request Oct 8, 2025
@slipher
Copy link
Member

slipher commented Oct 8, 2025

Also don't forget to delete it from daemon_src.dpkdir.

@illwieckz illwieckz force-pushed the illwieckz/builtin-null-wav branch from 3cee189 to 6c83ef0 Compare October 8, 2025 22:41
@illwieckz
Copy link
Member Author

I reworked the detection of the null sound file to avoid misdetecting sound/null.not as sound/null.wav instead of sound/null.not.opus, and I kept the code in LoadSoundCodec() because with the current design it's the most convenient place.

A lot of things is messy in the existing code: the code reports as empty a missing file, it reports the loading of sound files with any extension that doesn't exist and you can reload it as many time as you request a different extension, it does string copies all the way down, etc. But revamping that would require its own PR and that would be a large PR. That's why I stick to the least intrusive effort of hijacking LoadSoundCodec() for now.

I now deleted the file from the dpkdir.

@illwieckz illwieckz force-pushed the illwieckz/builtin-null-wav branch from 6c83ef0 to 01d939d Compare October 13, 2025 05:08
@illwieckz
Copy link
Member Author

@slipher any new comment?

@illwieckz illwieckz force-pushed the illwieckz/builtin-null-wav branch from 01d939d to 9ebb630 Compare October 16, 2025 05:35
@slipher
Copy link
Member

slipher commented Oct 16, 2025

LGTM

@illwieckz illwieckz merged commit b2a79d7 into master Oct 16, 2025
8 checks passed
@illwieckz illwieckz deleted the illwieckz/builtin-null-wav branch October 16, 2025 11:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants