Skip to content

Commit

Permalink
Fixed issue #5734 (FreeBoy Division by zero) (#6053)
Browse files Browse the repository at this point in the history
* Fixed issue #5734 (FreeBoy Division by zero).

Added comments and used more descriptive variable names for noise
channel initialization block.

Also indented the nested for loop to improve code clarity.
The reasons for doing this can be found in this answer:
https://softwareengineering.stackexchange.com/a/362796

* Better initial div_ratio guess

Allows us to skip r = 0 and a conditional in the loop below.

---------

Co-authored-by: Spekular <[email protected]>
  • Loading branch information
aidan-mueller and Spekular authored Jul 2, 2023
1 parent b7027fe commit 1f30ffc
Showing 1 changed file with 17 additions and 13 deletions.
30 changes: 17 additions & 13 deletions plugins/FreeBoy/FreeBoy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -358,30 +358,34 @@ void FreeBoyInstrument::playNote(NotePlayHandle* nph, sampleFrame* workingBuffer

if (tfp == 0)
{
//PRNG Frequency = (1048576 Hz / (ratio + 1)) / 2 ^ (shiftclockfreq + 1)
char sopt = 0;
char ropt = 1;
float fopt = 524288.0 / (ropt * std::pow(2.0, sopt + 1.0));
float f;
// Initialize noise channel...
// PRNG Frequency = (1048576 Hz / (ratio + 1)) / 2 ^ (shiftclockfreq + 1)
// When div_ratio = 0 the ratio should be 0.5. Since s = 0 is the only case where r = 0 gives
// a unique frequency, we can start by guessing s = r = 0 here and then skip r = 0 in the loop.
char clock_freq = 0;
char div_ratio = 0;
float closest_freq = 524288.0 / (0.5 * std::pow(2.0, clock_freq + 1.0));
// This nested for loop iterates over all possible combinations of clock frequency and dividing
// ratio and chooses the combination whose resulting frequency is closest to the note frequency
for (char s = 0; s < 16; ++s)
{
for (char r = 0; r < 8; ++r)
for (char r = 1; r < 8; ++r)
{
f = 524288.0 / (r * std::pow(2.0, s + 1.0));
if (std::fabs(freq - fopt) > std::fabs(freq - f))
float f = 524288.0 / (r * std::pow(2.0, s + 1.0));
if (std::fabs(freq - closest_freq) > std::fabs(freq - f))
{
fopt = f;
ropt = r;
sopt = s;
closest_freq = f;
div_ratio = r;
clock_freq = s;
}
}
}

data = sopt;
data = clock_freq;
data = data << 1;
data += m_ch4ShiftRegWidthModel.value();
data = data << 3;
data += ropt;
data += div_ratio;
papu->writeRegister(0xff22, data);

//channel 4 init
Expand Down

0 comments on commit 1f30ffc

Please sign in to comment.