In order to calculate the average BPM, FamiTracker 0.5.0 beta uses two circular
buffers in the CSoundGen class with 24 elements each, as well as a row ticks
counter, to store the tempo information at each row. Whenever the song is
playing and the corresponding option is enabled, the status bar uses this
calculated value instead of the static value for the current instant. Here is
how the circular buffers work:

1. One of the buffers stores BPM values, and the other one stores the number of
   ticks elapsed for each row. When the tracker starts playing, these buffers
   are reset using the *last* used BPM value and 1 tick respectively. The ticks
   counter is reset to 0.
   From CSoundGen::BeginPlayer(play_mode_t, int).

2. After that, the tracker loads the default tempo settings from the song.
   From existing code in CSoundGen::BeginPlayer(play_mode_t, int).

3. On every tick, the ticks counter increments by 1.
   From existing code in CSoundGen::RunFrame(void).

4. When the tracker is about to fetch the contents of the next row, the current
   BPM value and the ticks counter are inserted into the circular buffers; then
   the ticks counter is reset to 0 again.
   From CSoundGen::RunFrame(void).

5. The tracker updates the current tempo settings based on Fxx commands.
   From existing code in CSoundGen::EvaluateGlobalEffects(stChanNote*, int),
   called by CChannelHandler::PlayNote(stChanNote*, int),
   called by CSoundGen::PlayNote(int, stChanNote*, int),
   called by CSoundGen::PlayChannelNotes().

6. Steps 3-5 are repeated until the tracker stops playing; then the status bar
   uses the last instant's BPM value. (This is not noticeable if the option is
   disabled because the displayed BPM would then always be the current static
   value.)



Here is a step-by-step example illustrating these steps.

- Open FamiTracker 0.5.0 beta. Put a F14 command on row 01, which will set the
  BPM to 45.00 for the rest of the pattern. Play the pattern.

                           # : Pulse 1
                      ROW 00 : ... .. . ...    ; 6 ticks
                      ROW 01 : ... .. . F14    ; 20 ticks

- The last BPM is simply the default value of the track (150.00 BPM). The two
  buffers are thus initialized as follows.

                                                Starting position
                                                   v                BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |  150.00  |  150.00  |  150.00  |  150.00  |  150.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |       1  |       1  |       1  |       1  |       1  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                                   ^                Ticks
                                                  Next position

- Before the tracker fetches row 00, it writes the default BPM, then advances
  the buffer pointer. This entry is always counted as one tick in the buffer.

                                     Starting position
                                        v                           BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |  150.00  |  150.00  |  150.00  |  150.00  |  150.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |       1  |       1  |       1  |       1  |       1  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                                   ^                Ticks
                                                  Next position

- There are no tempo or speed effect commands on the first row, so the buffer
  receives the same BPM value before the second row is fetched, but this time
  6 ticks have elapsed.

                          Starting position
                             v                                      BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |  150.00  |  150.00  |  150.00  |  150.00  |  150.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |       1  |       1  |       6  |       1  |       1  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                                   ^                Ticks
                                                  Next position

- At this point the player cursor is already on row 02. The calculated average
  BPM is still 150.00 BPM, even though the F14 command has been processed. The
  buffer is always filled with the values of the last row, since global effects
  are applied after fetching the notes.

- Immediately after row 02 is fetched, the F14 command on row 01 finally takes
  effect for the circular buffer. The cursor is on row 03; what the status bar
  displays is always one row behind the cursor (as the cursor is also always
  seen starting on row 01, instead of row 00).

               Starting position
                  v                                                 BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |  150.00  |  150.00  |   45.00  |  150.00  |  150.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |       1  |       6  |      20  |       1  |       1  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                                   ^                Ticks
                                                  Next position

- When the cursor is on row 0x18 (24), the very first entry on the buffer is
  about to be overwritten. Since these are circular buffers, every entry will
  only exist for the duration of the 24 following rows.

                                     Starting position
                                        v                           BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |   45.00  |   45.00  |  150.00  |  150.00  |   45.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |      20  |      20  |       1  |       6  |      20  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                        ^                           Ticks
                                       Next position

- Once the cursor moves to row 0x19 (25), the information for the initial state
  becomes erased. This is the first row where the calculated BPM is accurate.

                          Starting position
                             v                                      BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |   45.00  |   45.00  |  150.00  |   45.00  |   45.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |      20  |      20  |       6  |      20  |      20  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                        ^                           Ticks
                                       Next position

- On row 0x1A (26), the buffer is now entirely filled with the new BPM value.

               Starting position
                  v                                                 BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |   45.00  |   45.00  |   45.00  |   45.00  |   45.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |      20  |      20  |      20  |      20  |      20  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                        ^                           Ticks
                                       Next position

- Stop the module, and then start playing again. During initialization, all the
  ticks counts are restored to 1 before the song's default settings apply.

                                     Starting position
                                        v                           BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |   45.00  |   45.00  |  150.00  |   45.00  |   45.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |       1  |       1  |       1  |       1  |       1  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                                   ^                Ticks
                                                  Next position

- As the cursor moves to row 02, the settings immediately before row 01 are
  written, which is another row of 150 BPM.

                          Starting position
                             v                                      BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |   45.00  |  150.00  |  150.00  |   45.00  |   45.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |       1  |       1  |       6  |       1  |       1  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                                   ^                Ticks
                                                  Next position

- After that, the new BPM is inserted into the buffer. Notice how the starting
  position always uses the song's settings; there will be a visible small bump
  in the average BPM whenever the first played row does not have the same BPM
  as the song's default settings.

               Starting position
                  v                                                 BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |  150.00  |  150.00  |   45.00  |   45.00  |   45.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |       1  |       6  |      20  |       1  |       1  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                                   ^                Ticks
                                                  Next position

- When the cursor is on row 0x19 (25) once more, the average BPM becomes
  independent of the initial BPM condition.

                          Starting position
                             v                                      BPM
         ---+----------+----------+----------+----------+----------+---
   . . .    |   45.00  |   45.00  |  150.00  |   45.00  |   45.00  |    . . .
         ---+----------+----------+----------+----------+----------+---
   . . .    |      20  |      20  |       6  |      20  |      20  |    . . .
         ---+----------+----------+----------+----------+----------+---
                                        ^                           Ticks
                                       Next position



The average BPM is simply a weighted sum of the BPM values in the buffer,
each multiplied with the corresponding ticks count, and the total BPM divided
by the total ticks count. Here are some values using the example above:

- The first time 45.00 BPM appears in the circular buffer, on row 03:

    Weighted BPM: 150 × 1 × 22 + 150 × 6 + 45 × 20 = 5100
     Total ticks:       1 × 22 +       6 +      20 = 48
     Average BPM:                                    5100 ÷ 48 = 106.25

- On row 04:

    Weighted BPM: 150 × 1 × 21 + 150 × 6 + 45 × 20 × 2 = 5850
     Total ticks:       1 × 21 +       6 +      20 × 2 = 67
     Average BPM:                                        5850 ÷ 67 = 87.31

- On row 05:

    Weighted BPM: 150 × 1 × 20 + 150 × 6 + 45 × 20 × 3 = 6600
     Total ticks:       1 × 20 +       6 +      20 × 3 = 86
     Average BPM:                                        6600 ÷ 86 = 76.74

- On row 19:

    Weighted BPM: 150 × 6 + 45 × 20 × 23 = 21600
     Total ticks:       6 +      20 × 23 = 466
     Average BPM:                          21600 ÷ 466 = 46.35

- Replay, on row 01:

    Weighted BPM: 45 × 1 × 23 + 150 × 1 = 1185
     Total ticks:      1 × 23 +       1 = 24
     Average BPM:                         1185 ÷ 24 = 49.38

- Replay, on row 02:

    Weighted BPM: 45 × 1 × 22 + 150 × 1 + 150 × 6 = 2040
     Total ticks:      1 × 22 +       1 +       6 = 29
     Average BPM:                                   2040 ÷ 29 = 70.34

- Replay, on row 03:

    Weighted BPM: 45 × 1 × 21 + 45 × 20 + 150 × 1 + 150 × 6 = 2895
     Total ticks:      1 × 21 +      20 +       1 +       6 = 48
     Average BPM:                                             2895 ÷ 48 = 60.31

This explains why the same pattern may have slightly different values for the
average BPM near the beginning of the played rows.