Skip to content

Commit

Permalink
Clean up readme
Browse files Browse the repository at this point in the history
  • Loading branch information
apollolux committed Jan 1, 2015
1 parent c429805 commit e3e1d69
Showing 1 changed file with 44 additions and 11 deletions.
55 changes: 44 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,43 +1,76 @@
**ym2612.js**, *the* definitive Yamaha YM2612 emulation in JavaScript!

# Preamble

This is a basic emulation of the Yamaha YM2612 synthesis chip written entirely in JavaScript. The intention is primarily to mockup interaction of a YM2612 core with an implementation of Steinberg's *VST* audio toolkit. This core is based entirely on the open-source C-based YM2612 core found in the Wii port of the Genesis Plus emulator.
This is as complete an emulation as possible of the Yamaha YM2612 synthesis chip written entirely in JavaScript. This core is ported entirely from the open-source C-based YM2612 core found in the Wii port of the Genesis Plus emulator, Genesis Plus GX. The original intention was primarily to mockup interaction of a YM2612 core with an implementation of Steinberg's *VST* audio toolkit, but now serves as the YM2612 core of my web-based VGM player.

* Genesis Plus can be found at [http://code.google.com/p/genplus-gx](http://code.google.com/p/genplus-gx)
* Genesis Plus GX can be found at [http://code.google.com/p/genplus-gx](http://code.google.com/p/genplus-gx)
* VST can be found at [http://www.steinberg.net/en/company/developer.html](http://www.steinberg.net/en/company/developer.html)
* Basic JavaScript implementation of VST by myself (as proof-of-concept for my mockup purposes) soon to follow!
* Source distribution of the web VGM player soon to follow!

# Installation

1. Download ym2612.js to a directory that's accessible by your intended webpage or other JavaScript-capable development environment (I personally use [Sphere](http://spheredev.org) for JavaScript).
1. Download ym2612.js to a directory that's accessible by your intended webpage or other JavaScript-capable development environment.
2. Reference the file in your project.
* In HTML, a normal script element on the page itself will do.
* In Sphere, you'll need to RequireScript it.
3. Follow the usage instructions below!

# Usage

First, you'll need to declare a `YM2612` object (a simple `var ym = new YM2612();` or some such will do). Once the object is loaded, you'll need to initialize it using `ym.init(int_clock, int_samplerate)` , where `int_clock` is the chip's native frequency (7670445 is the ideal value here) and `int_samplerate` is your output audio's sample-frame rate (44100 is a relatively normal value). Make sure that if you update the frame rate in your app that you call `ym.init` again.
First, you'll need to declare a `YM2612` object (a simple `var ym = new YM2612();` or some such will do). Once the object is loaded, you'll need to initialize it using `ym.init(int_clock, int_samplerate)` , where `int_clock` is the chip's native frequency (7670448 is the ideal value here for NTSC) and `int_samplerate` is your output audio's sample-frame rate (44100 is a relatively normal value). Make sure that if you update the frame rate in your app that you call `ym.init` again. You'll then need to `ym.config(9);` 9 being the bit length of PCM data to send to the DAC internally, followed by a `ym.reset();`, then `ym.write(0x28,0x00);` to make sure all the channels are keyed off.

Assuming your computer did not blow up, we should be ready to feed the chip some data! From this point forward, if you are going to feed data manually, you must know what the chip's registers do. Manually or programmatically, write to registers using `ym.write(byte_addr, byte_data)` , where `byte_reg` is the register to which to write and `byte_data` is the data to write to it. First, turn all your channels' notes off, as well as disable the DAC on channel 6 temporarily, then set the channels' panning and modulation states, then finally set the channels' FM parameters. Now it should be safe to send musical data to the chip. If you are feeding data manually, you may or may not need to write to registers such as timer registers.

Once you've written your data to the chip and your app wants to advance, get the generated audio using `buffer = ym.update(int_length)` , where `int_length` is the number of sample-frames to write to the `buffer` variable. The results should be an array[2][`int_length`] in size of 16-bit audio samples; you'll likely need to loop through `buffer` to add the samples to existing audio.

So! Your setup code should look similar to the following…

```
var ym = new YM2612();
ym.init(7670448, 44100); // call this if the clock and/or output sample rate ever need to change
ym.config(9);
ym.reset();
ym.write(0x28,0x00);
```

…and your update loop might look like the following…

```
do {
cmd = getByte();
if (cmd!==UPDATE) { // some control value you define specifying "time to update sound"
data = getByte();
ym.write(cmd, data);
}
else {
len = getNumberOfSamples(); // some function you define to get a particular length
buffer = ym.update(len);
sendBufferToAudioSink(buffer); // some function you define to send a stereo buffer to Web Audio
}
} while (canFeed); // canFeed is some boolean saying you can still emulate
```

# API
<h3>How to Initialize</h3>
<dl>
<dt>new YM2612();</dt>
<dd>If successful, a new YM2612 object is returned. (I will likely update this soon to allow direct init of clock and sample rate in constructor)</dd>
<dd>If successful, a new YM2612 object is returned.</dd>
</dl>
<dl>
<dt>void YM2612.init(int_clock, int_samplerate);</dt>
<dd>Initialize the chip to a given frequency and sample rate.</dd>
<dd>Arguments: `int_clock` is the YM2612's frequency native to the app (7670445 is the ideal value here); `int_samplerate` is the app's sample-frame rate (aka, "sample rate" or "frame rate", where 44100 is a normal value to use here).</dd>
<dd>Return: void (none)</dd>
<dt>YM2612.reset()</dt>
<dt>void YM2612.reset()</dt>
<dd>Reset the chip; silence all channels and zero all timers.</dd>
<dd>Arguments: none</dd>
<dd>Return: void (none)</dd>
<dt>YM2612.write(byte_addr, byte_data)</dt>
<dt>void YM2612.config(dac_bits)</dt>
<dd>Configure the chip's DAC precision for PCM data.</dd>
<dd>Arguments: `dac_bits` is the number of bits of DAC precision to use.</dd>
<dd>Return: void (none)</dd>
<dt>void YM2612.write(byte_addr, byte_data)</dt>
<dd>Write data to a chip register.</dd>
<dd>Arguments: `byte_addr` is the address of the register to which to write; `byte_data` is the data to write to that register.</dd>
<dd>Return: void (none)</dd>
Expand All @@ -51,11 +84,11 @@ Once you've written your data to the chip and your app wants to advance, get the
<dd>Return: Array[2][`int_length`] audio_buffer</dd>
<dt>Object YM2612.getContext()</dt>
<dd>TODO</dd>
<dd>Arguments: none</dd>
<dd>Arguments: TODO</dd>
<dd>Return: TODO</dd>
<dt>int YM2612.getContextSize()</dt>
<dd>TODO</dd>
<dd>Arguments: none</dd>
<dd>Arguments: TODO</dd>
<dd>Return: void (none)</dd>
<dt>void YM2612.restore(bytearray_buffer)</dt>
<dd>TODO</dd>
Expand All @@ -73,7 +106,7 @@ Once you've written your data to the chip and your app wants to advance, get the

# Disclaimer

[Genesis Plus](http://code.google.com/p/genplus-gx) is an open-source multi-platform emulator of the Sega Genesis/Mega Drive. I very much enjoy Genesis games and am a big fan of the audio output by the console, as well as FM synthesis in general, hence this project. The ultimate goal of this project is to create a usable YM2612 VST instrument for DAWs that support the VST format, as well as an Audio Unit for those OS X-based DAWs that support CoreAudio.
[Genesis Plus](http://code.google.com/p/genplus-gx) is an open-source multi-platform emulator of the Sega Genesis/Mega Drive. I very much enjoy Genesis games and am a big fan of the audio output by the console, as well as FM synthesis in general, hence this project. The two goals of this project are to create a stable YM2612 library in JavaScript to use in web-based players and synthesizers, and to design a usable YM2612 VST instrument for DAWs that support the VST format, as well as an Audio Unit for those OS X-based DAWs that support CoreAudio.

# License

Expand Down

0 comments on commit e3e1d69

Please sign in to comment.