YM2612 output buffer

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

Moderator: BigEvilCorporation

Post Reply
Shaho
Interested
Posts: 10
Joined: Mon Nov 26, 2012 2:07 pm

YM2612 output buffer

Post by Shaho » Mon Nov 26, 2012 2:52 pm

Hey guys! First post here, but I've been reading this forum for a few months. This site has been a fantastic resource, and I thought I'd pop in with a few questions :)

I'm implementing an FPGA version of the Genesis for a class project (building off of Gregory Estrade's project http://code.google.com/p/fpgagen/), and I've been working on adding the YM2612 core to the system. I've got the operator and channel calculations working thanks in large part to Nemesis's posts in the big YM2612 thread and the MAME source code. Where I'm getting stuck now is sending the channel output to the audio codec on the FPGA board. I read that the base output frequency of the YM2612 is roughly 53 kHz. My initial impression was that this was a sample of the channel output every 24 cycles, and I tried to send this directly to my audio codec which is sampling at 48 kHz. This of course does not produce enough samples, and I realized that I needed to resample the output from the FM clock rate (1.27 MHz) to 48 kHz. I confirmed this in Audacity and by slowing down the YM2612 clock by 24x (so that the channel is updated at 53 kHz) I was able to get the grand piano test note to play.

I now need to speed the YM2612 back up to its original rate and get the data to the slower audio codec. I think that a sufficiently large FIFO buffer could work, but I have a few questions about how this is implemented. In the MAME code, they have an output buffer of size 2160, which is "large enough to hold a whole frame at original chips rate." What exactly does this mean? Also, the MAME core has the luxury of starting and stopping the YM2612 for a specified number of samples, while the FPGA version is running constantly (technically, I could mimic this behavior but that would seem to be counter-intuitive). How do I keep the buffer from overflowing, other than stopping writes on Key Off? What about long held-out notes?

I'm somewhat new to audio, so I could be making some false assumptions, which I would be very grateful for anyone to correct. I'm curious about how the Sega Genesis itself handles this, and what the 53 kHz output frequency is supposed to mean (does the Genesis do its own internal resampling?). Thanks for any help you can provide! I'll be sure to release the source code for the project once everything's finished and cleaned up, if anyone's interested :D

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

Post by Arbee » Mon Nov 26, 2012 4:29 pm

I can explain the MAME part of this: MAME flushes out all the audio buffers once per video frame (59.97 Hz for NTSC). This means that the intermediate buffers need to be large enough to hold all the samples a chip can generate in 1 frame (1/59.97th of a second for NTSC) plus maybe a little slop in case the timing isn't perfect for whatever reason.

Assuming an exactly 53 kHz clock, that means the buffer should be 53000/59.97 samples, or 884 stereo 16-bit samples (3536 bytes).

In real hardware, it doesn't matter: the 2612 feeds the serial output stream at ~53 kHz to the DAC. Simple hardware DACs (e.g. a resistor ladder) do not have the concept of a sample rate; they merely output the correct analog voltage corresponding to the last digital sample they got, and as long as you feed it new samples at any consistent rate it will sound fine.

Shaho
Interested
Posts: 10
Joined: Mon Nov 26, 2012 2:07 pm

Post by Shaho » Tue Nov 27, 2012 2:01 am

Thanks Arbee!

The question then is what is this serial output stream supposed to consist of? If it's the channel output sampled at 53 kHz, the stream is too fast and I only hear a short "ding" from the speakers. If it is supposed to be the channel output (which updates at 1.27 MHz) extended into a 53 kHz serial stream, does that mean the YM2612 has an internal buffer? What I've done for now is to use a large FIFO buffer to store the sampled outputs written at the 53 kHz rate, then use a counter with my DAC controller (AC97 codec) to sample the same entry 24 times before moving on to the next one. This works ok, but I feel like it's a rather hack-ish solution. If anyone else has any insight into how the hardware is doing this (or if I'm doing something wrong), I would greatly appreciate it.

foobat
Very interested
Posts: 92
Joined: Fri Sep 14, 2012 1:06 pm

Post by foobat » Tue Nov 27, 2012 3:17 am

The YM2612 has an integrated DAC so it's hard to tell exactly what's going on in-between the signal generator and the DAC.

The YM2612 does operate at a fraction of its input clock (it's scaled down internally somewhere from 7.67... mhz). The input clock of the DAC is the internal clock of the ym2612 (NOT 7.67mhz) if other Yamaha FM chips (like the YM2151OPM + YM3012DAC) are any indication.

From here down is pure speculation and I barely know what I'm talking about if I know anything at all:

If the DAC scales that down yet again and the ym2612 does block until it successfully feeds that data into the DAC's internal shift register (which seems reasonable) that would explain the behaviour you see here. It would also explain some stuff that I read elsewhere about someone's PCM experiment with the YM2612 mostly working but "dropping" PCM writes if he exceeded the YM2612's maximum sample rate.

Mamizou
Interested
Posts: 25
Joined: Thu Apr 19, 2012 4:50 pm
Contact:

Post by Mamizou » Tue Nov 27, 2012 6:04 pm

The OPN2 actually outputs at 55.5kHz, same as all the other OPN chips. You can see most of the output stage here. The dropping writes is mainly due to limitations on how fast you can actually do things with an OPN2 and the system it's in (see here).

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

Post by TmEE co.(TM) » Wed Nov 28, 2012 12:03 am

55.5KHz is only with 8MHz clock.
Most YM docs assume 4 or 8MHz clock
In case of OPN2 it is MasterClk / 144

In PAL machines :
(53203424 / 7) / 144 ~ 52781
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

Shaho
Interested
Posts: 10
Joined: Mon Nov 26, 2012 2:07 pm

Post by Shaho » Wed Nov 28, 2012 11:04 pm

Thanks everyone for your help. It turns out that the FIFO buffer worked better for a single note than multiple ones. The buffer would get filled by the first note, causing the following ones to drop writes. I couldn't really see a way to get around this other than periodically stopping the chip (same as emulator). Clearing the buffer and stopping writes on "quiet" output is only moderately effective, and we can't guarantee gaps in output, particularly when bg music is playing. I ended up slowing down the internal clock of the synthesizer by 24 so that each channel is performing its calculations at ~53 kHz. When I output this directly to the audio codec, it sounds great. A YouTube video of this test can be seen here: http://www.youtube.com/watch?v=XuFO58_po_4. I'm running a simple program from http://www.hacking-cult.org/?r/18/88.

I'm still puzzled about the disconnect between the documented internal clock speed of 1.27 MHz and the output frequency of 53 kHz. Any more information on this so I can get the system to more accurately mimic the original chip would be great!

foobat
Very interested
Posts: 92
Joined: Fri Sep 14, 2012 1:06 pm

Post by foobat » Thu Nov 29, 2012 3:04 am

From http://code.google.com/p/bizhawk/source ... .cs?r=2235
The master clock on the genesis is 53,693,175 MCLK / sec (NTSC)
53,203,424 MCLK / sec (PAL)
7,670,454 68K cycles / sec (7 MCLK divisor)
3,579,545 Z80 cycles / sec (15 MCLK divisor)

YM2612 is fed by EXT CLOCK: 7,670,454 ECLK / sec (NTSC)
(Same clock on 68000) 7,600,489 ECLK / sec (PAL)

YM2612 has /6 divisor on the EXT CLOCK.
YM2612 takes 24 cycles to generate a sample. 6*24 = 144. This is where the /144 divisor comes from.
YM2612 native output rate is 7670454 / 144 = 53267 hz (NTSC), 52781 hz (PAL)
so that's where your 53khz comes from

Remember that the ym2612 doesn't have an accumulator so it cannot and does not actually play more than one channel at a time. It rapidly loops through playing each channel in a way that sounds like they're all playing at the same time, like how scanlines work on an NTSC display. It's called time-division multiplexing. Are you getting hung up on that?

Sorry if I have misunderstood. I barely understand the above (or I might misunderstand it completely) so feel free to ignore me if I've said something retarded.

Shaho
Interested
Posts: 10
Joined: Mon Nov 26, 2012 2:07 pm

Post by Shaho » Thu Nov 29, 2012 4:38 am

I think that's it! Somehow I had gotten the impression that the FM chip was clocked at VCLK and updated every VCLK/6 cycles, but only spit out an output every VCLK/144 cycles. This makes a lot more sense, and fits with my current implementation. I did know about the time-division multiplexing, but haven't implemented it yet; I believe it's supposed to sound roughly the same either way.

Thanks so much!

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

Post by HardWareMan » Thu Nov 29, 2012 7:49 am

Try to overclock AC97 chip from 48kHz to 53kHz.

Shaho
Interested
Posts: 10
Joined: Mon Nov 26, 2012 2:07 pm

Post by Shaho » Thu Nov 29, 2012 2:20 pm

I wish I could, but I'm using an Analog Devices AC97 chip that's internally clocked. As far as I can tell, I can only vary the sampling rate from 7 kHz to 48 kHz by setting a register.

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

Post by HardWareMan » Thu Nov 29, 2012 6:02 pm

So use 26,5KHz sample rate (53/2).

Post Reply