# Beep For YM2612

This note is about `ex03_beep.cpp`.

The goal is not to make a rich instrument yet.
The goal is to understand one simple YM2612 beep by starting from the final sound and then tracing how that sound is configured.

## Start with the browser demo

Before reading the code, open this page and hear the target result:

- [`YM2612 Beep Demo`](https://kyorohiro.github.io/hello_ymfm_wasm/demos/beep.html)

That demo applies the same YM2612 settings as `ex03_beep.cpp`.

So the main question of this tutorial is:

How do we describe that beep in FM terms, and how do we send those settings to `ymfm` or to the real chip?

## First describe the beep in FM terms

Before looking at register numbers, it helps to describe the beep like this:

- use `channel 1`
- use `algorithm 7`
- send output to both left and right
- use all 4 operators with simple `DT/MULTI` settings
- keep operators 1-3 effectively silent
- let operator 4 be the audible part
- set one pitch with `BLOCK` + `F-Number`
- send `Key ON`

This is the real idea behind the beep.
The register writes are only the chip-specific way to express that idea.

## Channel and operator idea

The YM2612 has 6 FM channels.
Each channel has 4 operators.

An operator is a small tone generator.
Operators can modulate each other, or they can directly contribute to the final output.

In `ex03_beep.cpp`, we use channel 1.

In FM synthesis, one channel is basically built from 4 operators.
That is why ranges such as `0x30-0x3c` exist: the settings are repeated for the 4 operators.

## Why Algorithm 7?

In Algorithm 7, all 4 operators work as carriers.
This is a simple starting point because every operator directly contributes to the output.

It is not the only way to make a sound, but it is easy to understand.

## Beep target configuration

For this beep, the intended setup is roughly:

### Channel

- channel: `1`
- algorithm: `7`
- pan: left + right

### Operators

- operator 1: simple frequency setting, almost silent
- operator 2: simple frequency setting, almost silent
- operator 3: simple frequency setting, almost silent
- operator 4: simple frequency setting, audible

More concretely:

- operators 1-4 use `DT=0`, `MULTI=1`
- operators 1-3 use `TL=0x7f`
- operator 4 uses `TL=0x00`
- operators 1-4 use fast `AR`
- operators 1-4 use simple sustain/release settings

### Pitch

- `0xa4 = 0x22`
- `0xa0 = 0x69`

### Trigger

- `0x28 = 0xf0`

Without `Key ON`, the chip is configured but the note does not actually begin.

## Then express that idea as YM2612 writes

Once the FM-side idea is clear, we can look at the chip-side expression.

Each register write follows this pattern:

1. Write the register number to the address port.
2. Write the value to the data port.

For example:

```cpp
chip.write(0, 0x30);
chip.write(1, 0x01);
```

This means:

1. Select register `0x30`.
2. Write value `0x01` into register `0x30`.

So `ex03_beep.cpp` is really doing two things at once:

- describing a beep in FM terms
- translating that description into YM2612 register writes

## Registers used in `ex03_beep.cpp`

### Quick view

- `0x30-0x3c`: operator detune and multiple
- `0x40-0x4c`: operator total level
- `0x50-0x5c`: operator attack rate
- `0x80-0x8c`: operator sustain level and release rate
- `0xb0`: channel algorithm and feedback
- `0xb4`: left/right output enable
- `0xa4` and `0xa0`: frequency
- `0x28`: key on / key off

### 1. DT / MULTI

These registers control detune and frequency multiple for each operator.

- `0x30`, `0x34`, `0x38`, `0x3c`

In `ex03_beep.cpp`, they are all set to `0x01`.

What happens:

- detune is kept very small
- multiple is set to `1`
- all 4 operators start from a simple frequency relationship

More detail:

- `Detune (DT)` slightly shifts the pitch
- `Multiple (MUL)` changes the frequency by integer ratios such as 1x, 2x, 3x, and 4x
- `MUL=2` is about one octave above the base frequency, and `MUL=4` is about two octaves above
- in FM synthesis, these harmonic relationships strongly affect the tone color

### 2. Total Level

These registers control the output level of each operator.

- `0x40`, `0x44`, `0x48`, `0x4c`

In `ex03_beep.cpp`, operator 4 is louder than the others:

- `0x40 = 0x7f`
- `0x44 = 0x7f`
- `0x48 = 0x7f`
- `0x4c = 0x00`

What happens:

- operators 1-3 are nearly silent
- operator 4 is loud
- this makes the result easier to understand as a simple beep

More detail:

- `Total Level (TL)` is the final output level of an operator
- lowering the TL of a carrier makes the audible volume smaller
- lowering the TL of a modulator reduces brightness and harshness, making the tone rounder

### 3. Attack Rate

These registers control how quickly the sound rises.

- `0x50`, `0x54`, `0x58`, `0x5c`

In `ex03_beep.cpp`, they are all set to `0x1f`.

What happens:

- the note starts quickly
- this helps make the sound feel like a short, clear beep

More detail:

- `Attack Rate (AR)` is how fast the sound reaches its peak after Key On
- larger values create a fast, sharp start
- smaller values create a slower, softer rise

### 4. Sustain / Release area

These registers are part of the envelope settings.

- `0x80`, `0x84`, `0x88`, `0x8c`

In `ex03_beep.cpp`, they are all set to `0x0f`.

What happens:

- the envelope stays simple
- the example does not try to shape a rich instrument yet

More detail:

- `Sustain Level (SL)` is the level held after the decay stage
- `Release Rate (RR)` is how fast the sound disappears after Key Off
- a larger `RR` makes the sound stop quickly
- a smaller `RR` leaves a longer tail

### 5. Algorithm

- `0xb0 = 0x07`

This selects Algorithm 7 for channel 1.

What happens:

- all 4 operators act as carriers
- they go directly to the output instead of forming a deeper modulation chain

More detail:

- `Algorithm (ALG)` defines how the 4 operators are connected
- different connections produce different musical characters, such as organ-like, bell-like, or bass-like tones
- `0xb0` also contains `Feedback (FB)`
- `Feedback` routes an operator output back into itself, which can add sharpness, noise, or distorted character

### 6. Stereo output

- `0xb4 = 0xc0`

This enables both left and right output.

What happens:

- the sound is sent to both `MOL` and `MOR`
- the beep is heard in both left and right channels

More detail:

- this register also controls `PAN`
- you can send the sound to the left channel, the right channel, or both
- enabling both sides makes the sound appear centered

### 7. Frequency

- `0xa4 = 0x22`
- `0xa0 = 0x69`

These two registers set the pitch.

What happens:

- the channel gets one specific note value
- if you change these values, the beep pitch changes

More detail:

- this is the main pitch control area of the YM2612
- `0xa4` contains upper information such as `BLOCK`
- `0xa0` contains the lower `F-Number` bits
- together they define the final note pitch

### 8. Key ON

- `0x28 = 0xf0`

This turns on operators 1-4 for channel 1.

What happens:

- the note begins
- without this write, the configured sound will not actually start

More detail:

- `0x28` is the actual note trigger
- it contains the channel number and the operator enable bits
- Key On starts the note, and Key Off moves the sound into its release phase

## Read the code as a register dictionary

If you want to understand the YM2612 more deeply and write your own setup by yourself,
it is a good idea to read `ymfm` source code directly.

In this repository, `src/ymfm_opn.h:209` is a very useful register dictionary.

These lines are especially helpful:

- `src/ymfm_opn.h:221`
  `0x30` range -> `op_detune`, `op_multiple`
- `src/ymfm_opn.h:223`
  `0x40` range -> `op_total_level`
- `src/ymfm_opn.h:224`
  `0x50` range -> `op_ksr`, `op_attack_rate`
- `src/ymfm_opn.h:229`
  `0x80` range -> `op_sustain_level`, `op_release_rate`
- `src/ymfm_opn.h:210`
  `0xb0` -> `ch_feedback`, `ch_algorithm`
- `src/ymfm_opn.h:212`
  `0xb4` -> channel output / pan related fields
- `src/ymfm_opn.h:209`
  `0xa4` + `0xa0` -> `ch_block_freq`

For `0x28` key on/key off handling, `src/ymfm_opn.cpp:176` is the place to read.

Once you can connect `ex03_beep.cpp` with these definitions, you are already very close to being able to build your own YM2612 beep setup.

## Important idea

The beep is not made by one special "beep command".

The sound appears because:

- the operators are configured
- the channel is configured
- the pitch is set
- `Key ON` starts the note
