VOGONS

Common searches


Invert Left/Right Audio Channels Stereo Sound?

Topic actions

Reply 20 of 83, by Flint Eastwood

User metadata
Rank Newbie
Rank
Newbie

@ripsaw8080: This sounds very good.

A parameter for the MIXER command inside DOSBox such as "MIXER /STEREOREVERSE" would also be a nice touch

A good idea. So You can make batch files with this command for the specific games.

i7 870 + Zotac 470GTX AMP! + 12GB RAM + Win7 64Bit

Reply 21 of 83, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I've finished my first try at making a patch for exchanging the left and right digital stereo channels in DOSBox 0.72. I implemented all the features I mentioned in my previous post, and I think it's a complete little package. Perhaps a moderator will feel this is worth splitting off into the patches section of the forum.

Features:

- Added a swapstereo= value to the [mixer] section in the conf file which defaults to false. If the value isn't in the conf file at all, it's considered as false.

- Added a switch to the MIXER command in DOSBox to toggle the swapping of the stereo channels. MIXER /SWAPSTEREO will invert the current setting. Also added a display of the current setting after the list of volume controls that MIXER displays.

Notes:

- The modifications are mostly contained in mixer.cpp, but dosbox.cpp also has a small change to support writing out the new conf setting when doing a "CONFIG -writeconf" in DOSBox.

- I chose the semantic of "swapped", but it could just as easily be "inverted", "reversed", "flipped", etc.

- Offset values are used to modify the AddSamples method in mixer.cpp, but I am unsure if this has less overhead or is more efficient than creating even more nested conditions in the code than there already are... perhaps someone knows without using a profiler?

The diff file for use in MSys/MinGW is attached. To apply the patch, copy the diff into your dosbox source folder, then in MSys: change directory to the dosbox source folder, run a "patch -p0<swapstereo.diff", and then "make" the application as usual.

I hope you will enjoy the patch and find it useful; and please let me know any thoughts or criticisms you have about it.

Attachments

  • Filename
    swapstereo.zip
    File size
    1.36 KiB
    Downloads
    203 downloads
    File license
    Fair use/fair dealing exception

Reply 22 of 83, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

After working on my mixer patch, I realized that anything causing the samples to be shifted in the DMA buffer could cause the stereo channels to get crossed. Looking at the code in sblaster.cpp, something caught my eye in GenerateDMASound:

case DSP_DMA_8:
if (sb.dma.stereo) {
read=sb.dma.chan->Read(size,&sb.dma.buf.b8[sb.dma.remain_size]);
Bitu total=read+sb.dma.remain_size;
if (!sb.dma.sign) sb.chan->AddSamples_s8(total>>1,sb.dma.buf.b8);
else sb.chan->AddSamples_s8s(total>>1,(Bit8s*)sb.dma.buf.b8);
if (total&1) {
sb.dma.remain_size=1;
sb.dma.buf.b8[0]=sb.dma.buf.b8[total-1];
} else sb.dma.remain_size=0;

The code snippet is for 8-bit stereo, but the 16-bit stereo code is structured basically the same. The remain_size property interested me, because it is acting as an offset into the DMA buffer. I'm not sure, but I think it has to do with an odd number of samples being transfered in a given DMA cycle, and stereo samples are processed in (even) pairs. Anyway, the code towards the bottom toggles the property between 0 and 1, so I thought I might be on to something. I decided to do some logging of SB stuff, first stopping the "Raising IRQ" messages that flooded the log, and then adding some more info to existing messages. The following log is from the CD version of System Shock configured to use the AIL3 (Miles) SB16 driver:

DSP:Reset
DMA unmasked,starting output, auto 0 block 1 mode 5 remain_size 0
DMA Transfer:16-bits PCM Stereo Single-Cycle freq 22050 rate 44100 size 1
Single cycle transfer ended
DMA unmasked,starting output, auto 1 block 4095 mode 4 remain_size 1
DMA Transfer:8-bits PCM Stereo Auto-Init freq 22050 rate 44100 size 2048
DMA unmasked,starting output, auto 1 block 4095 mode 4 remain_size 1
DMA unmasked,starting output, auto 1 block 4095 mode 4 remain_size 1
DMA unmasked,starting output, auto 1 block 4095 mode 4 remain_size 1
DMA unmasked,starting output, auto 1 block 4095 mode 4 remain_size 1

The unexpected thing is the first 16-bit stereo (DMA mode 5) transfer being done for a single sample, which happens when the game starts up, before any sound is heard. This initial transfer is causing the remain_size property to get "stuck" at 1 for all subsequent DMA unmask events. The remainder isn't eventually resolved during the transfer cycles because the number of samples is even thereafter. It might be just this single-cycle stereo transfer of one sample that causes the shifting; but looking at the code, it seems like any stereo transfer with an odd number of total samples (a bad idea to begin with) could result in the same thing.

I made a log for Dungeon Keeper, which also uses Miles drivers and has swapped stereo channels in DOSBox, using both SBPro and SB16 configurations, and saw the same initial single-sample stereo transfer that throws off remain_size. Another Miles driver game, Settlers 2, follows the same pattern; but its stereo separation isn't easy to hear. Looking at the Miles driver files SBPRO.DIG and SB16.DIG in these games shows that they went through a number of revisions; but the single-sample stereo transfer at initialization remained a consistent "feature".

I tried resetting sb.dma.remain_size to 0 on each DMA unmask event, and it seems effective in preventing the swapping; but there are probably a number of ways to harden the code against what the Miles drivers (and possibly others) are doing, and my approach might not be ideal in all circumstances.

Reply 23 of 83, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

interresting. switching between modes might reset to zero or so. Would have to check the spec sheet

Water flows down the stream
How to ask questions the smart way!

Reply 24 of 83, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

FYI, two DSP commands are issued between that first single-sample transfer, and the normal sound-producing tranfers: 0x41 (set output sample rate) and 0xC6, which generates a call to DSP_PrepareDMA_New. The "PrepareDMA" functions in DOSBox end up calling DSP_DoDMATransfer, which seems like it might be a good place to reset.

Reply 25 of 83, by Qbix

User metadata
Rank DOSBox Author
Rank
DOSBox Author

could you see what the games do you use the sbpro1 setting in dosbox ?
as the size=1 and such was added because that is how the sbpro1 handled it. (might be sbpro2)

Water flows down the stream
How to ask questions the smart way!

Reply 26 of 83, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Hmm, although System Shock does have a setup option for "Old SoundBlaster Pro" and "SoundBlaster Pro", the game's config file doesn't change with either setting, and there is only one SBPRO.DIG driver file... so perhaps the distinction is only important for auto-detection?

Anyway, a log with the SBPro driver:

DSP:Reset
DSP Command E1
DSP Command 40
DSP Command 14
DMA unmasked,starting output, auto 0 block 3 mode 4 remain_size 0
DMA Transfer:8-bits PCM Mono Single-Cycle freq 22222 rate 22222 size 4
Single cycle transfer ended
DSP Command D1
DSP Command 40
DSP Command 48
DSP Command 1C
DMA unmasked,starting output, auto 1 block 4095 mode 4 remain_size 0
DMA Transfer:8-bits PCM Stereo Auto-Init freq 11111 rate 44444 size 2048
DSP Command D0
DSP Command D4
DMA unmasked,starting output, auto 1 block 4095 mode 4 remain_size 0
DSP Command D0

It seems remain_size doesn't have an effect here, the initialization transfer is mono for 4 samples with the SBPro driver; but the channels are still swapped. 😒 Can't see another explanation... at least I still have my mixer patch to fall back on.

BTW, with the SB16 in Dungeon Keeper, I noticed there is a "pop" in the left channel when you hear the first sound in the game; but it's gone when you set remain_size to 0, effectively dropping that hanging initialization sample in the buffer and preventing it from being output. I could not say how real SB16 hardware handled it, but it works out more aesthetically to reset the remainder when initializing a new DMA transfer. 😉

Reply 27 of 83, by Flint Eastwood

User metadata
Rank Newbie
Rank
Newbie

I noticed there is a "pop" in the left channel when you hear the first sound in the game

Hmm, in Archimedean Dynasty(Schleichfahrt) I noticed this "pop" too (When the BlueByte-Logo comes up and the atmospheric water sound starts).

i7 870 + Zotac 470GTX AMP! + 12GB RAM + Win7 64Bit

Reply 28 of 83, by rolloLG

User metadata
Rank Member
Rank
Member

Please can you post patched exe(s)? I'm not a developer and don't have the MiniGW env etc. etc. but I really hate those games with inverted audio channels! 🙁

BTW, also Albion/DosBox has inverted stereo problems.

Reply 29 of 83, by ripsaw8080

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Albion uses the Miles sound drivers, so its situation is no different.

The attached file is a Win32 MinGW build of DOSBox 0.72 with the swapstereo patch. It also resets remain_size to zero when initializing a new DMA transfer, as discussed above, so the stereo channels with the Miles SB16 driver should be correct without swapping. The build includes most of the "optional" components: DDraw output, SDL_net, libpng/zlib. I gave up trying to get SDL_sound compiled under MinGW, but I don't notice the absence of whatever capability it provides. The executable has no debug or symbol info, making it more compact, and doesn't need any support files beyond those required by the official build.

There's also a bonus patch for the "zero split-line glitch" that affects the Event Horizon games, as discussed in Graphic glitch in Event Horizon games The approach used is not the post-decrement covered in the thread; instead it checks for the split before rendering lines, which is functionally similar to what is in the current CVS.

Have fun with it 😀

Attachments

Reply 34 of 83, by robertmo

User metadata
Rank l33t++
Rank
l33t++

I will just add that there is no stereo in wolf3d with sbtype=sbpro1,sbpro2 since dosbox 0.66beta2 (only sb16 with mixer=true has stereo sfx in wolf3D)

It was ok in dosbox 0.65. It is also ok on my real sbpro1 and real sbpro2 cards.

Reply 35 of 83, by Flint Eastwood

User metadata
Rank Newbie
Rank
Newbie

This is my first try to compile the DosBox Source.
I finally managed it to setup mingw + minsys on my pc.
I used this german Dosbox Build tutorial to compile dosbox.
Then I modified this SwapStereo-Patch for the v0.73 source.

I add my compiled version. It has SDLnet, SDLsound, LibPng and additionally Glide Support and SwapStereo-Patch(I hope that I did everything right 😉 ).

Attachments

i7 870 + Zotac 470GTX AMP! + 12GB RAM + Win7 64Bit

Reply 36 of 83, by HunterZ

User metadata
Rank l33t++
Rank
l33t++

Throwing another game on the pile: The VGA remake of Space Quest 1 plays Sarien footstep sounds from the opposite speaker in relation to the side of the screen on which they appear. This is with sbtype=sb16 and Sound Blaster selected (I think) as the sound card in the game's install utility.

Reply 37 of 83, by HunterZ

User metadata
Rank l33t++
Rank
l33t++

I can confirm that stereo is backwards in Albion under DOSBox 0.73 using either SB16 or SBPro 🙁

Would possibly be useful to have a conf setting until a proper fix can be made.

I wonder if patching the Miles drivers to swap the stereo at that level would be difficult?

Reply 38 of 83, by Flint Eastwood

User metadata
Rank Newbie
Rank
Newbie

Hello HunterZ: Just look 3 posts back. I compiled the Dosbox 0.73 with the SwapStereo-Patch. It should load all miles-based-games with Left/Right correctly. For Archimedean Dynasty and GTA it works fine. 😀
Additionally you can swap channels by command promt and in the *.conf too.

i7 870 + Zotac 470GTX AMP! + 12GB RAM + Win7 64Bit