AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Here you can discuss the development of patches.

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby Yesterplay80 » 2019-10-08 @ 07:02

I had to make two minor modifications (I omitted the first hunk for configure.ac, because of course I still want it to display "DOSBox ECE" in the tile bar and I deleted the changes to the VERSION file), but afterwards it applied and compiled cleanly. Looking good! :-D
My full-featured DOSBox SVN builds (without debugger) for Windows: Vanilla DOSBox and DOSBox ECE (Enhanced Community Edition)
User avatar
Yesterplay80
Member
 
Posts: 459
Joined: 2016-2-23 @ 11:02
Location: Germany

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-10-08 @ 19:18

Glad it's all back to normal. Thanks for the confirmation Yesterplay!
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-10-21 @ 05:29

More improvements are afoot over at the dosbox-staging repository, which I've been chipping away at as time and health allows.
I wanted to update you before the dust settles, so anyone can provide feedback as well.

Opus handling is now managed by pkg-config (via ./configure) and OS packages (libopusfile-dev and libspeexdsp-dev), in-lieu of the previous internal Makefile handling, which now allows VisualStudio 14 to build and link cleanly.

The built-in codecs have been bumped to their latest mid-October releases (dr_flac - v0.12.2, dr_mp3 - v0.5.1, and dr_wav - v0.11.1).
Much work was done by Dave to eliminate compiler warnings and static analysis corner-cases that arose from exhaustive build permutation testing, described below.

I put together a simple script (src, docs) that installs dependencies and compiles DOSBox with various build and link options on macOS, Windows, and Linux.
Some permutations tested include:
- Windows: clang, gcc 9; 32 and 64-bit; size-optimized, and debug (8 permutations)
- MacOS: clang, gcc 9; 32 and 64-bit; link-time-optimized, size-optimized, and debug (12 permutations)
- Linux: clang, gcc 4.8, 6, 7, 8, 9; 32 and 64-bit; link-time-optimized, size-optimized, and debug (36 permutations)

You can see the current running output for these OSes here, respectively:
- Windows builds: https://github.com/dreamer/dosbox-stagi ... =273406877
- MacOS builds: https://github.com/dreamer/dosbox-stagi ... =273406858
- Linux builds: https://github.com/dreamer/dosbox-stagi ... =273406857

I still want to add further optimizations using canned and portable profile-feedback data via GCC's AutoFDO feature.
This will let us exhaustively play-test all the major code paths (real mode, protected mode, core types, video types, audio types, .. ) and create a packaged set of feedback files that can be used to universally optimize DOSBox builds. This is how Mozilla Firefox is compiled, and you can see the benefits in the graphs here as "LTO+PGO" (LTO = link-time-optimized which the script handles, and PGO = profile feedback optimization).

The audio code has been play-tested x86_64, PowerPC, and ARM Cortex A-52 (big-endian) hardware.

This new round of improvements have been made both possible through the dosbox-staging repository created by @dreamer_.
He will be reviewing all of the above, and I'm looking forward to his second set of eyes to further improve this and catch issues.
For those with GitHub account, please feel free to contribute!

The review and feedback will be done under this merge-request: https://github.com/dreamer/dosbox-staging/pull/12
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-11-07 @ 06:34

More improvements have been made to further reduce CPU usage and 'zero-copy' several buffers.

Eliminated the following buffers:
  • Both buffers in SDL_Sound: the first buffer held decoded samples from the codec, while the second held converted types destined for output to the calling function. Note that SDL_Sound also repeatedly reallocated these buffers to match the requested read size from DOSBox's mixer; so the does away with that as well.
  • Both buffers in the Opus decoder: the first buffer held samples from SDL's sound object and the second was used to hold SpeexDSP-resampled data. With these gone, no buffers remain in the Opus chain.
  • The buffer in the MP3 decoder, which held decoded samples from SDL's sound object. With this gone, no buffers remain in the MP3 chain.
  • Also, no buffers remain in the FLAC, WAV, and Vorbis chains either.
  • The above zero-copy changes reduce the carry-capacity for each audio track by 96KB, for a maximum reduction of 9.5 MB from DOSBox's memory usage (if all 99 potential tracks are used). Heavy track users are Might and Magic IV (58 tracks), FX Figher (32 tracks), and Alone in the Dark 2 and 3 (63 and 59 tracks, respectively).
  • The above zero-copy eliminates four array-element reads and four array-element writes, multiplied by the track sampling rate-per-second. So for a 48,000 Hz track, this eliminates 1.1 million read-and-write byte operations per second.
Functional optimizations:
  • Removed SpeexDSP resampling in favour of native-rate decoding and allowing DOSBox's mixer to (optionally) scale the rate to match the user's configured [mixer] rate. If the [mixer] rate matches the track rate (ie: both are 48KHz or 44.1KHz), then no scaling is needed. The SpeexDSP resampler (although extremely efficient) consumed roughly 40 MHz of available CPU cycles, which becomes important for sub-1GHz processes such as early Raspberry Pis and cell phones.
  • Removed SDL_Sound's conversion routines, which eliminates rate scaling and type conversions in favour of letting DOSBox's mixer adjust as needed.
  • Converted all functional interfaces to operate on PCM-frame quantities instead of bytes. The difference is that PCM-frames are agnostic of the number of channels as well as the number of bytes-per-sample. Bytes, on the other hand, require you multiply the number of frames by the sample-size (16bit) and the number of channels (either 1 or 2). Therefore, this eliminates two extra multiplies across many tight-looped functions (also improving maintainability as it's more readable).
  • Hoisted the CDROM volume adjustment out of the per-sample callback loop.
    This moves the volume adjustment to the CDROM API, which is called by DOS games when they want to apply a volume adjustment to the RedBook audio. This is now a one-time function call used by games only on volume changes, and we pass that volume change to DOSBox's CDAUDIO channel instead of performing a conditional volume scaling per-sample that was previously inside the CDROM's callback loop. For every sample, this eliminates:
    • three additions,
    • one compare,
    • three multiplies, and
    • two divides
    • ... for a total of 793,800 instructions-per-second.
General changes:
  • Updated dr_mp3 to v0.5.2
  • Removed SpeexSDP and SDL's conversion source from the build and CI files
The changes are in this dosbox-staging pull request: https://github.com/dreamer/dosbox-staging/pull/36/files
This will go through a detailed review cycle with @dreamer_, after which I will post an updated patch against the SVN baseline.
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby ripsaw8080 » 2019-11-10 @ 16:03

It's important to consider features/functionality when looking for ways to reduce processing. The MSCDEX-based volume control was made separate of the DOSBox mixer for two reasons: 1) the SB mixer interface CD volume control is tied to the DOSBox mixer by default (can be disabled with sbmixer=false) and the two methods would be in conflict; 2) the user can adjust the mixer volume on top of what the game does with the MSCDEX volume, in other words a relative adjustment rather than an override.
User avatar
ripsaw8080
DOSBox Author
 
Posts: 4434
Joined: 2006-4-25 @ 23:24

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-11-10 @ 16:47

Thanks ripsaw8080.

With three volume knobs available:
- mixer master volume (volmaster)
- mixer channel volume (volmain)
- 'scale' multiplier

Between these three, the goal is to allow the user the two DOSBox's mixer volume controls (master and CDAUDIO), plus the game/app adding its own adjustment.

This combined volume adjustment is performed by the mixer for every sample, so we might as well use that instead of running a separate volume-multiplier loop across our samples up in the CD-DA code before passing the sames down to the mixer's channel.

Scale is, well, a single scalar value, so equally multiplies across both channels (so using that would be a regression.. so perhaps expanding to left and right is in order). From a maintenance point, it makes sense to move this third (application-side volume adjustment) into one place in the mixer, so each channel source isn't repeating largely the same code.

Will see if I can improve this; ideas welcome too. I'm trying to only touch the CD-DA chain to scope this overall patch.
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby ripsaw8080 » 2019-11-10 @ 17:32

A game case to consider: Chronicles of the Sword has speech in audio tracks, but with an unusual twist -- it puts separate audio on the left and right channel and adjusts the MSCDEX-based volume to zero on the channel that is not to be heard and to full on the channel that is be heard. The user should be able to change the volume level of this output with the mixer rather than it always being at full volume. The master mixer volume is not a solution for this, as it affects all audio devices. There are other cases I could mention, but they will probably be fine as long as CotS is adequately supported.
User avatar
ripsaw8080
DOSBox Author
 
Posts: 4434
Joined: 2006-4-25 @ 23:24

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-11-10 @ 17:35

Commit is here - https://github.com/dreamer/dosbox-stagi ... cb9f2dd59c

Tested this with Big Red Racing:
1. start DOSBox
3. Apply master adjustment: mixer master 200
2. Mount the BIN/CUE or ISO+compressed-audio/CUE
4. Apply CDAUDIO channel adjustment mixer CDAUDIO 200
5. Start the game
6. CD audio starts playing (significantly louder than normal)
7. Enter game options and scale the volume up or down (without losing the previous 200% master x 200% CDAUDIO volume adjustments).
8. Quit the game and try with different master and CDAUDIO mixer settings.
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby ripsaw8080 » 2019-11-10 @ 17:54

I've always thought the scaling factor was to give an absolute "weight" to the different audio devices relative to one another, but not really sure of the thinking behind it. However, if the scale factor should be left to serve its original purpose, I guess yet another factor could be added to the mixer...

In any case, I misremembered what Chronicles of the Sword does. It doesn't change the channel volumes, it "maps" one channel to both left and right outputs. That's something that the MSCDEX-based volume control can do, but the mixer can not. Notice in your changes that you are no longer using the .out[] control values. No doubt the mixer could be changed to support that, but it's less than trivial.
User avatar
ripsaw8080
DOSBox Author
 
Posts: 4434
Joined: 2006-4-25 @ 23:24

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby dreamer_ » 2019-11-10 @ 18:04

krcroft wrote: - mixer master volume (volmaster)
- mixer channel volume (volmain)
- 'scale' multiplier

Let's not forget about:
- per-application volume control present in all modern OSes (in Linux it's done either via PulseAudio or, in future, PipeWire)
- global software volume control in OS
- hardware volume control

My point here is: users don't actually change volume in DOSBox - they do it either in-game or in OS. Is there a way to dynamically change volume using some shortcut or is it limited only to `MIXER` builtin before starting the game?
Code: Select all
| ← Ceci n'est pas une pipe
User avatar
dreamer_
Newbie
 
Posts: 77
Joined: 2019-5-17 @ 20:19

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-11-11 @ 11:29

@ripsaw8080, yes - each instantiated mixer channel holds its own volume scalar, which it calculates from three volumes knobs:
  1. the user-defined master volume
  2. the user-defined channel volume ('FM', 'SB', 'CDAUDIO', ..)
  3. the channel's scalar volume, which was previous unused and left at 1.0 when instantiated by the CD-DA code. This became a perfect use for the application-defined ctrl.vol[]s without the need for carrying around new variables or adding to the math.
All three pairs of floating point scalars behave essentially the same.. just multiplied together in the UpdateVolumes() function.

Thanks for explaining the purpose of TCtrl's out[] array, and especially knowing that Chronicles of the Sword uses this control. Wow! That game is quite a gem with its extremely clever use of separate voice tracks on the left and right channels made possible with this channel-control API. It's surely near the pinnacle of DOS game CD-DA sophistication before dev shops moved to file-and-codec based audio streams.

I've made a couple more adjustments: channel mapping is now handled inline by the mixer in a generic and minimal way (without adding new logic or loops). This eliminates the need for a separate loop in the CD handling code, as well as eliminating the same volume and channel mapping loop in the Windows CDROM code. There's also no longer a need for the image player class to carry around a TCtrl object or the assocaited ctrlUsed boolean.

Commit: https://github.com/dreamer/dosbox-stagi ... 44861893f3

Minor observation that the original check: player.ctrlUsed = (ctrl.out[0]!=0 || ctrl.out[1]!=1 ... only catches changes from the default mapping, which works when the game sets a new mapping, but the check will fail if the game wants to revert back to the original mapping. Fortunately the volume checks (ctrl.vol[0]<0xfe || ctrl.vol[1]<0xfe) were very likely always sufficient to set the boolean, so this likely has never been an issue.

Here's some debug output from Chronicles of the Sword (I'm fascinated by this game.. love see it flipping channels around in the middle of discussions :-):
Code: Select all
MIXER CDAUDIO channel: application changed left and right volumes to 100% and 100%, respectively
MIXER CDAUDIO channel: application changed audio-channel mapping to left=>left and right=>right
MIXER CDAUDIO channel: application changed audio-channel mapping to left=>left and right=>left
MIXER CDAUDIO channel: application changed audio-channel mapping to left=>right and right=>right
MIXER CDAUDIO channel: application changed audio-channel mapping to left=>left and right=>left
MIXER CDAUDIO channel: application changed audio-channel mapping to left=>left and right=>right
MIXER CDAUDIO channel: application changed audio-channel mapping to left=>right and right=>right
Last edited by krcroft on 2019-11-11 @ 16:40, edited 5 times in total.
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-11-11 @ 11:43

dreamer_ wrote:My point here is: users don't actually change volume in DOSBox - they do it either in-game or in OS. Is there a way to dynamically change volume using some shortcut or is it limited only to `MIXER` builtin before starting the game?

You've nailed my usage scenario; I adjust pulse and/or speakers for my own comfort.
Only a handful of games need me to "correct" their own volume imbalances or shortcomings.. here's what grep brought up:
  • Bard's Tale I:mixer spkr 10
  • Crusader No Regret:mixer master 100 gus 200
  • Destruction Derby:mixer cdaudio 200
  • FX Fighter:mixer master 800
  • Lands of Lore The Throne of Chaos:mixer master 800
  • Micro Machines 2 Turbo Tournament:mixer gus 800
  • Might and Magic IV World (Clouds and Darkside) of Xeen:config -set "sblaster sbmixer=false"
  • Might and Magic IV World (Clouds and Darkside) of Xeen:mixer cdaudio 50 sb 50

I suppose the more sophisticated games have saved my in-game volume settings to config files and then either use the control interface (for CD-DA) or scaling their own PCM samples either before or inside their sound driver.

I also don't think there's anyway to adjust DOSBox's master or per-channel volumes on-the-fly after you've started a game/application.
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby ripsaw8080 » 2019-11-11 @ 14:24

krcroft wrote:Minor observation that the original check: player.ctrlUsed = (ctrl.out[0]!=0 || ctrl.out[1]!=1 ... only catches changes from the default mapping, which works when the game sets a new mapping, but the check will fail if the game wants to revert back to the original mapping.

The ctrlUsed Boolean is the decision on when the extra map/volume processing is needed. If the game reverts to normal mapping and full volume, or never uses channel control at all, then the extra processing isn't needed. As such, I don't see any "fail" case there.

MSCDEX-based channel control was at one time a patch pending developer acceptance: viewtopic.php?f=33&t=21306
Not touching the mixer was a goal of the patch, which is obviously not one of your goals. ;) Anyway, the history provides insight into why things are organized as they are.
User avatar
ripsaw8080
DOSBox Author
 
Posts: 4434
Joined: 2006-4-25 @ 23:24

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-11-11 @ 15:36

Very interesting thread of how you discovered and reverse-engineered the channel mapping functionality used by CotS.

This is as fascinating as the game itself; sometimes I wonder "is there a DOS developers guide somewhere?" that lays bare all of these details and magic numbers we see sprinkled about in the DOSBox code. Then I realize the majority is through efforts just like yours. Thanks for sharing that.

Regarding the ctrlused boolean; yes, I see and understand your point now. (The bool does go false, which disengages the volume & mapper loop that runs over the player's buffer prior to handing the buffer down to the mixer).
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Re: AUDIO Patch supporting FLAC, Opus, and MP3 audio tracks

Postby krcroft » 2019-11-25 @ 02:29

Revision 14 posted (OP updated) - viewtopic.php?f=41&t=62203&p=695839#p695839
User avatar
krcroft
Member
 
Posts: 428
Joined: 2017-4-29 @ 15:07
Location: Ogden's Retreat

Previous

Return to DOSBox Patches

Who is online

Users browsing this forum: No registered users and 1 guest