Skip to content

Commit 4d8bb44

Browse files
Fix PWMAudio speed when over/underclocking (#3135)
Fixes #3133
1 parent b1787da commit 4d8bb44

File tree

1 file changed

+16
-14
lines changed

1 file changed

+16
-14
lines changed

libraries/PWMAudio/src/PWMAudio.cpp

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -274,37 +274,39 @@ size_t PWMAudio::write(const uint8_t *buffer, size_t size) {
274274
void PWMAudio::find_pacer_fraction(int target, uint16_t *numerator, uint16_t *denominator) {
275275
const uint16_t max = 0xFFFF;
276276

277-
/*Cache last results so we dont have to recalculate*/
277+
// Cache last results so we dont have to recalculate
278278
static int last_target;
279279
static uint16_t bestNum;
280280
static uint16_t bestDenom;
281-
/*Check if we can load the previous values*/
281+
// Check if we can load the previous values
282282
if (target == last_target) {
283283
*numerator = bestNum;
284284
*denominator = bestDenom;
285285
return;
286286
}
287287

288-
// See if it's one of the precalculated values
289-
for (size_t i = 0; i < sizeof(__PWMAudio_pacer) / sizeof(__PWMAudio_pacer[0]); i++) {
290-
if (target == (int)__PWMAudio_pacer[i].freq) {
291-
last_target = target;
292-
bestNum = __PWMAudio_pacer[i].n;
293-
bestDenom = __PWMAudio_pacer[i].d;
294-
*numerator = bestNum;
295-
*denominator = bestDenom;
296-
return;
288+
// See if it's one of the precalculated values, and we're at the precalculated frequency
289+
if (rp2040.f_cpu() == F_CPU) {
290+
for (size_t i = 0; i < sizeof(__PWMAudio_pacer) / sizeof(__PWMAudio_pacer[0]); i++) {
291+
if (target == (int)__PWMAudio_pacer[i].freq) {
292+
last_target = target;
293+
bestNum = __PWMAudio_pacer[i].n;
294+
bestDenom = __PWMAudio_pacer[i].d;
295+
*numerator = bestNum;
296+
*denominator = bestDenom;
297+
return;
298+
}
297299
}
298300
}
299301

300302
// Nope, do exhaustive search. This is gonna be slooooow
301-
float targetRatio = (float)F_CPU / target;
303+
float targetRatio = (float)rp2040.f_cpu() / target;
302304
float lowestError = HUGE_VALF;
303305

304306
for (uint16_t denom = 1; denom < max; denom++) {
305-
uint16_t num = (int)((targetRatio * denom) + 0.5f); /*Calculate numerator, rounding to nearest integer*/
307+
uint16_t num = (int)((targetRatio * denom) + 0.5f); // Calculate numerator, rounding to nearest integer
306308

307-
/*Check if numerator is within bounds*/
309+
// Check if numerator is within bounds
308310
if (num > 0 && num < max) {
309311
float actualRatio = (float)num / denom;
310312
float error = fabsf(actualRatio - targetRatio);

0 commit comments

Comments
 (0)