New Documentation: An authoritative reference on the YM2612

For anything related to sound (YM2612, PSG, Z80, PCM...)

Moderator: BigEvilCorporation

Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Thu Aug 14, 2008 7:09 am

If I refer to the YM2151 diagram (this is I know a whole different chip but the data bus width for EG and PG seem to be the same as in YM2612), it is indeed a 14-bit input into ACCumulator

Image


PS: Arbee, if you read this, I found another little "bug" in SSG-EG implementation for MAME: in function advance_eg_channel, the variable swap_flag is used for all 4 operators but is not reseted between operators. This variable is used to swap (or not) the "invert output" flag at the end of the decay phases.

the result is that if two operators use different SSG-EG settings, this will interfere between each other

also, as the flag ssgn is modified several time during SSG-EG enveloppe, it should be reinitialized with the initial SSG register value when a KEY ON occurs

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Fri Aug 15, 2008 11:35 am

Heh, so much for assumptions.

-The operator unit does output a native 14-bit value. There's no shifting or other such voodoo. The operator unit calculates a true 14-bit value internally. MAME currently calculates this as a 13-bit value, probably because the way modulation has been implemented suggests a 13-bit value, and I'd made the same assumption in the first build of my core. Turns out we're both wrong. The internal sine table should store a 14-bit value. That's the second time I've thought that YM2151 diagram was wrong about something, and the second time it's turned out to be correct.

-Clipping DOES occur when operators are combined. The accumulator maps a single 14-bit operator output to the upper end of the 16-bit dynamic range of the DAC input ( operator output<<2 ). The accumulator limits the result to the 16-bit maximum, so if you were to try and combine two operators with a TL of 0, you'll get the upper half of the wave clipping. Try and combine 4 operators and you'll get the upper 3/4 of the wave clipping. You've got to have the right equipment to measure this properly. If you record from a sound card, you'll see what appears to be a "distorted" wave, as when the wave clips, the soundcard will try and balance the input back to 0, so you'll see a logarithmic decay even though the voltage is holding steady. Use an oscilloscope and the result is clear.

-After the DAC data is converted from unsigned to signed (DAC Data - 0x80), the result is simply mapped to the upper end of the 16-bit DAC input ( DAC data<<8 ). Since the lower bits are set to 0, the maximum DAC output is slightly lower than that of an fm channel, due to 6 less bits of significant data.

That should be everything required to get the FM and DAC levels right.

TmEE co.(TM)
Very interested
Posts: 2442
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Fri Aug 15, 2008 1:03 pm

Guess I have to get rid of couple of parts from my sound card then...

Can you test the MD2 DAC output ? MD1 DAC output it filled with aliasing noise, whereas MD2 DAC output is much cleaner.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Fri Aug 15, 2008 1:38 pm

It occurred to me that the next thing someone's going to want to know is how to balance the YM2612 output against the PSG, so I did some tests on that. All 4 PSG channels at max combined is equivalent to the maximum output of a single YM2612 channel at max.

Remember however that the YM2612 multiplexes the channel outputs, as shown by HardWareMan, which means the total output power at a given point in time will never exceed the maximum output of a single channel. It also means that each channel is not actually playing constantly. I'm unsure of the audible effects of multiplexing. It may create an apparent drop in volume for the YM2612, but that's not one you can measure digitally.

A minor correction to what I wrote above as well. The output circuitry for the Mega Drive is responsible for the "distorted" waveform when the YM2612 clips, it wasn't my soundcard. If you sample direct from the chip (like I did with my oscilloscope) you get the proper waveform. When I repeat the same process sampling the final output, I get the same waveform on my oscilloscope as I recorded on my PC. The output circuitry has the same effect on the PSG output signal, which being a square wave generator always flatlines, so that's the primary cause of the distorted PSG waveform outlined by Maxim in SN76489.txt. The actual decay when sampling direct from the chip is barely measurable, even at the minimum frequency.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Fri Aug 15, 2008 1:59 pm

Can you test the MD2 DAC output ? MD1 DAC output it filled with aliasing noise, whereas MD2 DAC output is much cleaner.
There's a bit of noise on all the output signals, but I've taken that into account. It wouldn't affect the results of these tests. It might make the DAC sound worse, but I've got enough data to be confident in how the output is generated, before it's affected by analog interference. I probably will do some tests on a MD2 at some point in the future anyway, but right now I haven't got any "modded" MD2's to perform easy tests on.

TmEE co.(TM)
Very interested
Posts: 2442
Joined: Tue Dec 05, 2006 1:37 pm
Location: Estonia, Rapla City
Contact:

Post by TmEE co.(TM) » Fri Aug 15, 2008 6:13 pm

My MD2 is having its audio part completely replaced with something much much better... only noise there is, is the VDP activity noise in the PSG line.
Mida sa loed ? Nagunii aru ei saa ;)
http://www.tmeeco.eu
Files of all broken links and images of mine are found here : http://www.tmeeco.eu/FileDen

HardWareMan
Very interested
Posts: 746
Joined: Sat Dec 15, 2007 7:49 am
Location: Kazakhstan, Pavlodar

Post by HardWareMan » Sat Aug 16, 2008 9:14 am

Nemesis wrote:-After the DAC data is converted from unsigned to signed (DAC Data - 0x80), the result is simply mapped to the upper end of the 16-bit DAC input ( DAC data<<8 ). Since the lower bits are set to 0, the maximum DAC output is slightly lower than that of an fm channel, due to 6 less bits of significant data.
I think, you mean "8 bits" not "6 bits", becouse DAC is 16 bit and DAC register is 8 bits.
And to convert usigned 8 bit value to signed 8 bit value you need just do "XOR" by 0x80 (or just invert most significant bit).

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sat Aug 16, 2008 10:24 am

I think, you mean "8 bits" not "6 bits", becouse DAC is 16 bit and DAC register is 8 bits.
No, I meant 6 bits. The output from the operator unit is a 14-bit value. This is shifted up by 2 to create the 16-bit output to the DAC. The DAC register gives an 8-bit value. This is shifted up by 8 to create the 16-bit output to the DAC. Comparing the maximum and minimum possible values from the DAC register (8-bit) with the output from the operator unit (14-bit), there's 6 less bits the DAC register is able to populate with significant data.

OTOH, it might be 8-bits afterall, depending on whether the operators are summed before they're converted to 16-bit values, or after. If the operator output is converted to a 16-bit value before each operator is summed, it would be possible for the lower 2 bits to be populated with meaningful data. If the operators were summed as 14-bit values, then the final value was shifted up by 2 when it's output to the DAC, the lower two bits would always be unset. I have yet to confirm which one is correct.
And to convert usigned 8 bit value to signed 8 bit value you need just do "XOR" by 0x80 (or just invert most significant bit).
You could, but I prefer to do the subtraction, as the processor will then perform sign extension and give a valid 2's compliment value even if you're using a datatype larger than 8-bit.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sat Aug 16, 2008 4:52 pm

Wow. Jarek, if you're reading this, you're a genius. I thought the MAME implementation of the operator unit was inaccurate. I just spent the last 6 hours sampling data from the YM2612, and the end result is, I've just confirmed that your implementations of sin_tab and tl_tab really are 100% binary accurate. You've even figured out algorithms to generate the exact datasets :shock:.

I'm not sure that MAME is going to benefit much from the next batch of info I publish. Everything I've tested so far seems to be emulated perfectly, with the possible exception of the accumulator which I simply haven't checked in MAME. Still, it should be a useful resource for anyone else writing their own core, or who simply wants to better understand the MAME implementation.

Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sat Aug 16, 2008 5:09 pm

I'm sure he is, just look how his enveloppe generator implementation quite exactly matches your results

However, the work you are doing here and the way you document it is still priceless for me, at least to finally understand the MAME implementation

Arbee
Interested
Posts: 16
Joined: Sat Aug 02, 2008 5:35 pm
Location: USA
Contact:

Post by Arbee » Tue Aug 19, 2008 4:55 pm

Honestly, one of the big problems with MAME's FM has been that it's not well documented. If you'd like to add comments explaining how it works we'd be more than happy to include them.

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Wed Aug 20, 2008 1:46 am

I might take you up on that. Once I've finished running tests and I've got everything documented, I'll consider going through the MAME core and commenting the implementation. The operator unit in particular needs a lot more info given. I'll get in touch with you when I'm thinking about starting.

Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sat Aug 23, 2008 3:00 pm

Nemesis, I have a question for you:

the MAME core implement some kind of delayed sample operator (MEM) for some algorithms, did you verify this happen on a real YM2612 ?

Nemesis
Very interested
Posts: 791
Joined: Wed Nov 07, 2007 1:09 am
Location: Sydney, Australia

Post by Nemesis » Sat Aug 23, 2008 6:31 pm

It's clear that the operator unit does have an internal temporary storage location which can hold the output of at least one operator. There's actually no way to verify what the operator unit stores from any tests on the system, but you can determine a lot from just looking at the way the algorithms are arranged.

If you look at all of the algorithms, it seems clear that the YM2612 always calculates operators 1-4 sequentially for each algorithm. You'll notice if you look at each arrangement that in every case, operators are only modulated by operators with a lower number. This is the reason operator 4 never modulates another operator for example. Also, in cases where an operator is only being modulated by a single operator, that operator is always the operator immediately before it in the sequence.

We know carriers have their output sent directly to the accumulator and that's the end of it. Operators which directly modulate another operator can simply have their output fed directly into the input for the next operator and they never need to be stored. Some of the algorithms in the YM2612 however involve the output from multiple operators being summed together to modulate another. The only way the operator unit can achieve this is if it has a temporary storage location where it can save the output from one of these operators into, so that it is then free to evaluate the other operator, then sum the result of the two. There's also algorithm 5, which involves the output of operator 1 being fed into all 3 other operators, which again requires the result to be stored.

Looking at the algorithms, none of the patterns would ever require more than one result to be stored when the operators are evalulated sequentially. It makes sense that there's a single "mem" slot inside the operator unit which can buffer a single result, which is used as this storage location. The only other option would be that the output of all 4 operators are saved along the way, but seeing as Yamaha designed their algorithms to allow them to get away with only one, and storing the output makes the device more complex, it's almost a given that there is simply a single cached storage location where an operator output can be stored.

Eke
Very interested
Posts: 885
Joined: Wed Feb 28, 2007 2:57 pm
Contact:

Post by Eke » Sat Aug 23, 2008 8:41 pm

Operators which directly modulate another operator can simply have their output fed directly into the input for the next operator and they never need to be stored.
So, with this in mind, would you think Algorithm #0 (all operators chained) would require MEM ?

I'm asking this because I got some musics in Mega Turrican (track 3,6,9...) playing wrong with the MAME core: for each of this track, the channel that is wrong always use algorithm #0 with the same configuration (feedback =7,... see attached picture here: http://gxdev.files.wordpress.com/2008/0 ... rrican.jpg)

If I switch to the GENS core, musics are fine
If I modify the MAME core to make C1 outputs directly to M2 without using MEM, it seems to fix also the problem

You can easily listen the difference using the current in_vgm for winamp which can switch between the two cores http://www.smspower.org/maxim/forumstuf ... in_vgm.zip
. vgm files are here: http://project2612.org/details.php?id=140
. incriminated tracks are "Stage 1-2" & "Stage 1 Boss" tracks


GENS does not use delayed sample operator btw

Post Reply