Skip to content

Stereo Dual YM3812

Technical discussion about the VGM format, and all the software you need to handle VGM files.

Moderator: Staff

Stereo Dual YM3812

Post by NewRisingSun2 »

I am working to add direct .VGM logging support to DOSBox, mostly so I can log Tandy 1000/PCjr music (SN76489). (I would also support the Game Blaster, but the .VGM specification 1.71 only seems to support a single SAA1099 chip, while the Game Blaster has two of them.)

I have been successful at correctly logging SN76489, 1xYM3812 and 1xYMF262 writes. I can also successfully log 2xYM3812 writes (when emulating a Sound Blaster Pro 1, configuration option sbtype=sbpro1), but all VGM players I tried play both chips in the center. On the Sound Blaster Pro 1, the first YM3812 is heard exclusively in the left channel, while the second YM3812 is heard exclusively in the right channel; to play in the center, a DOS program would write to both chips simultaneously.

Is there something I have to set up in the .VGM header, or via .VGM command bytes, to get stereo sound this way, or is this not supported in the .VGM format? I could not find any details on this in the .VGM specification, version 1.71.
  • ctr Offline
  • Posts: 492
  • Joined: 2013-07-17, 23:32:39

Post by ctr »

Currently there is no way to set hard panning for a specific sound chip (apart from the SN76489 PSG). But for the OPL2 you could actually pretend you're logging an OPL3 vgm and just set the channel pan bits. I'd consider it a hack, but that would give you stereo sound...
  • User avatar
  • ValleyBell Offline
  • Posts: 4767
  • Joined: 2011-12-01, 20:20:07
  • Location: Germany

Post by ValleyBell »

If you set bit 31 in the YM3812 clock (clock|0x80000000), you get a hard-panned dual OPL2 - see here. (line 251 is mono dual OPL2)
The first chip goes to the left, the second chip to the right speaker. (This detail is indeed missing in the current VGM spec.)

2xSAA1099 is supported in the same (hackish) way as most non-YM chips are:
  1. set bit 30 in the clock (i.e. clock|0x40000000)
  2. for the 2nd SAA chip, set bit 7 in the "register" byte (first parameter)
The dual chip list is a bit lacking because I apparently forget to add the v1.71 chips to it. At this point it would probably be easier to just list the chips that don't support two instances.

Post by NewRisingSun2 »

Thank-you for that information. I have now added working 2xOPL2 and Game Blaster .VGM logging support to DOSBox. A few cleanups are left, but then I think I will be able to post a source code patch and a compiled build using it, if there is an interest in that.

Another question: A small number of PC games (mostly by Distinctive Software) use the OPL2 together with the Sound Blaster's PCM channel, and the SN76489 with the Tandy 1000 SL/TL/RL's PCM channel, to play PCM drums. What is the best, or most efficient, way of logging uncompressed 8 bit PCM samples that ...
  • the game writes directly into a register from a timer interrupt service routine?
  • the game plays using a Direct Memory Access channel?
I that suppose for the DMA part, I should look at the VGM format's DAC stream control. I'm not too familiar with most of the chips in the VGM specification, but surely one of them can accommodate these simple uncompressed 8 bit samples, without having to add another chip type for them. Any suggestion would be appreciated.
  • ctr Offline
  • Posts: 492
  • Joined: 2013-07-17, 23:32:39

Post by ctr »

For DMA driven DACs, the DAC stream is indeed the best option. I used the YM2612 DAC for this purpose when doing the Midway/Williams arcade packs, since the format was the same (unsigned 8-bit PCM). The hardest part is probably optimizing the DAC streams. As long as there is no resampling or mixing, it should not be too difficult. dacopt would do most of that job for you (It creates the DAC streams from individual YM2612 or PWM commands as well as optimizes them)

Post by NewRisingSun2 »

Thank-you. (Ab)using the YM2612's DAC, DOSBox will now log Sound Blaster and Tandy DAC PCM, both direct and DMA-driven. Yeah!

The DAC is a little quiet against the OPL2. I suppose that's something to adjust by hand in the .VGM files after capturing though, so as not to clutter up the capturing source code.

Now, if .VGM were to add support for the SID chip, used on the "Entertainer" and "Innovation SSI 2001" PC sound cards and supported by a handful of games (some of which are not merely C64 ports), then all non-MIDI music from PC games could be captured with .VGM. (And for MIDI, the Standard MIDI File capturing method is of course entirely adequate.)
Last edited by NewRisingSun2 on 2016-12-28, 16:32:21, edited 1 time in total.
  • User avatar
  • ValleyBell Offline
  • Posts: 4767
  • Joined: 2011-12-01, 20:20:07
  • Location: Germany

Post by ValleyBell »

For DMA-driven audio streams, it could be a neat idea to write 0x92 commands into the VGM that hint at the speed of the stream.
So tools like dacopt could use that accurate value instead of calculating the frequency manually.
(I'd probably use command 0x92 0xFF [4-byte frequency], as this can't be used by VGMs normally.)

Post by NewRisingSun2 »

For DMA-driven streams, I am already directly writing the Data Block into the .VGM file, and of course the sample rate as well. I did this not for optimization purposes, but simply because DOSBox fetches DMA data asynchronously, so it was the simplest approach. I did include one optimization: keep track of all samples that have been played in the capturing session, so that each time a DMA transfer is initiated, the sample to which the DMA controller's registers point to is compared against all previously played samples, and if a match is found, the Data Block is not output to the .VGM buffer again.

dacopt is therefore only needed to optimize .VGMs from games that play PCM using the direct method. But I may be able to detect within DOSBox that the sample is being written from within a Timer Interrupt Service Routine, and if so, could write the Timer frequency as the sampling rate as well, helping dacopt, as you mentioned. This of course imposes the assumption that only one sample is written during each invocation of the Timer Interrupt Service Routine, but that does not seem to be an unreasonable assumption.

So, what are the chances of SID support being added to .VGM? :) The previous discussion on the subject seems to have been inconclusive.
  • User avatar
  • MaliceX Offline
  • Posts: 226
  • Joined: 2012-09-29, 11:45:48
  • Location: Australia
  • Contact:

Post by MaliceX »

Curious question - are you implementing this with vanilla DOSBOX or the SVN-DAUM tree? There are a number of game-breaking bug fixes that were implemented in SVN builds since vanilla hasn't been updated in ages. (not to mention the GUI is much more accessible than having to memorise keyboard shortcuts all over the place)
-dj.tuBIG/MaliceX

Post by NewRisingSun2 »

I use SVN r4000 of the main branch, which runs stably and is regularly updated. Daum hasn't been updated since January 2015, and has always been crash-prone on my system.
Post Reply