Dual-YM2612 hardware synthesizer

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

Moderator: BigEvilCorporation

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

Dual-YM2612 hardware synthesizer

Post by foobat » Wed Jun 05, 2013 10:00 am

Heya peoples,

I finally got around to making some schematics for my dual-YM2612 synthesizer. There might be some bugs in the layout and my EE knowledge is limited so I may have done some dumb stuff. Rough draft ahead.

This device takes MIDI input through a standard 5-pin MIDI DIN connector, generates sound, and outputs non-amplified audio via an unbalanced stereo connector (3.5mm or 1/4" TRS). Alternatively, it can accept a filtered stream of a VGM file via USB from a host computer running the 'vgmfilter' program (source provided in the 'vgmfilter' directory with a makefile that should compile easily under Linux).

The device has a 256 kilobit EEPROM capable of storing around 150-200 custom instruments (or instruments ripped from games). The EEPROM is programmed with a custom loader by enabling the relevant section of code and using the tserial program, using an eeprom generated from compressed and truncated OPM files called 'PAK' files.

In the 'tools' directory are several potentially useful tools and documents:
  • opm2pak.py - a Python program that can take an OPM file and produce several PAK instrument files. Several PAK files should be concatenated together directly (i.e. using the 'cat' program) before being flashed to the EEPROM
    tserial.py - a Python program that flashes EEPROM files (made from several concatenated PAK files) to the device via USB serial
    bitlist.txt - a crude specification for the PAK file format containing YM2612 parameters followed by the byte number of each parameter at which the value for that parameter is stored
    pak.eeprom - a sample EEPROM created from 100+ PAK files containing instruments from various games
    opms - a directory containing the 2612.org OPM file dump and some pre-generated PAK files
The actual code that runs on the device is contained in sketchbook/ym2612/ym2612.ino, and should be easy to edit in the Arduino IDE or in your C editor of choice. It's not particularly readable or even well-written, but there it is. It is lacking several important features and only supports a few MIDI CC commands for changing parameters on-the-fly, but has most basic synthesizer functionality including 12-channel polyphony and pitch bend.

The code supports an RS232 serial LCD character display and has some (currently disabled because it eats too many microprocessor cycles) support for rotary encoder input and for LED matrix outputs using MAX72XX controllers.

I'm currently designing a printed circuit board for this device, after which I'll work on an enclosure and then will spend more time polishing the code.

Schematic (PDF format): http://7355608.net/ym2612play.pdf
Schematic (EAGLE): http://7355608.net/ym2612play.sch
Source: http://7355608.net/ym2612.tgz

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

Post by TmEE co.(TM) » Wed Jun 05, 2013 11:06 am

Wow, this is awesome !
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

sega16
Very interested
Posts: 251
Joined: Sat Jan 29, 2011 3:16 pm
Location: U.S.A.

Post by sega16 » Wed Jun 05, 2013 3:05 pm

Since you are using an AVR you can generate up F_CPU/2 with PWM I believe the teensy has a 16mhz clock so you can generate an 8mhz clock which is perfect for the ym2612. This should save abit on components.

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

Post by HardWareMan » Wed Jun 05, 2013 6:31 pm

Clock on the YM2612 is best served through a capacitor. Otherwise it starts to warm up.

Charles MacDonald
Very interested
Posts: 283
Joined: Sat Apr 21, 2007 1:14 am

Re: Dual-YM2612 hardware synthesizer

Post by Charles MacDonald » Wed Jun 05, 2013 7:01 pm

This looks great! I'm comparing your circuit against a System 32 board (has two YM3438s) and this is what I'm seeing done differently:

- Each MOL and MOR outputs go through series resistors before being tied together. Without the resistors there's a conflict when one chip drives, say, MOL to a high voltage (near +5V) and the other drives MOL low (near +0V), and eventually there'd be some damage to the chip as they fight.

- Each of the combined MOL and MOR outputs goes through an op-amp to buffer the output. This way the rest of the audio circuit is being driven by the op-amp (which can handle a large load) instead of the YM3438 (which can't). Now here they are doing some additional stuff for active filtering, but in an audio circuit I made for a YM2413 just configuring an op-amp as a voltage follower was sufficient. I think you could do that too. You can get op-amps like the LM358 that have two in one package, for the left and right channels. Here a TL062 was used.

- The output of the op-amp can drive a line-in input on an amplifier, but isn't really designed to drive a headphones directly. If you don't want to connect the circuit to an external amplifier to in turn drive headphones or speakers I think there are small power amplifiers you can get. The NCP2809 looks like one for example, though it has poor availability. Maybe there are others. The Genesis used the CXA1034 headphone amp which isn't made anymore.

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

Post by foobat » Wed Jun 05, 2013 7:29 pm

I've been having some problems with op amps as voltage followers and preamps. I think the switching speed on them is too low or something and it causes distortion. The way the ym2612 does multichannel output is with time-division multiplexing, which it seems lots of cheap op amps have problems with. It's definitely something I want to spend more time on in the future

neologix
Very interested
Posts: 122
Joined: Mon May 07, 2007 5:19 pm
Location: New York, NY, USA
Contact:

Post by neologix » Wed Jun 05, 2013 8:17 pm

I haven't taken a look at any of this yet and I don't currently have the hardware to make it happen, BUT! As a YM2612 enthusiast I'd like to make a few suggestions:
  • re MIDI CCs to support - Aly James linked me to little-scale's GENMDM supported CC list a while back and for consistency between YM2612-capable things (the GENMDM, Aly's FMDRIVE VSTi which can actually hook up to the MD via GENMDM, superjoebob's YM2612 VSTi which will likely integrate this list as well, and eventually ValleyBell's VGM2MID) I highly recommend you support them as listed.
  • re OPM presets - while I understand and respect the desire to have as complete a preset pack as possible, I think OPM is the wrong format to start from as that's primarily formatted for YM2151 usage. Aly James provides an excellent 33000 preset large pack of TFI files for free download for use with TFI-capable things, and my own VGM2PRE can dump YM2612 presets from VGMs to more YM2612-friendly formats like VGI (the YM2612-specific successor to TFI) and TmEEco's TYI format. You could still convert to PAK, but I highly recommend the source format be something more YM2612-oriented.
Idea! I'll add YM2612-to-PAK support to VGM2PRE! This is exactly the kind of thing I wrote the tool for - a VGM2TFI replacement that can be easily extended to support other output formats :)

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

Post by foobat » Wed Jun 05, 2013 9:52 pm

It might be better for me to migrate off PAK and to something else. The only difference between PAK and TFI I think, besides the parameter-to-byte order, is that PAK has a header to contain the name of the instrument. It would probably be better for me to change and to consolidate on a standard file format. When I started, Aly hadn't finished FMDRIVE yet ;)

Since I only have rudimentary midi CC, it will not be any extra effort to use the little-scale CC list. So, that's exactly what I'll do! Thanks much for the tip!

neologix
Very interested
Posts: 122
Joined: Mon May 07, 2007 5:19 pm
Location: New York, NY, USA
Contact:

Post by neologix » Wed Jun 05, 2013 10:32 pm

Much obliged :)

Let me know what preset format you end up choosing and if VGM2PRE doesn't already support it I'll add it.

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

Post by HardWareMan » Thu Jun 06, 2013 3:13 am

I remind you that according to the analysis of the die shots, analog output is not complementary. It's just a current source that requires an external load. That is, it is necessary to put resistance to the GND. Furthermore, each output must use a separate repeater, atleast on one transistor. Scheme can peek at CCAM from TmEE.

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

Post by foobat » Tue Apr 01, 2014 7:48 am

Thanks for the suggestions, everybody. I finally got around to wrapping this thing up, and have sent a board design out to be built. The first set will probably be broken since this is my first time working with anything analog or with two separate power supplies, but we'll see how it goes. :)

Everything will be totally public and if anyone's interested in having one once I get it working we can figure something out.

board design: https://oshpark.com/shared_projects/UX2W428S
updated schematic: http://7355608.net/ym2612play/ym2612playSCH.pdf

Aly James
Very interested
Posts: 74
Joined: Sun Mar 31, 2013 11:34 pm
Location: FRANCE
Contact:

Post by Aly James » Mon Apr 07, 2014 10:53 pm

foobat wrote: Everything will be totally public and if anyone's interested in having one once I get it working we can figure something out.

Count me In for one!
:)
I never found the time to make mine because I have a GenMDM unit but the code is closed source so I cannot tweak the hell of it :)
I have a lot of features in FMDrive YM2612 VST that I would like to send directly to the chip via MIDI...
I remember looking at your earlier source and it lacks SSG registers supports, did you sort it out ?

Suggestions:
:idea:
An open source Hardware YM2612 unit fully MIDI controllable with built in VGM support is definitely what I had in mind, one thing that could be a future feature is that MD Emulators that handles plugins could implement one that streams the YM2612 Data over MIDI following a given register>MIDI map or serially, as is.
Maybe not the PCM but at least FM.
I notice handling for a second YM2612... you definitely should put a socket for the YM chips (might be already the case) because we could put a YM3438 on the second slot!

I do not remember if there was a little difference on the Timers but for the rest it is the same pins, but without the ladder effect! (YM2612 DAC sign-bit negative bug..). The output impedance is also not the same IIRC.

So it could be awesome to have the 2 main flavors of YM2612 on the same board! because creatively and sound wise, both are handy!

Plz send me a PM with your mail address so I can forward my PSG code to you 8)

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

Post by foobat » Tue Apr 08, 2014 3:10 am

SSG support isn't a big deal if we can control it via FMDrive using the little-scale CC list. The actual ym2612 is just a big list of registers, so once the hardware is in it's just raw lines of code to make the callbacks to handle the CC events ;)

This hardware definitely can't keep up with PCM being streamed over USB or serial, but it might be possible to play back small samples stored in the local eeprom. That's about 4kb worth of samples to work with. That's plenty for me, but I am not the most musical guy. The thing that bogs down the microcontroller is actually reading the messages sent via USB and executing the associated instructions. It'll take some clever hacks to make it useful. Running into a problem like this with a modern 16mhz microcontroller really blew my mind - it really gives you some serious appreciation for what the original engineers were able to do with a dinky little z80

Using a ym3438 in the second slot is an amazing idea! Originally I just had two ym2612's so I could do full 12-channel polyphony. I will *definitely* pick up some ym3438.

Aly James
Very interested
Posts: 74
Joined: Sun Mar 31, 2013 11:34 pm
Location: FRANCE
Contact:

Post by Aly James » Tue Apr 08, 2014 4:12 am

PM send :)
This info might help? http://www.pjrc.com/teensy/benchmark_us ... ceive.html

On a personal point of view (music creation in mind) I would not really care if I cannot stream PCM samples through the YM2612 DAC.
After all it is just a crappy way of playing PCM and you can reproduce the sound easily externally with low bit resolution and low sample rate.. skipping randomly some samples might help too... or ADPCM like X68000 but that is another story.

anyway, In case of making a music track for an homebrew we can still convert the MIDI and PCM from FMDrive to VGM without problem.
For Seeeeeriiiiooouuus game dev I will recommend the devs making their own music driver for Z80 or 68K in ASM to exactly suit the need of the music/game implementation because it is known fact that VGM reading is pretty expansive if you run a game in parallel..

This is however crucial for VGM playback on your device.
Maybe you can add a cheap little SD card shied for teensy devices (I know there is one and it feats on top of the device :)) You could then directly read from the SD Card any VGM or PCM in there letting USB free for MIDI converted DATA or other commands..

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

Post by foobat » Tue Apr 08, 2014 4:58 am

The deal is that to playback audio via the DAC, a VGM file records the transactions on the bus between the Z80 and the ym2612. A VGM also contains a recording of the time that the z80 spins in a tight loop waiting for the next instruction.

In order to play back the vgm file, you need to act on each wait instruction, too! You're basically creating a very rudimentary z80 emulator at this point.

For example:
  • read n bytes from usb
    first byte is the command for a keypress
    next byte is the key to press. Press it
    next byte is the command for 2 bytes of time to wait
    read the next 2 bytes and wait that long (timers etc.)
    next byte is the command for a keyup
    next byte is the key to lift. Lift it
    ...
This works all fine and dandy for simple things like keypresses, because the amount of time you wait between keypresses is aeons in microprocessor time.

But the problem is that when playing PCM data, the program flow looks like this:
  • before you do anything, read all the PCM data into memory
    read n bytes from usb
    first byte is the command for playing pcm data. The high nibble says "you're gonna play data" and the low nibble says "after playing data, wait this extremely short amount of time". Play one byte of the data stored in RAM, move the pointer to the next sequential byte, then wait.
    next byte is the command for pcm data. Play it etc. and wait
    next byte is the command for pcm data. Play it etc. and wait
    next byte is the command for pcm data. Play it etc. and wait
    ...
The amount of time to wait is so short that the time it takes to actually read that byte of data from the USB buffer is longer than the amount of time you need to wait after playing the sample! That causes lag whenever you have too many samples. So far it looks like the only way to actually play back a vgm file in real-time would be to cache the *whole thing* in the local circuit, uncompressed! Lots of people do actually seem to do this with their VGM players, it's why you see them physically switching eeprom DIPs in youtube videos. I'm not sure at this time that reading the instructions from an SD card and processing them will be significantly lower latency than reading them from USB and processing them. The focus is on making it a synth though, not a VGM player. It DOES play most VGM files, like the entirety of the Sonic library. I've got a recording of the end credits for Sonic 3 on it here: https://www.youtube.com/watch?v=hSqlA9uLqx0 with a couple of timing artifacts in it still, I was able to fix those. Any more PCM than this bogs it down. No matter how hard I tried, it was utterly impossible to get it to play r57shell's Ocean Melody without frequent slowdown though.

I think that it's the same fundamental problem that you have with SPSG not being able to time-division multiplex the outputs to in real-time based on computer controls to get the SID sound. The solution I'm thinking about following now is to replace the Teensy++ with a Teensy 3.1 in the future, which is just so massively beefy (up to 96mhz iirc) that it can just muscle through. That does kind of defeat the point of the exercise, though, which is to replicate something kind of similar to the original interconnect between the z80 and the ym2612 in the megadrive.

Regardless I'm totally stoked and I can't wait to get the first draft of boards in next week

Post Reply