VOGONS


First post, by xtreger

User metadata
Rank Member
Rank
Member

I had made a thread on trying to get redbook games working in DOS via SMEMU or VSBHDA, but I feel it's important to have a separate thread for the question in the title.

Context
On modern-ish (late 2000s or 2010s) motherboards it's almost impossible to get redbook CD-based games like Carmageddon or Tomb Raider working with full audio, since many PCI sound cards won't play nice with these motherboards despite having native DOS drivers. Using either SBEMU or VSBHDA, we can get digital sounds (i.e. the in-game sound effects) working but the CD audio (i.e. music) will not play.

Interesting observation
MPXPlay in particular is able to play music CD tracks without SBEMU / VSBHDA loaded, with no connector between the CD drive's audio out and sound card's CD-in. It's like in Windows when we enable digital CD audio for a particular CD drive - and CD audio gets played directly even for SATA CD drives (which have neither audio out at the back nor a 3.5mm input in the front). MPXPlay is able to replicate this functionality natively in DOS. A couple of posts in this thread also mention this: Help with understanding how to get (digital) CD audio to play in DOS. I've tested this behavior with ES1371 and Audigy 2 ZS, and it works. But with a YMF724 card MPXPlay just says no soundcard detected.
Also, this doesn't work with other DOS-based CD players that I tried, like CDM32, ACP112, CDPLAY14.

My question is, it seems all elements to play redbook games with full audio in DOS already exist. Are there any technical challenges to achieve this? Both SBEMU and VSBHDA seem to based on MPXPlay to an extent, so what would need to be done so that while in a redbook game with SBEMU/VSBHDA activated, the relevant MPXPlay routines are invoked to play the relevant CD track when the game requests it? Sorry if this is a noob question but I'm a beginner to all this, and curious to learn more.

Reply 1 of 7, by jmarsh

User metadata
Rank Oldbie
Rank
Oldbie

The method that MPXPlay is using is greatly different from just playing redbook audio.
With the old method, you just tell the CD drive to play from sectors X to Y and forget about it. The drive handles everything, the software doesn't really have to do anything besides occasionally checking the playback position. Data reads to the disc are also interleaved automatically by the drive.
With the digital extraction method every sector has to manually be retrieved from the disc, then manually mixed with any other audio that is being generated before being sent to the audio device. It's a huge increase in CPU overhead, it all needs to be synchronized so as to not corrupt the existing audio or drop samples and we're talking about an OS here that doesn't even support multithreading.

Reply 2 of 7, by xtreger

User metadata
Rank Member
Rank
Member
jmarsh wrote on Today, 08:16:

The method that MPXPlay is using is greatly different from just playing redbook audio.
With the old method, you just tell the CD drive to play from sectors X to Y and forget about it. The drive handles everything, the software doesn't really have to do anything besides occasionally checking the playback position. Data reads to the disc are also interleaved automatically by the drive.
With the digital extraction method every sector has to manually be retrieved from the disc, then manually mixed with any other audio that is being generated before being sent to the audio device. It's a huge increase in CPU overhead, it all needs to be synchronized so as to not corrupt the existing audio or drop samples and we're talking about an OS here that doesn't even support multithreading.

Thanks for the explanation! So from what I understood, we can't just parallely invoke the relevant MPXPlay routine whenever the game sends a request for a CD track to play (since no multithreading). But it would still be doable if a program could, as you said, get every sector from the CD and manually synchronize it with the digital sound output (i.e. the output SBEMU/VSBHDA ordinarily produces) before routing to audio device, right? Would this be possible with the modern-ish CPUs that are compatible with the modern-ish motherboards? (Typically they're >= 3 GHz which is quite a lot more than MHz CPUs that DOS software can run on)

Reply 3 of 7, by wierd_w

User metadata
Rank Oldbie
Rank
Oldbie

You need a way for your sound engine and the virtual cdrom drive to communicate a playback stream with each other.

If there was gobs and gobs of RAM available, just dumping the redbook tracks into xms, then instructing vsbhda to do playback might work, but it would locically be bass ackwards:

Normally, a game just tells the drive 'start playing music at this timestamp, on this track, and the drive does it.

In this case, the game tells the 'drive' (i am assuming shsucdhd here) to play, but it cant. It has no way to output anything, it's virtual. It needs to have some way to indicate to vsbhda that this playback has been requested.

In theory, shsucdhd could look for vsbhda being loaded, and if it finds it, communicate with it using a private API.

Things it would tell vsbhda:

1) I have these redbook tracks preloaded into XMS memory, at these handles, as raw pcm.

2) I was requested to play track FOO at timestamp BAR.

(And if images get loaded or unloaded)

3) I have ejected my media, old handles are invalidated.

4) I have loaded new media, here are the handles for the preloaded tracks.

After that, it's VSBHDA's show. It accepts instructions to playback pcm wave data starting at the instructed position, from the xms memory designated by the handle, like another digital voice channel.

This would need oodles of ram to work, but 'could' work.

You'd need to fork both shsucdx project, and vsbhda, to introduce the private API to both.

Reply 4 of 7, by xtreger

User metadata
Rank Member
Rank
Member
wierd_w wrote on Today, 12:48:
You need a way for your sound engine and the virtual cdrom drive to communicate a playback stream with each other. […]
Show full quote

You need a way for your sound engine and the virtual cdrom drive to communicate a playback stream with each other.

If there was gobs and gobs of RAM available, just dumping the redbook tracks into xms, then instructing vsbhda to do playback might work, but it would locically be bass ackwards:

Normally, a game just tells the drive 'start playing music at this timestamp, on this track, and the drive does it.

In this case, the game tells the 'drive' (i am assuming shsucdhd here) to play, but it cant. It has no way to output anything, it's virtual. It needs to have some way to indicate to vsbhda that this playback has been requested.

In theory, shsucdhd could look for vsbhda being loaded, and if it finds it, communicate with it using a private API.

Things it would tell vsbhda:

1) I have these redbook tracks preloaded into XMS memory, at these handles, as raw pcm.

2) I was requested to play track FOO at timestamp BAR.

(And if images get loaded or unloaded)

3) I have ejected my media, old handles are invalidated.

4) I have loaded new media, here are the handles for the preloaded tracks.

After that, it's VSBHDA's show. It accepts instructions to playback pcm wave data starting at the instructed position, from the xms memory designated by the handle, like another digital voice channel.

This would need oodles of ram to work, but 'could' work.

You'd need to fork both shsucdx project, and vsbhda, to introduce the private API to both.

Thanks. So this is assuming a virtual drive though. And there are other issues with virtual drives not being compatible with .bin/.cue format, so let's forget about it for now and assume there's a physical CD drive present. With a real CD drive instead of shsucd, would the scenario be exactly the same using prohibitive amount of RAM?

Reply 5 of 7, by wierd_w

User metadata
Rank Oldbie
Rank
Oldbie

You still need a way to get the digital audio data to the playback engine.

You still have a drive that has no way to present it to that endpoint on its own without help.

With an old fashioned cd drive, an analog audio cable does this job.

For digital audio, a means to get the data into memory (where the player can process it), and to tell the player to process it, is required. Regardless of if the drive is virtual, or physical.

If you dont want to blow 100s of megabytes of xms to copy whole redbook tracks for this, you'll need a more robust private API.

Maybe a 'dual playback buffer'?

As the playback engine processes the smaller sample in memory, it asserts a 'progress' value to the disc driver. (Shsucdx or shsucdhd, respectively) This driver then keeps track of that status, and loads more data into the 'inactive' buffer, as needed. The playback engine switches the buffer when it reaches the end, and continues.

With several seconds of time buffered, we'd only need a few MB, instead of a few hundred MB of XMS, but again, the API becomes more complex, with more, and more frequent, interprocess activity and communication.

Reply 6 of 7, by xtreger

User metadata
Rank Member
Rank
Member
wierd_w wrote on Today, 18:03:
You still need a way to get the digital audio data to the playback engine. […]
Show full quote

You still need a way to get the digital audio data to the playback engine.

You still have a drive that has no way to present it to that endpoint on its own without help.

With an old fashioned cd drive, an analog audio cable does this job.

For digital audio, a means to get the data into memory (where the player can process it), and to tell the player to process it, is required. Regardless of if the drive is virtual, or physical.

If you dont want to blow 100s of megabytes of xms to copy whole redbook tracks for this, you'll need a more robust private API.

Maybe a 'dual playback buffer'?

As the playback engine processes the smaller sample in memory, it asserts a 'progress' value to the disc driver. (Shsucdx or shsucdhd, respectively) This driver then keeps track of that status, and loads more data into the 'inactive' buffer, as needed. The playback engine switches the buffer when it reaches the end, and continues.

With several seconds of time buffered, we'd only need a few MB, instead of a few hundred MB of XMS, but again, the API becomes more complex, with more, and more frequent, interprocess activity and communication.

I wish I had your knowledge and I could seriously try my luck at it (even if probably destined to fail, would be fun to try). Do you know of any resources or literature I can read to get an idea about all this stuff?

Reply 7 of 7, by wierd_w

User metadata
Rank Oldbie
Rank
Oldbie

I am thinking hypothetically. What you would need to do, and why.

Implementations are much harder than ideas.

Ideas are free. Implementations are not.