TinyCircuits / TinyCircuits-Thumby-Lib

C/C++ library for Thumby!
Other
10 stars 0 forks source link

Truncation/overflow issues in `play` #1

Open joewreschnig opened 2 years ago

joewreschnig commented 2 years ago

The wrap and level in the Pico SDK are passed as uint16_t, but the calculations in play are done with uint32_t. This leads to incorrect tones or no sound being played at all for many values. E.g. if you play(523):

  uint32_t wrap = clock_get_hz(clk_sys)/freq - 1;
  uint32_t level = (uint32_t)(wrap * (duty / 65535.0f));

  // i.e.
  uint32_t wrap = 125000000/523 - 1;
  uint32_t wrap = 239004;
  // and so
  uint32_t level = (uint32_t)(239004 * (32768 / 65535.0f));
  uint32_t level = 119502;

When truncated to 16 bits during passing to pwm_set_wrap and pwm_set_chan_level, results in wrap = 42396 and level = 53967, i.e. a 0% duty cycle.

Instead, to handle frequencies below ~2kHz, you need to adjust the clock divider as well. E.g. the similar code in MicroPython.