BSD-licensed Yamaha FM sound cores (OPM, OPN, OPL, and others)

Related tags

Miscellaneous ymfm
Overview

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++17 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_opm.h:
    • YM2151 (OPM)
    • YM2164 (OPP)
  • ymfm_opn.h:
    • YM2149 (SSG)
    • YM2203 (OPN)
    • YM2608 (OPNA)
    • YM2610 (OPNB)
    • YM2610B (OPNB2)
    • YM2612 (OPN2)
    • YM3438 (OPN2C)
    • YMF276 (OPN2L)
  • ymfm_opl.h:
    • YM3526 (OPL)
    • Y8950 (MSX-Audio)
    • YM3812 (OPL2)
    • YMF262 (OPL3)
    • YMF278B (OPL4) -- partial (only the FM side)
    • YM2413 (OPLL)
    • YM2423 (OPLL-X)
    • YMF281 (OPLLP)
    • DS1001 (Konami 053982)
  • ymfm_opq.h:
    • YM3806 (OPQ) -- preliminary
  • ymfm_opz.h:
    • YM2414 (OPZ) -- preliminary

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.

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().

Issues
  • Delays are required

    Delays are required

    Hi Aaron! Is there a #define we can use in ymfm to disable the required delays (INSTANT_MODE or something like that)?

    If not, how much delay we should add between writes? I suppose it is not a delay in time but in N calls to clock() before some writes(addr, reg). Am I right?

    opened by LeonardoDemartino 8
  • ADPCM: fixed end/limit address checking and reading external data

    ADPCM: fixed end/limit address checking and reading external data

    This patch fixes checking of end and limit addresses in ADPCM.

    In the original implementation, loop playback of ADPCM sound was sometimes incorrect because the limit address checking was done first and it changed the data address to 0.

    opened by hyano 6
  • LFO speed appears to be a little bit slower than hardware or Nuked

    LFO speed appears to be a little bit slower than hardware or Nuked

    LFO is running considerably at a lower rate (confirmed on YM2612 and YM2610), it is really noticeable on high LFO speeds (like speed 7 MAX SPEED as shown in my example). Image for comparison with NUKED/HW: https://deflemask.com/LFO_rate.png

    https://deflemask.com/LFO_rate_test.vgm https://deflemask.com/LFO_nuked.wav https://deflemask.com/LFO_ymfm.wav

    opened by LeonardoDemartino 6
  • SSG-EG issues: the sequel

    SSG-EG issues: the sequel

    Another quirk in the SSG-EG emulation was found!

    https://deflemask.com/ssgeg_issue_6_ymfm.wav https://deflemask.com/ssgeg_issue_6_nuked.wav https://deflemask.com/ssgeg_issue_6.vgm

    opened by LeonardoDemartino 5
  • OPN: fixed behavior of F-Num2(registers 0xa4,0xac)

    OPN: fixed behavior of F-Num2(registers 0xa4,0xac)

    This patch fixes the behavior of registers A4-A6h and AC-AEh in OPN. In real chip, there is one latch for each of A4-A6h and AC-AEh.

    In some games, if this behavior is not reproduced, a bug in the sound driver causes incorrect pitch.

    Although this patch is little bit redundant, it uses unused registers for latching as same as the original implementation. Please modify, if you have better idea.

    opened by hyano 4
  • OPL3 waveform 7 (derived square) doesn't seem right

    OPL3 waveform 7 (derived square) doesn't seem right

    I've been doing some experimentation with using ymfm for OPL3-based MIDI playback. So far almost everything sounds great, but I've noticed an issue where waveform 7 sounds noticeably different than it should, whether it's being used as a carrier or a modulator.

    I recorded a simple "1-operator" test patch using Nuked-OPL3 (via Wohlstand's patch editor) and my own ymfm-based application for comparison:

    image (Nuked on the left, ymfm on the right)

    https://revenant1.net/opl3-dsq-nuked.ogg https://revenant1.net/opl3-dsq-ymfm.ogg

    It's especially apparent for patches that use it as a modulator, since the difference can have a pretty drastic effect on whatever other operators are involved.

    opened by devinacker 4
  • SSG: fixed output when both tone & noise are disabled

    SSG: fixed output when both tone & noise are disabled

    This is a patch to fix incorrect behavior of the mixer-control register in SSG.

    ch_noise_enable_n()/ch_tone_enable_n() are not good names, but I couldn't have a better one.

    opened by hyano 3
  • YM2151 Timer B information

    YM2151 Timer B information

    Not sure where to put this, but there were some comments on Mametesters regarding slow music in some Konami games, and how the FPGA implementations dealt with that.

    https://mametesters.org/view.php?id=8146

    I encountered this slow music bug on a number of Konami games even when attempting to get both Iron Horse (which uses the YM2203 rather than the YM2151) and Jackal working on an FPGA. It seems the origin of this issue is an error in the timer behavior of both OPM and OPN family FM chips. With the YM2151, it's specifically timer B which appears to have an issue as the lower 4 bits are supposed to be free-running. If these bits aren't free-running in MAME, it's likely the root cause of slow music in a number of Konami games with the YM2151. For reference, Jose Tejada's JT51 is what I used for Jackal and this is how the timers are modeled after being fixed to correct the slow music problem: https://github.com/jotego/jt51/blob/master/hdl/jt51_timers.v He also has his own FPGA clone of Contra which has the correct music speed after this fix. Hope this helps.

    opened by DavidHaywood 3
  • SSG-EG amplitude issue?

    SSG-EG amplitude issue?

    We found a FM instrument that sounds really really different on the HW/Nuked vs the ymfm cores. https://deflemask.com/bug_ssgeg_7_nuked.wav https://deflemask.com/bug_ssgeg_7_ymfm.wav https://deflemask.com/bug_ssgeg_7.vgm

    It sounds different on amplitude but also on some of the inner works.

    opened by LeonardoDemartino 3
  • Pan for OPLL rhythm sound is not properly

    Pan for OPLL rhythm sound is not properly

    Pan for OPLL rhythm sound is not properly. Could you please confirm?

    ymfm_fm.h: around L300

    Before:

    if (RegisterType::OUTPUTS == 1 || m_regs.ch_output_0(choffs))

    After:

    if (RegisterType::OUTPUTS >= 1 || m_regs.ch_output_0(choffs))

    opened by 110-kenichi 2
  • All chip support

    All chip support

    Do you have a plant to support all sound chips implemented by MAME?

    I'm developing a DAW/MIDI synth with MAME engine. ( https://github.com/110-kenichi/mame )

    However, it became very difficult to get the MAME engine source after big sound refactoring into the application. ( This is because the stream_sample_t class has been changed to read_stream_view/write_stream_view. ) So, I would like to change my MAME sound engine to the ymfm sound engine.

    opened by 110-kenichi 2
  • YMF278B issue with Dragon Blaze in MAME

    YMF278B issue with Dragon Blaze in MAME

    Just forwarding this as a bug report, from a comment left by "Sudo Nimh" on my YouTube.

    Starting with MAME 0.232 there are some out of place sounds in Dragon Blaze

    0.232 contained the following change

    • 8090: 3rdparty/ymfm: Implemented YMF278B PCM functionality, and fixed a number of edge cases. [Aaron Giles]

    The easiest way to hear this is if you insert a coin and let the counter tick down to 4, there is an odd click sound. This sound also occurs at various points in gameplay.

    Unfortunately I can't find any original footage to be able to say what is meant to happen.

    opened by DavidHaywood 0
  • YM2151 Noise Freq is reversed

    YM2151 Noise Freq is reversed

    For OPM, register 0x0F is noise frequency (bits 0-5) and noise_enable (bit 7) In YMFM, the noise frequency output is highest when this value = 0 and lowest when this value = 1F. The real hardware behaves in the reverse of this. (1F = highest freq, 00 = lowest freq)

    We did a test using the same VGM data on two emulators and a real chip. The emulator(s) using YMFM get the pitch backwards. The real HW and emulators using either Nuked OPM or the previous MAME core produce the expected results (1F = lowest, 00 = highest)

    VGM attached Noise Sweep VGMs.zip

    opened by ZeroByteOrg 3
  • ADPCM: fixed reading external data

    ADPCM: fixed reading external data

    This patch is a part of fix I send in PR https://github.com/aaronsgiles/ymfm/pull/31.

    I splitted the following commit into 2 comits and it is for reading external ADPCM memory. OPNA/ADPCM: fixed reading reg values and external data

    I think this fix is better than the original, but in some case, behavior of status ragister is still not good because of behavior of dummy read. Change for dummy read in PR #31 depends on this PR and I need to consider how to share with you.

    opened by hyano 0
  • ADPCM: fixed end/limit address checking

    ADPCM: fixed end/limit address checking

    It is a fixed patch I have sent in PR #31 first. In the original behavior, ADPCM sounds doesn't play with loop if stop address and limit address are same. I reffered the behavior and implementation of fmgen.

    https://github.com/aaronsgiles/ymfm/pull/31#issue-1190632498


    This patch fixes checking of end and limit addresses in ADPCM.

    In the original implementation, loop playback of ADPCM sound was sometimes incorrect because the limit address checking was done first and it changed the data address to 0.

    opened by hyano 7
  • Slight differences in YM2612 emulation

    Slight differences in YM2612 emulation

    (Crossposting from Mametesters)

    I've recorded what may be a good test case for the YM2612's "ladder effect", a track from Earthworm Jim 2 which Tommy Tallarico has mentioned was made specifically to exploit said effect (I'm assuming to add to the cringiness of the level where it's used): https://youtu.be/V2he1ez_JKc

    Hardware used: Japanese Mega Drive VA1 (note that this may accentuate these effects, in comparison with later hardware revisions) Sound in the video was amplified by 20dB, since Mega Drive recordings tend to sound pretty faint.

    Steps to reproduce in MAME: Load the genesis driver with the game "ejim2u" and then open this savestate (created in MAME 0.240) or:

    • Start a game
    • Pause, then enter A, C, C, A, B, A, B, Left to enter the sound test
    • Select the sount test, press A until the track number is 0
    • Press C to play the track
    opened by ICEknigh7 4
  • YM2149F envelope mode emulation bug

    YM2149F envelope mode emulation bug

    When turning on the hardware envelope on a channel, and setting that channel's tone and noise mode off, the channel stays silent and does not reflect the envelope value.

    See issue https://github.com/tildearrow/furnace/issues/77 and potential fix.

    opened by tildearrow 1
Owner
Aaron Giles
Aaron Giles
C/C++ language server supporting multi-million line code base, powered by libclang. Emacs, Vim, VSCode, and others with language server protocol support. Cross references, completion, diagnostics, semantic highlighting and more

Archived cquery is no longer under development. clangd and ccls are both good replacements. cquery cquery is a highly-scalable, low-latency language s

Jacob Dufault 2.3k Jun 20, 2022
The whole design is modular, parametric (cost and others), field repairable, and super extensible

Easy-Transceiver The whole design is modular, parametric (cost and others), field repairable, and super extensible. It is almost trivial to add suppor

Dhiru Kholia 2 Apr 22, 2022
Allows you to easily control via MQTT any Micronova equiped pellet stove. (MCZ, Extraflame, Laminox, and many others brands!)

micronova_controller Kits are available on Tindie! Currently out of stock. V2 will be in stock soon! Here is an overview of the additions: possibility

Philibert Cheminot 27 Apr 13, 2022
Apple cctools and ld64 port for Linux, *BSD and macOS

Apple cctools and ld64 port for Linux, *BSD and macOS

Thomas Pöchtrager 605 Jun 24, 2022
Sega Master System / Game Gear / SG-1000 emulator for iOS, macOS, Raspberry Pi, Windows, Linux, BSD and RetroArch.

Gearsystem is a very accurate, cross-platform Sega Master System / Game Gear / SG-1000 emulator written in C++ that runs on Windows, macOS, Linux, BSD, iOS, Raspberry Pi and RetroArch.

Ignacio Sanchez Gines 161 Jun 22, 2022
Tiny implementation of the GNU/Linux CGroupFS (sans resource controllers) as a PUFFS or FUSE filesystem for BSD platforms

CGrpFS CGrpFS is a tiny implementation of the GNU/Linux CGroup filesystem for BSD platforms. It takes the form of a either a PUFFS or FUSE filesystem,

null 11 Jan 10, 2022
Qt5 "Hello, world!" app for Linux, BSD, Windows, Mac.

hello world in qt5 Contributions in all forms (code, bug reports, community engagement, localization, etc) are warmly welcomed. Development activity I

Jakob Flierl 2 Jan 26, 2022
New linux driver and tools for RME HDSPe sound cards and extension modules

snd-hdspe New linux kernel ALSA driver for RME HDSPe MADI / AES / RayDAT / AIO and AIO Pro sound cards and extension modules. In addition to the funct

Philippe Bekaert 20 Jun 29, 2022
StochFuzz - Sound and Cost-effective Fuzzing of Stripped Binaries by Incremental and Stochastic Rewriting

StochFuzz: A New Solution for Binary-only Fuzzing StochFuzz is a (probabilistically) sound and cost-effective fuzzing technique for stripped binaries.

Zhuo Zhang 161 Apr 7, 2022
Plua is a superset of Lua for classic PalmOS devices with added support for graphics, UI, networking, events and sound.

Plua2c Plua is a superset of Lua for classic PalmOS devices with added support for graphics, UI, networking, events and sound. This is the source code

Cameron Kaiser 8 May 16, 2022
Plays native alert sound and shows native dialogs/alerts in your Flutter app.

flutter_platform_alert 2021 © Weizhong Yang a.k.a zonble. A simple plugin to present native alerts, including playing alert sounds and showing alert d

Weizhong Yang a.k.a zonble 52 Jun 18, 2022
The purpose of this library is to control a piezo crystal and make sound with it

Beeper-Library The purpose of this library is to control a piezo crystal and make sound with it. The piezo may either have electronic or be connected

Dirk Ohme 2 Jan 20, 2022
No loss LV2 sound effect plugin

B.Spacr Description: LV2 sound effect plugin B.Spacr is a unique LV2 effect plugin that enables a clear and brilliant audibility of your music product

null 13 Nov 28, 2021
Bollu learns physically based sound sythesis

Kavariance bollu learns digital audio synthesis from the blog at the bottom of the sea. the name is a pun on Kaveri, A wav/river goddess, and Covarian

Siddharth 8 Dec 29, 2021
usb to 5 din midi converter-filter-router, sound generator

multi What is multi? It's a PCB (shield/hat) hosting a seeeduino Xiao. It has 6 potentiometers, 2 pushbuttons and a 1/8" audio out connected to the Xi

pangrus 18 Jun 17, 2022
This repository provides the implementation of a ADC real-time viewer for an analog sound sensor.

Real-time sound analysing using microcontroller FRDM-KL25Z Acest cod este realizat pentru o platforma autonoma realizata cu kitul de la NXP care are r

null 5 Jan 20, 2022
Portedplugins - A collection of plugins for the SuperCollider sound environment, all of which are ported / remixed from elsewhere

PortedPlugins A collection of plugins for the SuperCollider sound environment, all of which are ported / remixed from elsewhere - including hardware s

mads kjeldgaard 116 Jun 23, 2022
Aims to be an accurate C port of Impulse Tracker 2.15's IT replayer (with selectable IT2 sound drivers)

it2play Aims to be an accurate C port of Impulse Tracker 2.15's IT replayer (with selectable IT2 sound drivers). This is a direct port of the original

Olav Sørensen 17 May 21, 2022
null 235 Jun 22, 2022