Giter VIP home page Giter VIP logo

ymfm's Introduction

ymfm

ymfm is a collection of BSD-licensed Yamaha FM sound cores (OPM, OPN, OPL, and others), written by Aaron Giles

Supported environments

This code should compile cleanly in any environment that has C++14 support. It has been tested on gcc, clang, and Microsoft Visual C++ 2019.

Supported chip families

Currently, support is present for the following chips (organized by header file):

  • ymfm_misc.h:
    • YM2149 (SSG) [1983: MSX; Atari ST]
  • ymfm_opm.h:
    • YM2151 (OPM) [1983: Sharp X1, X68000; MSX; synths: DX21, DX27, DX100]
    • YM2164 (OPP) [1985: FB-01 MIDI Expander; IBM Music Feature Card; MSX; synths: Korg DS-8, 707]
  • ymfm_opn.h:
    • YM2203 (OPN) [1984: NEC PC-88, PC-98, NEC PC-6001mkII SR, PC-6601 SR]
    • YM2608 (OPNA) [1985: NEC PC-88, PC-98]
    • YM2610 (OPNB) [1987: Neo Geo]
    • YM2610B (OPNB2)
    • YM2612 (OPN2) [1988: Sega Mega Drive/Genesis; FM Towns]
    • YM3438 (OPN2C)
    • YMF276 (OPN2L)
    • YMF288 (OPN3L) [1995: NEC PC-98]
  • ymfm_opl.h:
    • YM3526 (OPL) [1984: C64 SFX Sound Expander]
    • Y8950 (MSX-Audio) [1984: MSX]
    • YM3812 (OPL2) [1985: AdLib, Sound Blaster; synths: some Portasound keyboards]
    • YMF262 (OPL3) [1988: Sound Blaster Pro 2.0, SB16]
    • YMF289B (OPL3L)
    • YMF278B (OPL4) [1993: MSX Moonsound cartridge]
    • YM2413 (OPLL) [1986: Sega Master System, Mark III; MSX; synths: Portasound PSS-140, PSS-170, PSS-270]
    • YM2423 (OPLL-X)
    • YMF281 (OPLLP)
    • DS1001 (Konami 053982/VRC7) [1991: Famicom cartridge Lagrange Point]
  • ymfm_opq.h:
    • YM3806 (OPQ) [synths: PSR-60/70]
  • ymfm_opz.h:
    • YM2414 (OPZ) [1987: synths: TX81Z, DX11, YS200; Korg Z3 guitar synth]

There are some obviously-related chips that also are on my horizon but have no implementation as yet:

  • YMW-258-F 'GEW8' (aka Sega 315-5560 aka Sega Multi-PCM)
  • YMF271 (OPX)
  • YM21280 (OPS) / YM21290 (EGS) [synths: DX7, DX1, DX5, DX9, TX7, TX216, TX416, TX816]
  • OPK?

History

These cores were originally written during the summer and fall of 2020 as part of the MAME project. As such, their design started off heavily based on how MAME works.

The OPM/OPN cores first appeared in MAME 0.230. The OPL cores were added in MAME 0.231. A further rewrite to abstract MAME dependencies is planned for MAME 0.232.

The goal was threefold:

  1. provide BSD-licensed emulation cores that are more compatible with MAME's core licensing
  2. modernize and unify the code around a common implementation of shared features
  3. improve accuracy where possible based on discoveries made by others

Accuracy

The goal of these cores is not 100% digital accuracy. To achieve that would require full emulation of the pipelines, which would make the code extremely difficult to comprehend. It would also make it much harder to share common implementations of features, or to add support for less well-known chip types. If you want that level of accuracy, there are several decap-based emulation cores out there.

Instead, the main goals are:

  1. Extremely high (audibly indistinguishable) accuracy
  2. Reasonable performance
  3. Clean design with readable code
  4. Clear documentation of the various chips

General approach

Check out the examples directory for some example usage patterns. I'm not a big fan of makefiles for simple things, so instructions on how to compile each example are provided at the top.

IMPORTANT

As of May 2021, the interface to these is still a bit in flux. Be prepared when syncing with upstream to make some adjustments.

Clocking

The general philosophy of the emulators provided here is that they are clock-independent. Much like the actual chips, you (the consumer) control the clock; the chips themselves have no idea what time it is. They just tick forward each time you ask them to.

The way you move things along is via the generate() function, which ticks the internal system forward one or more samples, and writes out an array out chip-specific output_data. But what, exactly, is a "sample", and how long is it?

This is where the external clock comes in. Most of the Yamaha chips are externally clocked in the MHz range. They then divide that clock by a factor (sometimes dynamically controllable), and then the internal operators are pipelined to further divide the clock.

For example, the YM2151 internally divides the clock by 2, and has 32 operators to iterate through. Thus, for a nominal input lock of 3.58MHz, you end up at around a 55.9kHz sample rate. Fortunately, all the chip implementations can compute this for you; just pass the raw external clock value to the sample_rate() method and it will hand you back the output sample rate you want.

Then call generate() that many times per second to output the results.

But what if I want to output at a "normal" rate, like 44.1kHz? Sorry, you'll have to rate convert as needed.

Reading and Writing

To read or write to the chips, you can call the read() and write() methods. The offset provided corresponds to the addressing input lines in a (hopefully) logical way.

For reads, almost all chips have a status register, which you can read via read_status(). Some chips have a data port that can be read via read_data(). And chips with extended addressing may also have read_status_hi() and read_data_hi().

For writes, almost all chips have an address register and a data register, and so you can reliably count on there being a write_address() and write_data() method as well. If the chip supports extended addressing, it may also have write_address_hi() and write_data_hi().

ymfm's People

Contributors

aaronsgiles avatar franciscod avatar toxieainc avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.