Mozzi  version v2.0
sound synthesis library for Arduino
mozzi_utils.h
1 /*
2  * mozzi_utils.h
3  *
4  * This file is part of Mozzi.
5  *
6  * Copyright 2012-2024 Tim Barrass and the Mozzi Team
7  *
8  * Mozzi is licensed under the GNU Lesser General Public Licence (LGPL) Version 2.1 or later.
9  *
10  */
11 
12 #ifndef UTILS_H_
13 #define UTILS_H_
14 
15 
16 #include <Arduino.h>
17 
18 #include "hardware_defines.h"
19 
20 // macros for setting and clearing register bits
21 #ifndef cbi
22 #define cbi(sfr, bit) (_SFR_UINT8_T(sfr) &= ~_BV(bit))
23 #endif
24 #ifndef sbi
25 #define sbi(sfr, bit) (_SFR_UINT8_T(sfr) |= _BV(bit))
26 #endif
27 
28 
29 /** @ingroup util
30 Set digital pin 13 to output for testing timing with an oscilloscope.*/
31 inline
32 void setPin13Out()
33 {
34 #if IS_AVR()
35  DDRB |= B00100000;
36 #else
37  pinMode(13, OUTPUT);
38 #endif
39 }
40 
41 
42 /** @ingroup util
43 Set pin 13 high for testing timing with an oscilloscope.*/
44 inline
45 void setPin13High()
46 {
47 #if IS_AVR()
48  PORTB |= B00100000;
49 #else
50  digitalWrite(13, HIGH);
51 #endif
52 }
53 
54 
55 /** @ingroup util
56 Set pin 13 low for testing timing with an oscilloscope.*/
57 inline
58 void setPin13Low()
59 {
60 #if IS_AVR()
61  PORTB &= B11011111;
62 #else
63  digitalWrite(13, LOW);
64 #endif
65 }
66 
67 
68 /** @ingroup util
69 Given a power of 2, work out the number to shift right by to do a divide by the number, or shift left to multiply.
70 @param a power of 2, or any other number for that matter
71 @return the number of trailing zeros on the right hand end
72 */
73 constexpr uint8_t trailingZerosConst(unsigned long v) { return ((v % 2) ? 0 : 1+trailingZerosConst(v >> 1)); }
74 /* NOTE: previous version of the above is super-nifty, but pulls in software float code on AVR (the platform where it makes a difference), leading to bloat and a compile time warning.
75  * Sine the only use-case I could find works on a compile-time constant (template-parameter), I added a constexpr function in mozzi_utils.h, instead. I renamed it, too,
76  * so, we'll learn about any use-case outside of this scope. If there are no reports of breakage, the following can probably be removed for good.
77 long trailingZeros(unsigned long v) {
78  // find the number of trailing zeros in v, from http://graphics.stanford.edu/~seander/bithacks.html#ZerosOnRightFloatCast
79  // there are faster methods on the bit twiddling site, but this is short
80  float f = (float)(v & -v); // cast the least significant bit in v to a float
81  return (*(uint32_t *)&f >> 23) - 0x7f;
82 }
83 
84 Here's an alternate, trivial version:
85 uint8_t trailingZeros(uint16_t v) {
86  uint8_t ret = 0;
87  while ((v % 2) == 0) {
88  v = v >> 1;
89  ++ret;
90  }
91  return ret;
92 } */
93 
94 
95 /** Convert BPM to milliseconds, which can be used to set the delay between beats for Metronome.
96 @param bpm beats per minute
97 */
98 constexpr uint16_t BPMtoMillis(float bpm){
99  //float seconds_per_beat = 60.f/bpm;
100  return (uint16_t) (((float) 60.f/bpm)*1000);
101 }
102 
103 #endif /* UTILS_H_ */