View Issue Details
| ID | Project | Category | View Status | Date Submitted | Last Update |
|---|---|---|---|---|---|
| 0006647 | The Dark Mod | Sound | public | 11.12.2025 19:55 | 13.12.2025 23:45 |
| Reporter | Amadeus | Assigned To | stgatilov | ||
| Priority | normal | Severity | normal | Reproducibility | always |
| Status | resolved | Resolution | fixed | ||
| Product Version | TDM 2.13 | ||||
| Target Version | TDM 2.14 | Fixed in Version | TDM 2.14 | ||
| Summary | 0006647: In-game main menu music doesn't loop when "leadin" value is applied to custom soundshader. | ||||
| Description | If a custom sound shader using a "leadin" sound file is used for the main menu, then the game ignores the "loop" sound file once it is supposed to play. This works perfectly only when first starting up The Dark Mod game itself. However, when in-game and after quitting the mission to return to the main menu again, the game only plays the 'leadin" sound, ignoring the loop sound entirely. This causes a very abrupt stop in the soundshader being played, and there is only silence afterward. In short, the soundshader works correctly when: - The game is first loaded and when viewing the text briefing It does not work when: - escaping from in-game to the main menu - after quitting the mission and returning to the main menu | ||||
| Additional Information | This bug seems like it might be related to FrostSalamander's bug report: 0006532 | ||||
| Tags | sound | ||||
|
Interestingly, I also see this warning spammed nonstop after the sound ends: Called idSampleDecoderLocal::DecodeOGG() on idSoundSample '%s' without nonCacheData |
|
|
There is also explanation BTW: // assert( false ); // this should never happen /* DG: turned this assertion into a warning, because this can happen, at least with * the Classic Doom3 mod (when starting a new game). There idSoundCache::EndLevelLoad() * purges (with idSoundSample::PurgeSoundSample()) sound/music/cdoomtheme.ogg * (the music running in the main menu), which free()s nonCacheData. * But afterwards (still during loading) idSoundSystemLocal::currentSoundWorld * is set back to menuSoundWorld, which still tries to play that sample, * which brings us here. Shortly afterwards the sound world is set to * the game soundworld (sw) and that sample is not referenced anymore * (until opening the menu again, when that sample is apparently properly reloaded) * see also https://github.com/dhewm/dhewm3/issues/461 */ |
|
|
I think this is a consequence of the typical Doom 3 level load logic. During level load, we preload all assets (sounds / images / etc.) which are referenced in map and decl files. We also mark them as "levelLoadReferenced = true". When level load ends, we go through all loaded assets, and purge the ones which are not "levelLoadReferenced". Because they are supposed to be leftovers from the previous map/mission. So I guess the problem here is that main menu sound is not used/referenced anywhere in the map/decl, hence it is unloaded too... |
|
|
The question however is: why leadin sound plays? It is also not referenced in the mission (in fact, both leadin and looping sounds are referenced only by the same sound shader). The answer is that it gets reloaded here: idSoundWorldLocal::PlayShaderDirectly idSoundEmitterLocal::StartSound // if the sample is onDemand (voice mails, etc), load it now if ( chan->leadinSample->purged ) { int start = Sys_Milliseconds(); chan->leadinSample->Load(); int end = Sys_Milliseconds(); session->TimeHitch( end - start ); // recalculate start44kHz, because loading may have taken a fair amount of time if ( !soundWorld->fpa[0] ) { start44kHz = soundSystemLocal.GetCurrent44kHzTime() + MIXBUFFER_SAMPLES; } } |
|
|
As far as I understand, this bug should apply to all sounds which: 1) are not referenced in the map/level AND 2) are played dynamically via "music" or "play" or "localSound" in GUI, or "startMusic" script event, or "testSound" console command Recall that sound loading consists of two parts: 1) loading data from the file/disk (into nonCacheData) 2) decompressing OGG format It seems that p.1 is done during level load and when PlayShaderDirectly is called (by only for leadin). On the other hand, p.2 is done on async/sound thread, which is called "realtime decoding". The problem right now is that looping sounds are not loaded from disk (p.1). I can either add their loading inside PlayShaderDirectly, increasing potential latency for looping sounds when they are first played. Or I can try to load the looping files on async thread in idSoundChannel::GatherChannelSamples... which I don't like for a variety of reasons. |
|
|
Fixed this in svn rev 11032. I decided to simple include the sound sample of loop body in the loading logic inside PlayShaderDirectly, so that it gets loaded along with leadin/first sample. Works fine for me. Note: as far as I see in the code, looping sounds are expected to have only one loop body sound. The loading logic only loads the first sound sample from the list of alternatives. |
|
| Date Modified | Username | Field | Change |
|---|---|---|---|
| 11.12.2025 19:55 | Amadeus | New Issue | |
| 11.12.2025 19:55 | Amadeus | Tag Attached: sound | |
| 11.12.2025 19:55 | Amadeus | Relationship added | related to 0006532 |
| 13.12.2025 18:41 | stgatilov | Note Added: 0017089 | |
| 13.12.2025 18:44 | stgatilov | Note Added: 0017090 | |
| 13.12.2025 18:52 | stgatilov | Note Added: 0017091 | |
| 13.12.2025 19:33 | stgatilov | Note Added: 0017092 | |
| 13.12.2025 19:43 | stgatilov | Note Added: 0017093 | |
| 13.12.2025 23:44 | stgatilov | Note Added: 0017094 | |
| 13.12.2025 23:45 | stgatilov | Assigned To | => stgatilov |
| 13.12.2025 23:45 | stgatilov | Status | new => resolved |
| 13.12.2025 23:45 | stgatilov | Resolution | open => fixed |
| 13.12.2025 23:45 | stgatilov | Fixed in Version | => TDM 2.14 |
| 13.12.2025 23:45 | stgatilov | Relationship replaced | has duplicate 0006532 |